diff options
Diffstat (limited to 'telephony/java')
90 files changed, 1795 insertions, 15069 deletions
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java index a5af42abe405..24cecb415216 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -4013,13 +4013,21 @@ public final class Telephony { public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts"); /** - * The id of the subscription which received this cell broadcast message. + * The subscription which received this cell broadcast message. + * @deprecated use {@link #SLOT_INDEX} instead. * <P>Type: INTEGER</P> * @hide */ public static final String SUB_ID = "sub_id"; /** + * The slot which received this cell broadcast message. + * <P>Type: INTEGER</P> + * @hide + */ + public static final String SLOT_INDEX = "slot_index"; + + /** * Message geographical scope. Valid values are: * <ul> * <li>{@link android.telephony.SmsCbMessage#GEOGRAPHICAL_SCOPE_CELL_WIDE}. meaning the @@ -4253,7 +4261,7 @@ public final class Telephony { public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time"; /** - * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects. + * Query columns for instantiating com.android.cellbroadcastreceiver.CellBroadcastMessage. * @hide */ @NonNull @@ -4286,6 +4294,7 @@ public final class Telephony { */ public static final String[] QUERY_COLUMNS_FWK = { _ID, + SLOT_INDEX, GEOGRAPHICAL_SCOPE, PLMN, LAC, diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java new file mode 100644 index 000000000000..72f758eba39a --- /dev/null +++ b/telephony/java/android/telephony/Annotation.java @@ -0,0 +1,512 @@ +package android.telephony; + +import android.annotation.IntDef; +import android.telephony.data.ApnSetting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Telephony Annotations. + * Telephony sdk is a mainline module and others cannot reference hidden @IntDef. Moving some + * telephony annotations to a separate class to allow others statically link to it. + * + * @hide + */ +public class Annotation { + @IntDef(prefix = {"DATA_"}, value = { + TelephonyManager.DATA_ACTIVITY_NONE, + TelephonyManager.DATA_ACTIVITY_IN, + TelephonyManager.DATA_ACTIVITY_OUT, + TelephonyManager.DATA_ACTIVITY_INOUT, + TelephonyManager.DATA_ACTIVITY_DORMANT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DataActivityType { + } + + @IntDef(prefix = {"DATA_"}, value = { + TelephonyManager.DATA_UNKNOWN, + TelephonyManager.DATA_DISCONNECTED, + TelephonyManager.DATA_CONNECTING, + TelephonyManager.DATA_CONNECTED, + TelephonyManager.DATA_SUSPENDED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DataState { + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"RADIO_POWER_"}, + value = { + TelephonyManager.RADIO_POWER_OFF, + TelephonyManager.RADIO_POWER_ON, + TelephonyManager.RADIO_POWER_UNAVAILABLE, + }) + public @interface RadioPowerState { + } + + @IntDef({ + TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN, + TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATING, + TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATED, + TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED, + TelephonyManager.SIM_ACTIVATION_STATE_RESTRICTED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SimActivationState { + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SRVCC_STATE_"}, + value = { + TelephonyManager.SRVCC_STATE_HANDOVER_NONE, + TelephonyManager.SRVCC_STATE_HANDOVER_STARTED, + TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED, + TelephonyManager.SRVCC_STATE_HANDOVER_FAILED, + TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED}) + public @interface SrvccState { + } + + @IntDef(prefix = {"CALL_STATE_"}, value = { + TelephonyManager.CALL_STATE_IDLE, + TelephonyManager.CALL_STATE_RINGING, + TelephonyManager.CALL_STATE_OFFHOOK + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CallState { + } + + @IntDef({ + TelephonyManager.NETWORK_TYPE_UNKNOWN, + TelephonyManager.NETWORK_TYPE_GPRS, + TelephonyManager.NETWORK_TYPE_EDGE, + TelephonyManager.NETWORK_TYPE_UMTS, + TelephonyManager.NETWORK_TYPE_CDMA, + TelephonyManager.NETWORK_TYPE_EVDO_0, + TelephonyManager.NETWORK_TYPE_EVDO_A, + TelephonyManager.NETWORK_TYPE_1xRTT, + TelephonyManager.NETWORK_TYPE_HSDPA, + TelephonyManager.NETWORK_TYPE_HSUPA, + TelephonyManager.NETWORK_TYPE_HSPA, + TelephonyManager.NETWORK_TYPE_IDEN, + TelephonyManager.NETWORK_TYPE_EVDO_B, + TelephonyManager.NETWORK_TYPE_LTE, + TelephonyManager.NETWORK_TYPE_EHRPD, + TelephonyManager.NETWORK_TYPE_HSPAP, + TelephonyManager.NETWORK_TYPE_GSM, + TelephonyManager.NETWORK_TYPE_TD_SCDMA, + TelephonyManager.NETWORK_TYPE_IWLAN, + TelephonyManager.NETWORK_TYPE_LTE_CA, + TelephonyManager.NETWORK_TYPE_NR, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NetworkType { + } + + @IntDef(flag = true, prefix = {"TYPE_"}, value = { + ApnSetting.TYPE_DEFAULT, + ApnSetting.TYPE_MMS, + ApnSetting.TYPE_SUPL, + ApnSetting.TYPE_DUN, + ApnSetting.TYPE_HIPRI, + ApnSetting.TYPE_FOTA, + ApnSetting.TYPE_IMS, + ApnSetting.TYPE_CBS, + ApnSetting.TYPE_IA, + ApnSetting.TYPE_EMERGENCY, + ApnSetting.TYPE_MCX + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ApnType { + } + + @IntDef(value = { + DataFailCause.NONE, + DataFailCause.OPERATOR_BARRED, + DataFailCause.NAS_SIGNALLING, + DataFailCause.LLC_SNDCP, + DataFailCause.INSUFFICIENT_RESOURCES, + DataFailCause.MISSING_UNKNOWN_APN, + DataFailCause.UNKNOWN_PDP_ADDRESS_TYPE, + DataFailCause.USER_AUTHENTICATION, + DataFailCause.ACTIVATION_REJECT_GGSN, + DataFailCause.ACTIVATION_REJECT_UNSPECIFIED, + DataFailCause.SERVICE_OPTION_NOT_SUPPORTED, + DataFailCause.SERVICE_OPTION_NOT_SUBSCRIBED, + DataFailCause.SERVICE_OPTION_OUT_OF_ORDER, + DataFailCause.NSAPI_IN_USE, + DataFailCause.REGULAR_DEACTIVATION, + DataFailCause.QOS_NOT_ACCEPTED, + DataFailCause.NETWORK_FAILURE, + DataFailCause.UMTS_REACTIVATION_REQ, + DataFailCause.FEATURE_NOT_SUPP, + DataFailCause.TFT_SEMANTIC_ERROR, + DataFailCause.TFT_SYTAX_ERROR, + DataFailCause.UNKNOWN_PDP_CONTEXT, + DataFailCause.FILTER_SEMANTIC_ERROR, + DataFailCause.FILTER_SYTAX_ERROR, + DataFailCause.PDP_WITHOUT_ACTIVE_TFT, + DataFailCause.ACTIVATION_REJECTED_BCM_VIOLATION, + DataFailCause.ONLY_IPV4_ALLOWED, + DataFailCause.ONLY_IPV6_ALLOWED, + DataFailCause.ONLY_SINGLE_BEARER_ALLOWED, + DataFailCause.ESM_INFO_NOT_RECEIVED, + DataFailCause.PDN_CONN_DOES_NOT_EXIST, + DataFailCause.MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED, + DataFailCause.COLLISION_WITH_NETWORK_INITIATED_REQUEST, + DataFailCause.ONLY_IPV4V6_ALLOWED, + DataFailCause.ONLY_NON_IP_ALLOWED, + DataFailCause.UNSUPPORTED_QCI_VALUE, + DataFailCause.BEARER_HANDLING_NOT_SUPPORTED, + DataFailCause.ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED, + DataFailCause.UNSUPPORTED_APN_IN_CURRENT_PLMN, + DataFailCause.INVALID_TRANSACTION_ID, + DataFailCause.MESSAGE_INCORRECT_SEMANTIC, + DataFailCause.INVALID_MANDATORY_INFO, + DataFailCause.MESSAGE_TYPE_UNSUPPORTED, + DataFailCause.MSG_TYPE_NONCOMPATIBLE_STATE, + DataFailCause.UNKNOWN_INFO_ELEMENT, + DataFailCause.CONDITIONAL_IE_ERROR, + DataFailCause.MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE, + DataFailCause.PROTOCOL_ERRORS, + DataFailCause.APN_TYPE_CONFLICT, + DataFailCause.INVALID_PCSCF_ADDR, + DataFailCause.INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN, + DataFailCause.EMM_ACCESS_BARRED, + DataFailCause.EMERGENCY_IFACE_ONLY, + DataFailCause.IFACE_MISMATCH, + DataFailCause.COMPANION_IFACE_IN_USE, + DataFailCause.IP_ADDRESS_MISMATCH, + DataFailCause.IFACE_AND_POL_FAMILY_MISMATCH, + DataFailCause.EMM_ACCESS_BARRED_INFINITE_RETRY, + DataFailCause.AUTH_FAILURE_ON_EMERGENCY_CALL, + DataFailCause.INVALID_DNS_ADDR, + DataFailCause.INVALID_PCSCF_OR_DNS_ADDRESS, + DataFailCause.CALL_PREEMPT_BY_EMERGENCY_APN, + DataFailCause.UE_INITIATED_DETACH_OR_DISCONNECT, + DataFailCause.MIP_FA_REASON_UNSPECIFIED, + DataFailCause.MIP_FA_ADMIN_PROHIBITED, + DataFailCause.MIP_FA_INSUFFICIENT_RESOURCES, + DataFailCause.MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE, + DataFailCause.MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE, + DataFailCause.MIP_FA_REQUESTED_LIFETIME_TOO_LONG, + DataFailCause.MIP_FA_MALFORMED_REQUEST, + DataFailCause.MIP_FA_MALFORMED_REPLY, + DataFailCause.MIP_FA_ENCAPSULATION_UNAVAILABLE, + DataFailCause.MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE, + DataFailCause.MIP_FA_REVERSE_TUNNEL_UNAVAILABLE, + DataFailCause.MIP_FA_REVERSE_TUNNEL_IS_MANDATORY, + DataFailCause.MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED, + DataFailCause.MIP_FA_MISSING_NAI, + DataFailCause.MIP_FA_MISSING_HOME_AGENT, + DataFailCause.MIP_FA_MISSING_HOME_ADDRESS, + DataFailCause.MIP_FA_UNKNOWN_CHALLENGE, + DataFailCause.MIP_FA_MISSING_CHALLENGE, + DataFailCause.MIP_FA_STALE_CHALLENGE, + DataFailCause.MIP_HA_REASON_UNSPECIFIED, + DataFailCause.MIP_HA_ADMIN_PROHIBITED, + DataFailCause.MIP_HA_INSUFFICIENT_RESOURCES, + DataFailCause.MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE, + DataFailCause.MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE, + DataFailCause.MIP_HA_REGISTRATION_ID_MISMATCH, + DataFailCause.MIP_HA_MALFORMED_REQUEST, + DataFailCause.MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS, + DataFailCause.MIP_HA_REVERSE_TUNNEL_UNAVAILABLE, + DataFailCause.MIP_HA_REVERSE_TUNNEL_IS_MANDATORY, + DataFailCause.MIP_HA_ENCAPSULATION_UNAVAILABLE, + DataFailCause.CLOSE_IN_PROGRESS, + DataFailCause.NETWORK_INITIATED_TERMINATION, + DataFailCause.MODEM_APP_PREEMPTED, + DataFailCause.PDN_IPV4_CALL_DISALLOWED, + DataFailCause.PDN_IPV4_CALL_THROTTLED, + DataFailCause.PDN_IPV6_CALL_DISALLOWED, + DataFailCause.PDN_IPV6_CALL_THROTTLED, + DataFailCause.MODEM_RESTART, + DataFailCause.PDP_PPP_NOT_SUPPORTED, + DataFailCause.UNPREFERRED_RAT, + DataFailCause.PHYSICAL_LINK_CLOSE_IN_PROGRESS, + DataFailCause.APN_PENDING_HANDOVER, + DataFailCause.PROFILE_BEARER_INCOMPATIBLE, + DataFailCause.SIM_CARD_CHANGED, + DataFailCause.LOW_POWER_MODE_OR_POWERING_DOWN, + DataFailCause.APN_DISABLED, + DataFailCause.MAX_PPP_INACTIVITY_TIMER_EXPIRED, + DataFailCause.IPV6_ADDRESS_TRANSFER_FAILED, + DataFailCause.TRAT_SWAP_FAILED, + DataFailCause.EHRPD_TO_HRPD_FALLBACK, + DataFailCause.MIP_CONFIG_FAILURE, + DataFailCause.PDN_INACTIVITY_TIMER_EXPIRED, + DataFailCause.MAX_IPV4_CONNECTIONS, + DataFailCause.MAX_IPV6_CONNECTIONS, + DataFailCause.APN_MISMATCH, + DataFailCause.IP_VERSION_MISMATCH, + DataFailCause.DUN_CALL_DISALLOWED, + DataFailCause.INTERNAL_EPC_NONEPC_TRANSITION, + DataFailCause.INTERFACE_IN_USE, + DataFailCause.APN_DISALLOWED_ON_ROAMING, + DataFailCause.APN_PARAMETERS_CHANGED, + DataFailCause.NULL_APN_DISALLOWED, + DataFailCause.THERMAL_MITIGATION, + DataFailCause.DATA_SETTINGS_DISABLED, + DataFailCause.DATA_ROAMING_SETTINGS_DISABLED, + DataFailCause.DDS_SWITCHED, + DataFailCause.FORBIDDEN_APN_NAME, + DataFailCause.DDS_SWITCH_IN_PROGRESS, + DataFailCause.CALL_DISALLOWED_IN_ROAMING, + DataFailCause.NON_IP_NOT_SUPPORTED, + DataFailCause.PDN_NON_IP_CALL_THROTTLED, + DataFailCause.PDN_NON_IP_CALL_DISALLOWED, + DataFailCause.CDMA_LOCK, + DataFailCause.CDMA_INTERCEPT, + DataFailCause.CDMA_REORDER, + DataFailCause.CDMA_RELEASE_DUE_TO_SO_REJECTION, + DataFailCause.CDMA_INCOMING_CALL, + DataFailCause.CDMA_ALERT_STOP, + DataFailCause.CHANNEL_ACQUISITION_FAILURE, + DataFailCause.MAX_ACCESS_PROBE, + DataFailCause.CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION, + DataFailCause.NO_RESPONSE_FROM_BASE_STATION, + DataFailCause.REJECTED_BY_BASE_STATION, + DataFailCause.CONCURRENT_SERVICES_INCOMPATIBLE, + DataFailCause.NO_CDMA_SERVICE, + DataFailCause.RUIM_NOT_PRESENT, + DataFailCause.CDMA_RETRY_ORDER, + DataFailCause.ACCESS_BLOCK, + DataFailCause.ACCESS_BLOCK_ALL, + DataFailCause.IS707B_MAX_ACCESS_PROBES, + DataFailCause.THERMAL_EMERGENCY, + DataFailCause.CONCURRENT_SERVICES_NOT_ALLOWED, + DataFailCause.INCOMING_CALL_REJECTED, + DataFailCause.NO_SERVICE_ON_GATEWAY, + DataFailCause.NO_GPRS_CONTEXT, + DataFailCause.ILLEGAL_MS, + DataFailCause.ILLEGAL_ME, + DataFailCause.GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED, + DataFailCause.GPRS_SERVICES_NOT_ALLOWED, + DataFailCause.MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK, + DataFailCause.IMPLICITLY_DETACHED, + DataFailCause.PLMN_NOT_ALLOWED, + DataFailCause.LOCATION_AREA_NOT_ALLOWED, + DataFailCause.GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, + DataFailCause.PDP_DUPLICATE, + DataFailCause.UE_RAT_CHANGE, + DataFailCause.CONGESTION, + DataFailCause.NO_PDP_CONTEXT_ACTIVATED, + DataFailCause.ACCESS_CLASS_DSAC_REJECTION, + DataFailCause.PDP_ACTIVATE_MAX_RETRY_FAILED, + DataFailCause.RADIO_ACCESS_BEARER_FAILURE, + DataFailCause.ESM_UNKNOWN_EPS_BEARER_CONTEXT, + DataFailCause.DRB_RELEASED_BY_RRC, + DataFailCause.CONNECTION_RELEASED, + DataFailCause.EMM_DETACHED, + DataFailCause.EMM_ATTACH_FAILED, + DataFailCause.EMM_ATTACH_STARTED, + DataFailCause.LTE_NAS_SERVICE_REQUEST_FAILED, + DataFailCause.DUPLICATE_BEARER_ID, + DataFailCause.ESM_COLLISION_SCENARIOS, + DataFailCause.ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK, + DataFailCause.ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER, + DataFailCause.ESM_BAD_OTA_MESSAGE, + DataFailCause.ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL, + DataFailCause.ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT, + DataFailCause.DS_EXPLICIT_DEACTIVATION, + DataFailCause.ESM_LOCAL_CAUSE_NONE, + DataFailCause.LTE_THROTTLING_NOT_REQUIRED, + DataFailCause.ACCESS_CONTROL_LIST_CHECK_FAILURE, + DataFailCause.SERVICE_NOT_ALLOWED_ON_PLMN, + DataFailCause.EMM_T3417_EXPIRED, + DataFailCause.EMM_T3417_EXT_EXPIRED, + DataFailCause.RRC_UPLINK_DATA_TRANSMISSION_FAILURE, + DataFailCause.RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER, + DataFailCause.RRC_UPLINK_CONNECTION_RELEASE, + DataFailCause.RRC_UPLINK_RADIO_LINK_FAILURE, + DataFailCause.RRC_UPLINK_ERROR_REQUEST_FROM_NAS, + DataFailCause.RRC_CONNECTION_ACCESS_STRATUM_FAILURE, + DataFailCause.RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS, + DataFailCause.RRC_CONNECTION_ACCESS_BARRED, + DataFailCause.RRC_CONNECTION_CELL_RESELECTION, + DataFailCause.RRC_CONNECTION_CONFIG_FAILURE, + DataFailCause.RRC_CONNECTION_TIMER_EXPIRED, + DataFailCause.RRC_CONNECTION_LINK_FAILURE, + DataFailCause.RRC_CONNECTION_CELL_NOT_CAMPED, + DataFailCause.RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE, + DataFailCause.RRC_CONNECTION_REJECT_BY_NETWORK, + DataFailCause.RRC_CONNECTION_NORMAL_RELEASE, + DataFailCause.RRC_CONNECTION_RADIO_LINK_FAILURE, + DataFailCause.RRC_CONNECTION_REESTABLISHMENT_FAILURE, + DataFailCause.RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER, + DataFailCause.RRC_CONNECTION_ABORT_REQUEST, + DataFailCause.RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR, + DataFailCause.NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH, + DataFailCause.NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH, + DataFailCause.ESM_PROCEDURE_TIME_OUT, + DataFailCause.INVALID_CONNECTION_ID, + DataFailCause.MAXIMIUM_NSAPIS_EXCEEDED, + DataFailCause.INVALID_PRIMARY_NSAPI, + DataFailCause.CANNOT_ENCODE_OTA_MESSAGE, + DataFailCause.RADIO_ACCESS_BEARER_SETUP_FAILURE, + DataFailCause.PDP_ESTABLISH_TIMEOUT_EXPIRED, + DataFailCause.PDP_MODIFY_TIMEOUT_EXPIRED, + DataFailCause.PDP_INACTIVE_TIMEOUT_EXPIRED, + DataFailCause.PDP_LOWERLAYER_ERROR, + DataFailCause.PDP_MODIFY_COLLISION, + DataFailCause.MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED, + DataFailCause.NAS_REQUEST_REJECTED_BY_NETWORK, + DataFailCause.RRC_CONNECTION_INVALID_REQUEST, + DataFailCause.RRC_CONNECTION_TRACKING_AREA_ID_CHANGED, + DataFailCause.RRC_CONNECTION_RF_UNAVAILABLE, + DataFailCause.RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE, + DataFailCause.RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE, + DataFailCause.RRC_CONNECTION_ABORTED_AFTER_HANDOVER, + DataFailCause.RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE, + DataFailCause.RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE, + DataFailCause.IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER, + DataFailCause.IMEI_NOT_ACCEPTED, + DataFailCause.EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, + DataFailCause.EPS_SERVICES_NOT_ALLOWED_IN_PLMN, + DataFailCause.MSC_TEMPORARILY_NOT_REACHABLE, + DataFailCause.CS_DOMAIN_NOT_AVAILABLE, + DataFailCause.ESM_FAILURE, + DataFailCause.MAC_FAILURE, + DataFailCause.SYNCHRONIZATION_FAILURE, + DataFailCause.UE_SECURITY_CAPABILITIES_MISMATCH, + DataFailCause.SECURITY_MODE_REJECTED, + DataFailCause.UNACCEPTABLE_NON_EPS_AUTHENTICATION, + DataFailCause.CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED, + DataFailCause.NO_EPS_BEARER_CONTEXT_ACTIVATED, + DataFailCause.INVALID_EMM_STATE, + DataFailCause.NAS_LAYER_FAILURE, + DataFailCause.MULTIPLE_PDP_CALL_NOT_ALLOWED, + DataFailCause.EMBMS_NOT_ENABLED, + DataFailCause.IRAT_HANDOVER_FAILED, + DataFailCause.EMBMS_REGULAR_DEACTIVATION, + DataFailCause.TEST_LOOPBACK_REGULAR_DEACTIVATION, + DataFailCause.LOWER_LAYER_REGISTRATION_FAILURE, + DataFailCause.DATA_PLAN_EXPIRED, + DataFailCause.UMTS_HANDOVER_TO_IWLAN, + DataFailCause.EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY, + DataFailCause.EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE, + DataFailCause.EVDO_HDR_CHANGED, + DataFailCause.EVDO_HDR_EXITED, + DataFailCause.EVDO_HDR_NO_SESSION, + DataFailCause.EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL, + DataFailCause.EVDO_HDR_CONNECTION_SETUP_TIMEOUT, + DataFailCause.FAILED_TO_ACQUIRE_COLOCATED_HDR, + DataFailCause.OTASP_COMMIT_IN_PROGRESS, + DataFailCause.NO_HYBRID_HDR_SERVICE, + DataFailCause.HDR_NO_LOCK_GRANTED, + DataFailCause.DBM_OR_SMS_IN_PROGRESS, + DataFailCause.HDR_FADE, + DataFailCause.HDR_ACCESS_FAILURE, + DataFailCause.UNSUPPORTED_1X_PREV, + DataFailCause.LOCAL_END, + DataFailCause.NO_SERVICE, + DataFailCause.FADE, + DataFailCause.NORMAL_RELEASE, + DataFailCause.ACCESS_ATTEMPT_ALREADY_IN_PROGRESS, + DataFailCause.REDIRECTION_OR_HANDOFF_IN_PROGRESS, + DataFailCause.EMERGENCY_MODE, + DataFailCause.PHONE_IN_USE, + DataFailCause.INVALID_MODE, + DataFailCause.INVALID_SIM_STATE, + DataFailCause.NO_COLLOCATED_HDR, + DataFailCause.UE_IS_ENTERING_POWERSAVE_MODE, + DataFailCause.DUAL_SWITCH, + DataFailCause.PPP_TIMEOUT, + DataFailCause.PPP_AUTH_FAILURE, + DataFailCause.PPP_OPTION_MISMATCH, + DataFailCause.PPP_PAP_FAILURE, + DataFailCause.PPP_CHAP_FAILURE, + DataFailCause.PPP_CLOSE_IN_PROGRESS, + DataFailCause.LIMITED_TO_IPV4, + DataFailCause.LIMITED_TO_IPV6, + DataFailCause.VSNCP_TIMEOUT, + DataFailCause.VSNCP_GEN_ERROR, + DataFailCause.VSNCP_APN_UNATHORIZED, + DataFailCause.VSNCP_PDN_LIMIT_EXCEEDED, + DataFailCause.VSNCP_NO_PDN_GATEWAY_ADDRESS, + DataFailCause.VSNCP_PDN_GATEWAY_UNREACHABLE, + DataFailCause.VSNCP_PDN_GATEWAY_REJECT, + DataFailCause.VSNCP_INSUFFICIENT_PARAMETERS, + DataFailCause.VSNCP_RESOURCE_UNAVAILABLE, + DataFailCause.VSNCP_ADMINISTRATIVELY_PROHIBITED, + DataFailCause.VSNCP_PDN_ID_IN_USE, + DataFailCause.VSNCP_SUBSCRIBER_LIMITATION, + DataFailCause.VSNCP_PDN_EXISTS_FOR_THIS_APN, + DataFailCause.VSNCP_RECONNECT_NOT_ALLOWED, + DataFailCause.IPV6_PREFIX_UNAVAILABLE, + DataFailCause.HANDOFF_PREFERENCE_CHANGED, + DataFailCause.OEM_DCFAILCAUSE_1, + DataFailCause.OEM_DCFAILCAUSE_2, + DataFailCause.OEM_DCFAILCAUSE_3, + DataFailCause.OEM_DCFAILCAUSE_4, + DataFailCause.OEM_DCFAILCAUSE_5, + DataFailCause.OEM_DCFAILCAUSE_6, + DataFailCause.OEM_DCFAILCAUSE_7, + DataFailCause.OEM_DCFAILCAUSE_8, + DataFailCause.OEM_DCFAILCAUSE_9, + DataFailCause.OEM_DCFAILCAUSE_10, + DataFailCause.OEM_DCFAILCAUSE_11, + DataFailCause.OEM_DCFAILCAUSE_12, + DataFailCause.OEM_DCFAILCAUSE_13, + DataFailCause.OEM_DCFAILCAUSE_14, + DataFailCause.OEM_DCFAILCAUSE_15, + DataFailCause.REGISTRATION_FAIL, + DataFailCause.GPRS_REGISTRATION_FAIL, + DataFailCause.SIGNAL_LOST, + DataFailCause.PREF_RADIO_TECH_CHANGED, + DataFailCause.RADIO_POWER_OFF, + DataFailCause.TETHERED_CALL_ACTIVE, + DataFailCause.ERROR_UNSPECIFIED, + DataFailCause.UNKNOWN, + DataFailCause.RADIO_NOT_AVAILABLE, + DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER, + DataFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN, + DataFailCause.LOST_CONNECTION, + DataFailCause.RESET_BY_FRAMEWORK + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DataFailureCause { + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"PRECISE_CALL_STATE_"}, + value = { + PreciseCallState.PRECISE_CALL_STATE_NOT_VALID, + PreciseCallState.PRECISE_CALL_STATE_IDLE, + PreciseCallState.PRECISE_CALL_STATE_ACTIVE, + PreciseCallState.PRECISE_CALL_STATE_HOLDING, + PreciseCallState.PRECISE_CALL_STATE_DIALING, + PreciseCallState.PRECISE_CALL_STATE_ALERTING, + PreciseCallState. PRECISE_CALL_STATE_INCOMING, + PreciseCallState.PRECISE_CALL_STATE_WAITING, + PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED, + PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING}) + public @interface PreciseCallStates {} + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"RIL_RADIO_TECHNOLOGY_" }, value = { + ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN, + ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, + ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, + ServiceState.RIL_RADIO_TECHNOLOGY_UMTS, + ServiceState.RIL_RADIO_TECHNOLOGY_IS95A, + ServiceState.RIL_RADIO_TECHNOLOGY_IS95B, + ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT, + ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0, + ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A, + ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA, + ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA, + ServiceState.RIL_RADIO_TECHNOLOGY_HSPA, + ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B, + ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD, + ServiceState.RIL_RADIO_TECHNOLOGY_LTE, + ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP, + ServiceState.RIL_RADIO_TECHNOLOGY_GSM, + ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA, + ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, + ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA, + ServiceState.RIL_RADIO_TECHNOLOGY_NR}) + public @interface RilRadioTechnology {} +} diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java index 1c03d8089df7..cd830adf23b0 100644 --- a/telephony/java/android/telephony/CallAttributes.java +++ b/telephony/java/android/telephony/CallAttributes.java @@ -21,8 +21,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import java.util.Objects; /** diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 3056f9b6dfa8..e2f60b857547 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -526,6 +526,15 @@ public class CarrierConfigManager { "default_vm_number_roaming_string"; /** + * Where there is no preloaded voicemail number on a SIM card, specifies the carrier's default + * voicemail number while the device is both roaming and not registered for IMS. + * When empty string, no default voicemail number is specified for roaming network and + * unregistered state in IMS. + */ + public static final String KEY_DEFAULT_VM_NUMBER_ROAMING_AND_IMS_UNREGISTERED_STRING = + "default_vm_number_roaming_and_ims_unregistered_string"; + + /** * Flag that specifies to use the user's own phone number as the voicemail number when there is * no pre-loaded voicemail number on the SIM card. * <p> @@ -1753,9 +1762,8 @@ public class CarrierConfigManager { "allow_emergency_video_calls_bool"; /** - * Flag indicating whether the carrier supports RCS presence indication for video calls. When - * {@code true}, the carrier supports RCS presence indication for video calls. When presence - * is supported, the device should use the + * Flag indicating whether the carrier supports RCS presence indication for + * User Capability Exchange (UCE). When presence is supported, the device should use the * {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE} bit mask and set the * {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE_VT_CAPABLE} bit to indicate * whether each contact supports video calling. The UI is made aware that presence is enabled @@ -1766,6 +1774,12 @@ public class CarrierConfigManager { public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool"; /** + * Flag indicating whether the carrier supports RCS SIP OPTIONS indication for + * User Capability Exchange (UCE). + */ + public static final String KEY_USE_RCS_SIP_OPTIONS_BOOL = "use_rcs_sip_options_bool"; + + /** * The duration in seconds that platform call and message blocking is disabled after the user * contacts emergency services. Platform considers values for below cases: * 1) 0 <= VALUE <= 604800(one week): the value will be used as the duration directly. @@ -2839,7 +2853,7 @@ public class CarrierConfigManager { "ping_test_before_data_switch_bool"; /** - * Controls time in milli seconds until DcTracker reevaluates 5G connection state. + * Controls time in milliseconds until DcTracker reevaluates 5G connection state. * @hide */ public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = @@ -3221,6 +3235,13 @@ public class CarrierConfigManager { public static final String KEY_CARRIER_CERTIFICATE_STRING_ARRAY = "carrier_certificate_string_array"; + /** + * DisconnectCause array to play busy tone. Value should be array of + * {@link android.telephony.DisconnectCause}. + */ + public static final String KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY = + "disconnect_cause_play_busytone_int_array"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -3247,6 +3268,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORT_DOWNGRADE_VT_TO_AUDIO_BOOL, true); sDefaults.putString(KEY_DEFAULT_VM_NUMBER_STRING, ""); sDefaults.putString(KEY_DEFAULT_VM_NUMBER_ROAMING_STRING, ""); + sDefaults.putString(KEY_DEFAULT_VM_NUMBER_ROAMING_AND_IMS_UNREGISTERED_STRING, ""); sDefaults.putBoolean(KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL, false); sDefaults.putBoolean(KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, true); sDefaults.putBoolean(KEY_VILTE_DATA_IS_METERED_BOOL, true); @@ -3464,6 +3486,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL, true); sDefaults.putInt(KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0); sDefaults.putBoolean(KEY_USE_RCS_PRESENCE_BOOL, false); + sDefaults.putBoolean(KEY_USE_RCS_SIP_OPTIONS_BOOL, false); sDefaults.putBoolean(KEY_FORCE_IMEI_BOOL, false); sDefaults.putInt( KEY_CDMA_ROAMING_MODE_INT, TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT); @@ -3653,6 +3676,8 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true); sDefaults.putAll(Ims.getDefaults()); sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, null); + sDefaults.putIntArray(KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY, + new int[] {4 /* BUSY */}); } /** diff --git a/telephony/java/android/telephony/CellBroadcastService.java b/telephony/java/android/telephony/CellBroadcastService.java new file mode 100644 index 000000000000..46eb9df8bdad --- /dev/null +++ b/telephony/java/android/telephony/CellBroadcastService.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.annotation.CallSuper; +import android.annotation.SystemApi; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.telephony.cdma.CdmaSmsCbProgramData; + +/** + * A service which exposes the cell broadcast handling module to the system. + * <p> + * To extend this class, you must declare the service in your manifest file to require the + * {@link android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE} permission and include an intent + * filter with the {@link #CELL_BROADCAST_SERVICE_INTERFACE}. + * Implementations of this service should run in the phone process and with its UID. + * <p> + * For example: + * <pre>{@code + * <manifest xmlns:android="http://schemas.android.com/apk/res/android" + * android:sharedUserId="android.uid.phone"> + * <service android:name=".MyCellBroadcastService" + * android:label="@string/service_name" + * android:process="com.android.phone" + * android:exported="true" + * android:permission="android.permission.BIND_CELL_BROADCAST_SERVICE"> + * <intent-filter> + * <action android:name="android.telephony.CellBroadcastService" /> + * </intent-filter> + * </service> + * </manifest> + * }</pre> + * @hide + */ +@SystemApi +public abstract class CellBroadcastService extends Service { + + public static final String CELL_BROADCAST_SERVICE_INTERFACE = + "android.telephony.CellBroadcastService"; + + private final ICellBroadcastService.Stub mStubWrapper; + + public CellBroadcastService() { + mStubWrapper = new ICellBroadcastServiceWrapper(); + } + + /** + * Handle a GSM cell broadcast SMS message forwarded from the system. + * @param slotIndex the index of the slot which received the message + * @param message the SMS PDU + */ + public abstract void onGsmCellBroadcastSms(int slotIndex, byte[] message); + + /** + * Handle a CDMA cell broadcast SMS message forwarded from the system. + * @param slotIndex the index of the slot which received the message + * @param bearerData the CDMA SMS bearer data + * @param serviceCategory the CDMA SCPT service category + */ + public abstract void onCdmaCellBroadcastSms(int slotIndex, byte[] bearerData, + @CdmaSmsCbProgramData.Category int serviceCategory); + + /** + * If overriding this method, call through to the super method for any unknown actions. + * {@inheritDoc} + */ + @Override + @CallSuper + public IBinder onBind(Intent intent) { + return mStubWrapper; + } + + /** + * A wrapper around ICellBroadcastService that forwards calls to implementations of + * {@link CellBroadcastService}. + * @hide + */ + public class ICellBroadcastServiceWrapper extends ICellBroadcastService.Stub { + /** + * Handle a GSM cell broadcast SMS. + * @param slotIndex the index of the slot which received the broadcast + * @param message the SMS message PDU + */ + @Override + public void handleGsmCellBroadcastSms(int slotIndex, byte[] message) { + CellBroadcastService.this.onGsmCellBroadcastSms(slotIndex, message); + } + + /** + * Handle a CDMA cell broadcast SMS. + * @param slotIndex the index of the slot which received the broadcast + * @param bearerData the CDMA SMS bearer data + * @param serviceCategory the CDMA SCPT service category + */ + @Override + public void handleCdmaCellBroadcastSms(int slotIndex, byte[] bearerData, + int serviceCategory) { + CellBroadcastService.this.onCdmaCellBroadcastSms(slotIndex, bearerData, + serviceCategory); + } + } +} diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index 432978d1c866..b7dab161c331 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -35,6 +35,15 @@ public abstract class CellIdentity implements Parcelable { /** @hide */ public static final int INVALID_CHANNEL_NUMBER = -1; + /** + * parameters for validation + * @hide + */ + public static final int MCC_LENGTH = 3; + + private static final int MNC_MIN_LENGTH = 2; + private static final int MNC_MAX_LENGTH = 3; + // Log tag /** @hide */ protected final String mTag; @@ -207,6 +216,17 @@ public abstract class CellIdentity implements Parcelable { dest.writeString(mAlphaShort); } + /** Used by phone interface manager to verify if a given string is valid MccMnc + * @hide + */ + public static boolean isValidPlmn(@NonNull String plmn) { + if (plmn.length() < MCC_LENGTH + MNC_MIN_LENGTH + || plmn.length() > MCC_LENGTH + MNC_MAX_LENGTH) { + return false; + } + return (isMcc(plmn.substring(0, MCC_LENGTH)) && isMnc(plmn.substring(MCC_LENGTH))); + } + /** * Construct from Parcel * @hide @@ -267,10 +287,10 @@ public abstract class CellIdentity implements Parcelable { /** @hide */ private static boolean isMcc(@NonNull String mcc) { // ensure no out of bounds indexing - if (mcc.length() != 3) return false; + if (mcc.length() != MCC_LENGTH) return false; // Character.isDigit allows all unicode digits, not just [0-9] - for (int i = 0; i < 3; i++) { + for (int i = 0; i < MCC_LENGTH; i++) { if (mcc.charAt(i) < '0' || mcc.charAt(i) > '9') return false; } @@ -280,7 +300,7 @@ public abstract class CellIdentity implements Parcelable { /** @hide */ private static boolean isMnc(@NonNull String mnc) { // ensure no out of bounds indexing - if (mnc.length() < 2 || mnc.length() > 3) return false; + if (mnc.length() < MNC_MIN_LENGTH || mnc.length() > MNC_MAX_LENGTH) return false; // Character.isDigit allows all unicode digits, not just [0-9] for (int i = 0; i < mnc.length(); i++) { @@ -289,4 +309,5 @@ public abstract class CellIdentity implements Parcelable { return true; } + } diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index 7edc91cd67e8..18687d400faf 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -189,11 +189,15 @@ public abstract class CellInfo implements Parcelable { mTimeStamp = ts; } - /** @hide */ + /** + * @return a {@link CellIdentity} instance. + */ @NonNull public abstract CellIdentity getCellIdentity(); - /** @hide */ + /** + * @return a {@link CellSignalStrength} instance. + */ @NonNull public abstract CellSignalStrength getCellSignalStrength(); diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java index 9775abd5075c..cea83230391d 100644 --- a/telephony/java/android/telephony/CellInfoNr.java +++ b/telephony/java/android/telephony/CellInfoNr.java @@ -19,6 +19,8 @@ package android.telephony; import android.annotation.NonNull; import android.os.Parcel; +import dalvik.annotation.codegen.CovariantReturnType; + import java.util.Objects; /** @@ -46,6 +48,7 @@ public final class CellInfoNr extends CellInfo { /** * @return a {@link CellIdentityNr} instance. */ + @CovariantReturnType(returnType = CellIdentityNr.class, presentAfter = 29) @Override @NonNull public CellIdentity getCellIdentity() { @@ -55,6 +58,7 @@ public final class CellInfoNr extends CellInfo { /** * @return a {@link CellSignalStrengthNr} instance. */ + @CovariantReturnType(returnType = CellSignalStrengthNr.class, presentAfter = 29) @Override @NonNull public CellSignalStrength getCellSignalStrength() { diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java index cdf01dab0059..4dc54f0fef58 100644 --- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java @@ -245,9 +245,12 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements } /** - * Get the Ec/No as dB + * Get the Ec/No (Energy per chip over the noise spectral density) as dB. * - * @hide + * Reference: TS 25.133 Section 9.1.2.3 + * + * @return the Ec/No of the measured cell in the range [-24, 1] or + * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable */ public int getEcNo() { return mEcNo; diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java index ca264f738e1d..246bec7de59e 100644 --- a/telephony/java/android/telephony/DataFailCause.java +++ b/telephony/java/android/telephony/DataFailCause.java @@ -21,6 +21,7 @@ import android.annotation.SystemApi; import android.content.Context; import android.os.PersistableBundle; +import android.telephony.Annotation.DataFailureCause; import com.android.internal.util.ArrayUtils; import java.lang.annotation.Retention; @@ -968,355 +969,6 @@ public final class DataFailCause { */ public static final int HANDOVER_FAILED = 0x10006; - /** @hide */ - @IntDef(value = { - NONE, - OPERATOR_BARRED, - NAS_SIGNALLING, - LLC_SNDCP, - INSUFFICIENT_RESOURCES, - MISSING_UNKNOWN_APN, - UNKNOWN_PDP_ADDRESS_TYPE, - USER_AUTHENTICATION, - ACTIVATION_REJECT_GGSN, - ACTIVATION_REJECT_UNSPECIFIED, - SERVICE_OPTION_NOT_SUPPORTED, - SERVICE_OPTION_NOT_SUBSCRIBED, - SERVICE_OPTION_OUT_OF_ORDER, - NSAPI_IN_USE, - REGULAR_DEACTIVATION, - QOS_NOT_ACCEPTED, - NETWORK_FAILURE, - UMTS_REACTIVATION_REQ, - FEATURE_NOT_SUPP, - TFT_SEMANTIC_ERROR, - TFT_SYTAX_ERROR, - UNKNOWN_PDP_CONTEXT, - FILTER_SEMANTIC_ERROR, - FILTER_SYTAX_ERROR, - PDP_WITHOUT_ACTIVE_TFT, - ACTIVATION_REJECTED_BCM_VIOLATION, - ONLY_IPV4_ALLOWED, - ONLY_IPV6_ALLOWED, - ONLY_SINGLE_BEARER_ALLOWED, - ESM_INFO_NOT_RECEIVED, - PDN_CONN_DOES_NOT_EXIST, - MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED, - COLLISION_WITH_NETWORK_INITIATED_REQUEST, - ONLY_IPV4V6_ALLOWED, - ONLY_NON_IP_ALLOWED, - UNSUPPORTED_QCI_VALUE, - BEARER_HANDLING_NOT_SUPPORTED, - ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED, - UNSUPPORTED_APN_IN_CURRENT_PLMN, - INVALID_TRANSACTION_ID, - MESSAGE_INCORRECT_SEMANTIC, - INVALID_MANDATORY_INFO, - MESSAGE_TYPE_UNSUPPORTED, - MSG_TYPE_NONCOMPATIBLE_STATE, - UNKNOWN_INFO_ELEMENT, - CONDITIONAL_IE_ERROR, - MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE, - PROTOCOL_ERRORS, - APN_TYPE_CONFLICT, - INVALID_PCSCF_ADDR, - INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN, - EMM_ACCESS_BARRED, - EMERGENCY_IFACE_ONLY, - IFACE_MISMATCH, - COMPANION_IFACE_IN_USE, - IP_ADDRESS_MISMATCH, - IFACE_AND_POL_FAMILY_MISMATCH, - EMM_ACCESS_BARRED_INFINITE_RETRY, - AUTH_FAILURE_ON_EMERGENCY_CALL, - INVALID_DNS_ADDR, - INVALID_PCSCF_OR_DNS_ADDRESS, - CALL_PREEMPT_BY_EMERGENCY_APN, - UE_INITIATED_DETACH_OR_DISCONNECT, - MIP_FA_REASON_UNSPECIFIED, - MIP_FA_ADMIN_PROHIBITED, - MIP_FA_INSUFFICIENT_RESOURCES, - MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE, - MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE, - MIP_FA_REQUESTED_LIFETIME_TOO_LONG, - MIP_FA_MALFORMED_REQUEST, - MIP_FA_MALFORMED_REPLY, - MIP_FA_ENCAPSULATION_UNAVAILABLE, - MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE, - MIP_FA_REVERSE_TUNNEL_UNAVAILABLE, - MIP_FA_REVERSE_TUNNEL_IS_MANDATORY, - MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED, - MIP_FA_MISSING_NAI, - MIP_FA_MISSING_HOME_AGENT, - MIP_FA_MISSING_HOME_ADDRESS, - MIP_FA_UNKNOWN_CHALLENGE, - MIP_FA_MISSING_CHALLENGE, - MIP_FA_STALE_CHALLENGE, - MIP_HA_REASON_UNSPECIFIED, - MIP_HA_ADMIN_PROHIBITED, - MIP_HA_INSUFFICIENT_RESOURCES, - MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE, - MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE, - MIP_HA_REGISTRATION_ID_MISMATCH, - MIP_HA_MALFORMED_REQUEST, - MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS, - MIP_HA_REVERSE_TUNNEL_UNAVAILABLE, - MIP_HA_REVERSE_TUNNEL_IS_MANDATORY, - MIP_HA_ENCAPSULATION_UNAVAILABLE, - CLOSE_IN_PROGRESS, - NETWORK_INITIATED_TERMINATION, - MODEM_APP_PREEMPTED, - PDN_IPV4_CALL_DISALLOWED, - PDN_IPV4_CALL_THROTTLED, - PDN_IPV6_CALL_DISALLOWED, - PDN_IPV6_CALL_THROTTLED, - MODEM_RESTART, - PDP_PPP_NOT_SUPPORTED, - UNPREFERRED_RAT, - PHYSICAL_LINK_CLOSE_IN_PROGRESS, - APN_PENDING_HANDOVER, - PROFILE_BEARER_INCOMPATIBLE, - SIM_CARD_CHANGED, - LOW_POWER_MODE_OR_POWERING_DOWN, - APN_DISABLED, - MAX_PPP_INACTIVITY_TIMER_EXPIRED, - IPV6_ADDRESS_TRANSFER_FAILED, - TRAT_SWAP_FAILED, - EHRPD_TO_HRPD_FALLBACK, - MIP_CONFIG_FAILURE, - PDN_INACTIVITY_TIMER_EXPIRED, - MAX_IPV4_CONNECTIONS, - MAX_IPV6_CONNECTIONS, - APN_MISMATCH, - IP_VERSION_MISMATCH, - DUN_CALL_DISALLOWED, - INTERNAL_EPC_NONEPC_TRANSITION, - INTERFACE_IN_USE, - APN_DISALLOWED_ON_ROAMING, - APN_PARAMETERS_CHANGED, - NULL_APN_DISALLOWED, - THERMAL_MITIGATION, - DATA_SETTINGS_DISABLED, - DATA_ROAMING_SETTINGS_DISABLED, - DDS_SWITCHED, - FORBIDDEN_APN_NAME, - DDS_SWITCH_IN_PROGRESS, - CALL_DISALLOWED_IN_ROAMING, - NON_IP_NOT_SUPPORTED, - PDN_NON_IP_CALL_THROTTLED, - PDN_NON_IP_CALL_DISALLOWED, - CDMA_LOCK, - CDMA_INTERCEPT, - CDMA_REORDER, - CDMA_RELEASE_DUE_TO_SO_REJECTION, - CDMA_INCOMING_CALL, - CDMA_ALERT_STOP, - CHANNEL_ACQUISITION_FAILURE, - MAX_ACCESS_PROBE, - CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION, - NO_RESPONSE_FROM_BASE_STATION, - REJECTED_BY_BASE_STATION, - CONCURRENT_SERVICES_INCOMPATIBLE, - NO_CDMA_SERVICE, - RUIM_NOT_PRESENT, - CDMA_RETRY_ORDER, - ACCESS_BLOCK, - ACCESS_BLOCK_ALL, - IS707B_MAX_ACCESS_PROBES, - THERMAL_EMERGENCY, - CONCURRENT_SERVICES_NOT_ALLOWED, - INCOMING_CALL_REJECTED, - NO_SERVICE_ON_GATEWAY, - NO_GPRS_CONTEXT, - ILLEGAL_MS, - ILLEGAL_ME, - GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED, - GPRS_SERVICES_NOT_ALLOWED, - MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK, - IMPLICITLY_DETACHED, - PLMN_NOT_ALLOWED, - LOCATION_AREA_NOT_ALLOWED, - GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, - PDP_DUPLICATE, - UE_RAT_CHANGE, - CONGESTION, - NO_PDP_CONTEXT_ACTIVATED, - ACCESS_CLASS_DSAC_REJECTION, - PDP_ACTIVATE_MAX_RETRY_FAILED, - RADIO_ACCESS_BEARER_FAILURE, - ESM_UNKNOWN_EPS_BEARER_CONTEXT, - DRB_RELEASED_BY_RRC, - CONNECTION_RELEASED, - EMM_DETACHED, - EMM_ATTACH_FAILED, - EMM_ATTACH_STARTED, - LTE_NAS_SERVICE_REQUEST_FAILED, - DUPLICATE_BEARER_ID, - ESM_COLLISION_SCENARIOS, - ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK, - ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER, - ESM_BAD_OTA_MESSAGE, - ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL, - ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT, - DS_EXPLICIT_DEACTIVATION, - ESM_LOCAL_CAUSE_NONE, - LTE_THROTTLING_NOT_REQUIRED, - ACCESS_CONTROL_LIST_CHECK_FAILURE, - SERVICE_NOT_ALLOWED_ON_PLMN, - EMM_T3417_EXPIRED, - EMM_T3417_EXT_EXPIRED, - RRC_UPLINK_DATA_TRANSMISSION_FAILURE, - RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER, - RRC_UPLINK_CONNECTION_RELEASE, - RRC_UPLINK_RADIO_LINK_FAILURE, - RRC_UPLINK_ERROR_REQUEST_FROM_NAS, - RRC_CONNECTION_ACCESS_STRATUM_FAILURE, - RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS, - RRC_CONNECTION_ACCESS_BARRED, - RRC_CONNECTION_CELL_RESELECTION, - RRC_CONNECTION_CONFIG_FAILURE, - RRC_CONNECTION_TIMER_EXPIRED, - RRC_CONNECTION_LINK_FAILURE, - RRC_CONNECTION_CELL_NOT_CAMPED, - RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE, - RRC_CONNECTION_REJECT_BY_NETWORK, - RRC_CONNECTION_NORMAL_RELEASE, - RRC_CONNECTION_RADIO_LINK_FAILURE, - RRC_CONNECTION_REESTABLISHMENT_FAILURE, - RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER, - RRC_CONNECTION_ABORT_REQUEST, - RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR, - NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH, - NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH, - ESM_PROCEDURE_TIME_OUT, - INVALID_CONNECTION_ID, - MAXIMIUM_NSAPIS_EXCEEDED, - INVALID_PRIMARY_NSAPI, - CANNOT_ENCODE_OTA_MESSAGE, - RADIO_ACCESS_BEARER_SETUP_FAILURE, - PDP_ESTABLISH_TIMEOUT_EXPIRED, - PDP_MODIFY_TIMEOUT_EXPIRED, - PDP_INACTIVE_TIMEOUT_EXPIRED, - PDP_LOWERLAYER_ERROR, - PDP_MODIFY_COLLISION, - MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED, - NAS_REQUEST_REJECTED_BY_NETWORK, - RRC_CONNECTION_INVALID_REQUEST, - RRC_CONNECTION_TRACKING_AREA_ID_CHANGED, - RRC_CONNECTION_RF_UNAVAILABLE, - RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE, - RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE, - RRC_CONNECTION_ABORTED_AFTER_HANDOVER, - RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE, - RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE, - IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER, - IMEI_NOT_ACCEPTED, - EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, - EPS_SERVICES_NOT_ALLOWED_IN_PLMN, - MSC_TEMPORARILY_NOT_REACHABLE, - CS_DOMAIN_NOT_AVAILABLE, - ESM_FAILURE, - MAC_FAILURE, - SYNCHRONIZATION_FAILURE, - UE_SECURITY_CAPABILITIES_MISMATCH, - SECURITY_MODE_REJECTED, - UNACCEPTABLE_NON_EPS_AUTHENTICATION, - CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED, - NO_EPS_BEARER_CONTEXT_ACTIVATED, - INVALID_EMM_STATE, - NAS_LAYER_FAILURE, - MULTIPLE_PDP_CALL_NOT_ALLOWED, - EMBMS_NOT_ENABLED, - IRAT_HANDOVER_FAILED, - EMBMS_REGULAR_DEACTIVATION, - TEST_LOOPBACK_REGULAR_DEACTIVATION, - LOWER_LAYER_REGISTRATION_FAILURE, - DATA_PLAN_EXPIRED, - UMTS_HANDOVER_TO_IWLAN, - EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY, - EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE, - EVDO_HDR_CHANGED, - EVDO_HDR_EXITED, - EVDO_HDR_NO_SESSION, - EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL, - EVDO_HDR_CONNECTION_SETUP_TIMEOUT, - FAILED_TO_ACQUIRE_COLOCATED_HDR, - OTASP_COMMIT_IN_PROGRESS, - NO_HYBRID_HDR_SERVICE, - HDR_NO_LOCK_GRANTED, - DBM_OR_SMS_IN_PROGRESS, - HDR_FADE, - HDR_ACCESS_FAILURE, - UNSUPPORTED_1X_PREV, - LOCAL_END, - NO_SERVICE, - FADE, - NORMAL_RELEASE, - ACCESS_ATTEMPT_ALREADY_IN_PROGRESS, - REDIRECTION_OR_HANDOFF_IN_PROGRESS, - EMERGENCY_MODE, - PHONE_IN_USE, - INVALID_MODE, - INVALID_SIM_STATE, - NO_COLLOCATED_HDR, - UE_IS_ENTERING_POWERSAVE_MODE, - DUAL_SWITCH, - PPP_TIMEOUT, - PPP_AUTH_FAILURE, - PPP_OPTION_MISMATCH, - PPP_PAP_FAILURE, - PPP_CHAP_FAILURE, - PPP_CLOSE_IN_PROGRESS, - LIMITED_TO_IPV4, - LIMITED_TO_IPV6, - VSNCP_TIMEOUT, - VSNCP_GEN_ERROR, - VSNCP_APN_UNATHORIZED, - VSNCP_PDN_LIMIT_EXCEEDED, - VSNCP_NO_PDN_GATEWAY_ADDRESS, - VSNCP_PDN_GATEWAY_UNREACHABLE, - VSNCP_PDN_GATEWAY_REJECT, - VSNCP_INSUFFICIENT_PARAMETERS, - VSNCP_RESOURCE_UNAVAILABLE, - VSNCP_ADMINISTRATIVELY_PROHIBITED, - VSNCP_PDN_ID_IN_USE, - VSNCP_SUBSCRIBER_LIMITATION, - VSNCP_PDN_EXISTS_FOR_THIS_APN, - VSNCP_RECONNECT_NOT_ALLOWED, - IPV6_PREFIX_UNAVAILABLE, - HANDOFF_PREFERENCE_CHANGED, - OEM_DCFAILCAUSE_1, - OEM_DCFAILCAUSE_2, - OEM_DCFAILCAUSE_3, - OEM_DCFAILCAUSE_4, - OEM_DCFAILCAUSE_5, - OEM_DCFAILCAUSE_6, - OEM_DCFAILCAUSE_7, - OEM_DCFAILCAUSE_8, - OEM_DCFAILCAUSE_9, - OEM_DCFAILCAUSE_10, - OEM_DCFAILCAUSE_11, - OEM_DCFAILCAUSE_12, - OEM_DCFAILCAUSE_13, - OEM_DCFAILCAUSE_14, - OEM_DCFAILCAUSE_15, - REGISTRATION_FAIL, - GPRS_REGISTRATION_FAIL, - SIGNAL_LOST, - PREF_RADIO_TECH_CHANGED, - RADIO_POWER_OFF, - TETHERED_CALL_ACTIVE, - ERROR_UNSPECIFIED, - UNKNOWN, - RADIO_NOT_AVAILABLE, - UNACCEPTABLE_NETWORK_PARAMETER, - CONNECTION_TO_DATACONNECTIONAC_BROKEN, - LOST_CONNECTION, - RESET_BY_FRAMEWORK - }) - @Retention(RetentionPolicy.SOURCE) - public @interface FailCause{} - private static final Map<Integer, String> sFailCauseMap; static { sFailCauseMap = new HashMap<>(); @@ -1737,7 +1389,8 @@ public final class DataFailCause { * * @hide */ - public static boolean isRadioRestartFailure(@NonNull Context context, @FailCause int cause, + public static boolean isRadioRestartFailure(@NonNull Context context, + @DataFailureCause int cause, int subId) { CarrierConfigManager configManager = (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); @@ -1765,7 +1418,8 @@ public final class DataFailCause { } /** @hide */ - public static boolean isPermanentFailure(@NonNull Context context, @FailCause int failCause, + public static boolean isPermanentFailure(@NonNull Context context, + @DataFailureCause int failCause, int subId) { synchronized (sPermanentFailureCache) { @@ -1825,7 +1479,7 @@ public final class DataFailCause { } /** @hide */ - public static boolean isEventLoggable(@FailCause int dataFailCause) { + public static boolean isEventLoggable(@DataFailureCause int dataFailCause) { return (dataFailCause == OPERATOR_BARRED) || (dataFailCause == INSUFFICIENT_RESOURCES) || (dataFailCause == UNKNOWN_PDP_ADDRESS_TYPE) || (dataFailCause == USER_AUTHENTICATION) @@ -1845,13 +1499,13 @@ public final class DataFailCause { } /** @hide */ - public static String toString(@FailCause int dataFailCause) { + public static String toString(@DataFailureCause int dataFailCause) { int cause = getFailCause(dataFailCause); return (cause == UNKNOWN) ? "UNKNOWN(" + dataFailCause + ")" : sFailCauseMap.get(cause); } /** @hide */ - public static int getFailCause(@FailCause int failCause) { + public static int getFailCause(@DataFailureCause int failCause) { if (sFailCauseMap.containsKey(failCause)) { return failCause; } else { diff --git a/telephony/java/android/telephony/ICellBroadcastService.aidl b/telephony/java/android/telephony/ICellBroadcastService.aidl new file mode 100644 index 000000000000..bcd6cc546eed --- /dev/null +++ b/telephony/java/android/telephony/ICellBroadcastService.aidl @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +/** + * Service bound to by the system to allow custom handling of cell broadcast messages. + * <p> + * @see android.telephony.CellBroadcastService + * @hide + */ +interface ICellBroadcastService { + + /** @see android.telephony.CellBroadcastService#onGsmCellBroadcastSms */ + oneway void handleGsmCellBroadcastSms(int slotId, in byte[] message); + + /** @see android.telephony.CellBroadcastService#onCdmaCellBroadcastSms */ + oneway void handleCdmaCellBroadcastSms(int slotId, in byte[] bearerData, int serviceCategory); +} diff --git a/telephony/java/android/telephony/ICellInfoCallback.aidl b/telephony/java/android/telephony/ICellInfoCallback.aidl index ee3c1b1be6d9..60732a3db59a 100644 --- a/telephony/java/android/telephony/ICellInfoCallback.aidl +++ b/telephony/java/android/telephony/ICellInfoCallback.aidl @@ -16,7 +16,6 @@ package android.telephony; -import android.os.ParcelableException; import android.telephony.CellInfo; import java.util.List; @@ -28,5 +27,5 @@ import java.util.List; oneway interface ICellInfoCallback { void onCellInfo(in List<CellInfo> state); - void onError(in int errorCode, in ParcelableException detail); + void onError(in int errorCode, in String exceptionName, in String message); } diff --git a/telephony/java/android/telephony/IFinancialSmsCallback.aidl b/telephony/java/android/telephony/IFinancialSmsCallback.aidl deleted file mode 100644 index aa88615c15cf..000000000000 --- a/telephony/java/android/telephony/IFinancialSmsCallback.aidl +++ /dev/null @@ -1,34 +0,0 @@ -/* -** Copyright 2019, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ -package android.telephony; - -import android.app.PendingIntent; -import android.database.CursorWindow; -import android.net.Uri; -import android.os.Bundle; -import com.android.internal.telephony.SmsRawData; - -/** Interface for returning back the financial sms messages asynchrously. - * @hide - */ -interface IFinancialSmsCallback { - /** - * Return sms messages back to calling financial app. - * - * @param messages the sms messages returned for cinancial app. - */ - oneway void onGetSmsMessagesForFinancialApp(in CursorWindow messages); -} diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java index da4da79a39df..45deea206cfc 100644 --- a/telephony/java/android/telephony/MbmsDownloadSession.java +++ b/telephony/java/android/telephony/MbmsDownloadSession.java @@ -243,6 +243,7 @@ public class MbmsDownloadSession implements AutoCloseable { }; private AtomicReference<IMbmsDownloadService> mService = new AtomicReference<>(null); + private ServiceConnection mServiceConnection; private final InternalDownloadSessionCallback mInternalCallback; private final Map<DownloadStatusListener, InternalDownloadStatusListener> mInternalDownloadStatusListeners = new HashMap<>(); @@ -318,56 +319,66 @@ public class MbmsDownloadSession implements AutoCloseable { } private int bindAndInitialize() { - return MbmsUtils.startBinding(mContext, MBMS_DOWNLOAD_SERVICE_ACTION, - new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - IMbmsDownloadService downloadService = - IMbmsDownloadService.Stub.asInterface(service); - int result; - try { - result = downloadService.initialize(mSubscriptionId, mInternalCallback); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Service died before initialization"); - sIsInitialized.set(false); - return; - } catch (RuntimeException e) { - Log.e(LOG_TAG, "Runtime exception during initialization"); - sendErrorToApp( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } - if (result == MbmsErrors.UNKNOWN) { - // Unbind and throw an obvious error - close(); - throw new IllegalStateException("Middleware must not return an" - + " unknown error code"); - } - if (result != MbmsErrors.SUCCESS) { - sendErrorToApp(result, "Error returned during initialization"); - sIsInitialized.set(false); - return; - } - try { - downloadService.asBinder().linkToDeath(mDeathRecipient, 0); - } catch (RemoteException e) { - sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, - "Middleware lost during initialization"); - sIsInitialized.set(false); - return; - } - mService.set(downloadService); - } + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IMbmsDownloadService downloadService = + IMbmsDownloadService.Stub.asInterface(service); + int result; + try { + result = downloadService.initialize(mSubscriptionId, mInternalCallback); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Service died before initialization"); + sIsInitialized.set(false); + return; + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Runtime exception during initialization"); + sendErrorToApp( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } + if (result == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return an" + + " unknown error code"); + } + if (result != MbmsErrors.SUCCESS) { + sendErrorToApp(result, "Error returned during initialization"); + sIsInitialized.set(false); + return; + } + try { + downloadService.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware lost during initialization"); + sIsInitialized.set(false); + return; + } + mService.set(downloadService); + } - @Override - public void onServiceDisconnected(ComponentName name) { - Log.w(LOG_TAG, "bindAndInitialize: Remote service disconnected"); - sIsInitialized.set(false); - mService.set(null); - } - }); + @Override + public void onServiceDisconnected(ComponentName name) { + Log.w(LOG_TAG, "bindAndInitialize: Remote service disconnected"); + sIsInitialized.set(false); + mService.set(null); + } + + @Override + public void onNullBinding(ComponentName name) { + Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null"); + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware service binding returned null"); + sIsInitialized.set(false); + mService.set(null); + mContext.unbindService(this); + } + }; + return MbmsUtils.startBinding(mContext, MBMS_DOWNLOAD_SERVICE_ACTION, mServiceConnection); } /** @@ -965,17 +976,19 @@ public class MbmsDownloadSession implements AutoCloseable { public void close() { try { IMbmsDownloadService downloadService = mService.get(); - if (downloadService == null) { + if (downloadService == null || mServiceConnection == null) { Log.i(LOG_TAG, "Service already dead"); return; } downloadService.dispose(mSubscriptionId); + mContext.unbindService(mServiceConnection); } catch (RemoteException e) { // Ignore Log.i(LOG_TAG, "Remote exception while disposing of service"); } finally { mService.set(null); sIsInitialized.set(false); + mServiceConnection = null; mInternalCallback.stop(); } } diff --git a/telephony/java/android/telephony/MbmsGroupCallSession.java b/telephony/java/android/telephony/MbmsGroupCallSession.java index f1be31fa5477..d54071f28be9 100644 --- a/telephony/java/android/telephony/MbmsGroupCallSession.java +++ b/telephony/java/android/telephony/MbmsGroupCallSession.java @@ -80,6 +80,7 @@ public class MbmsGroupCallSession implements AutoCloseable { }; private InternalGroupCallSessionCallback mInternalCallback; + private ServiceConnection mServiceConnection; private Set<GroupCall> mKnownActiveGroupCalls = new ArraySet<>(); private final Context mContext; @@ -163,7 +164,7 @@ public class MbmsGroupCallSession implements AutoCloseable { public void close() { try { IMbmsGroupCallService groupCallService = mService.get(); - if (groupCallService == null) { + if (groupCallService == null || mServiceConnection == null) { // Ignore and return, assume already disposed. return; } @@ -172,11 +173,13 @@ public class MbmsGroupCallSession implements AutoCloseable { s.getCallback().stop(); } mKnownActiveGroupCalls.clear(); + mContext.unbindService(mServiceConnection); } catch (RemoteException e) { // Ignore for now } finally { mService.set(null); sIsInitialized.set(false); + mServiceConnection = null; mInternalCallback.stop(); } } @@ -244,59 +247,69 @@ public class MbmsGroupCallSession implements AutoCloseable { } private int bindAndInitialize() { - return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION, - new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - IMbmsGroupCallService groupCallService = - IMbmsGroupCallService.Stub.asInterface(service); - int result; - try { - result = groupCallService.initialize(mInternalCallback, - mSubscriptionId); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Service died before initialization"); - mInternalCallback.onError( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } catch (RuntimeException e) { - Log.e(LOG_TAG, "Runtime exception during initialization"); - mInternalCallback.onError( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } - if (result == MbmsErrors.UNKNOWN) { - // Unbind and throw an obvious error - close(); - throw new IllegalStateException("Middleware must not return" - + " an unknown error code"); - } - if (result != MbmsErrors.SUCCESS) { - mInternalCallback.onError(result, - "Error returned during initialization"); - sIsInitialized.set(false); - return; - } - try { - groupCallService.asBinder().linkToDeath(mDeathRecipient, 0); - } catch (RemoteException e) { - mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, - "Middleware lost during initialization"); - sIsInitialized.set(false); - return; - } - mService.set(groupCallService); - } + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IMbmsGroupCallService groupCallService = + IMbmsGroupCallService.Stub.asInterface(service); + int result; + try { + result = groupCallService.initialize(mInternalCallback, + mSubscriptionId); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Service died before initialization"); + mInternalCallback.onError( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Runtime exception during initialization"); + mInternalCallback.onError( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } + if (result == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return" + + " an unknown error code"); + } + if (result != MbmsErrors.SUCCESS) { + mInternalCallback.onError(result, + "Error returned during initialization"); + sIsInitialized.set(false); + return; + } + try { + groupCallService.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware lost during initialization"); + sIsInitialized.set(false); + return; + } + mService.set(groupCallService); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + sIsInitialized.set(false); + mService.set(null); + } - @Override - public void onServiceDisconnected(ComponentName name) { - sIsInitialized.set(false); - mService.set(null); - } - }); + @Override + public void onNullBinding(ComponentName name) { + Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null"); + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware service binding returned null"); + sIsInitialized.set(false); + mService.set(null); + mContext.unbindService(this); + } + }; + return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION, mServiceConnection); } } diff --git a/telephony/java/android/telephony/MbmsStreamingSession.java b/telephony/java/android/telephony/MbmsStreamingSession.java index cd465d22d331..3fbbc03f0c67 100644 --- a/telephony/java/android/telephony/MbmsStreamingSession.java +++ b/telephony/java/android/telephony/MbmsStreamingSession.java @@ -82,6 +82,7 @@ public class MbmsStreamingSession implements AutoCloseable { }; private InternalStreamingSessionCallback mInternalCallback; + private ServiceConnection mServiceConnection; private Set<StreamingService> mKnownActiveStreamingServices = new ArraySet<>(); private final Context mContext; @@ -168,7 +169,7 @@ public class MbmsStreamingSession implements AutoCloseable { public void close() { try { IMbmsStreamingService streamingService = mService.get(); - if (streamingService == null) { + if (streamingService == null || mServiceConnection == null) { // Ignore and return, assume already disposed. return; } @@ -177,11 +178,13 @@ public class MbmsStreamingSession implements AutoCloseable { s.getCallback().stop(); } mKnownActiveStreamingServices.clear(); + mContext.unbindService(mServiceConnection); } catch (RemoteException e) { // Ignore for now } finally { mService.set(null); sIsInitialized.set(false); + mServiceConnection = null; mInternalCallback.stop(); } } @@ -286,59 +289,69 @@ public class MbmsStreamingSession implements AutoCloseable { } private int bindAndInitialize() { - return MbmsUtils.startBinding(mContext, MBMS_STREAMING_SERVICE_ACTION, - new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - IMbmsStreamingService streamingService = - IMbmsStreamingService.Stub.asInterface(service); - int result; - try { - result = streamingService.initialize(mInternalCallback, - mSubscriptionId); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Service died before initialization"); - sendErrorToApp( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } catch (RuntimeException e) { - Log.e(LOG_TAG, "Runtime exception during initialization"); - sendErrorToApp( - MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, - e.toString()); - sIsInitialized.set(false); - return; - } - if (result == MbmsErrors.UNKNOWN) { - // Unbind and throw an obvious error - close(); - throw new IllegalStateException("Middleware must not return" - + " an unknown error code"); - } - if (result != MbmsErrors.SUCCESS) { - sendErrorToApp(result, "Error returned during initialization"); - sIsInitialized.set(false); - return; - } - try { - streamingService.asBinder().linkToDeath(mDeathRecipient, 0); - } catch (RemoteException e) { - sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, - "Middleware lost during initialization"); - sIsInitialized.set(false); - return; - } - mService.set(streamingService); - } + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IMbmsStreamingService streamingService = + IMbmsStreamingService.Stub.asInterface(service); + int result; + try { + result = streamingService.initialize(mInternalCallback, + mSubscriptionId); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Service died before initialization"); + sendErrorToApp( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Runtime exception during initialization"); + sendErrorToApp( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } + if (result == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return" + + " an unknown error code"); + } + if (result != MbmsErrors.SUCCESS) { + sendErrorToApp(result, "Error returned during initialization"); + sIsInitialized.set(false); + return; + } + try { + streamingService.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware lost during initialization"); + sIsInitialized.set(false); + return; + } + mService.set(streamingService); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + sIsInitialized.set(false); + mService.set(null); + } - @Override - public void onServiceDisconnected(ComponentName name) { - sIsInitialized.set(false); - mService.set(null); - } - }); + @Override + public void onNullBinding(ComponentName name) { + Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null"); + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware service binding returned null"); + sIsInitialized.set(false); + mService.set(null); + mContext.unbindService(this); + } + }; + return MbmsUtils.startBinding(mContext, MBMS_STREAMING_SERVICE_ACTION, mServiceConnection); } private void sendErrorToApp(int errorCode, String message) { diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java index 43bc85c9f2bd..d105fe3ddc71 100644 --- a/telephony/java/android/telephony/ModemActivityInfo.java +++ b/telephony/java/android/telephony/ModemActivityInfo.java @@ -20,11 +20,10 @@ import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; - import android.os.SystemClock; import android.util.Range; + import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -64,17 +63,20 @@ public final class ModemActivityInfo implements Parcelable { mTimestamp = timestamp; mSleepTimeMs = sleepTimeMs; mIdleTimeMs = idleTimeMs; - if (txTimeMs != null) { - populateTransmitPowerRange(txTimeMs); - } + populateTransmitPowerRange(txTimeMs); mRxTimeMs = rxTimeMs; } /** helper API to populate tx power range for each bucket **/ private void populateTransmitPowerRange(@NonNull int[] transmitPowerMs) { - for (int i = 0; i < Math.min(transmitPowerMs.length, TX_POWER_LEVELS); i++) { + int i = 0; + for ( ; i < Math.min(transmitPowerMs.length, TX_POWER_LEVELS); i++) { mTransmitPowerInfo.add(i, new TransmitPower(TX_POWER_RANGES[i], transmitPowerMs[i])); } + // Make sure that mTransmitPowerInfo is fully initialized. + for ( ; i < TX_POWER_LEVELS; i++) { + mTransmitPowerInfo.add(i, new TransmitPower(TX_POWER_RANGES[i], 0)); + } } @Override diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index a76b8da09064..56b723631115 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -24,7 +24,7 @@ import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.TransportType; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -90,7 +90,7 @@ public final class NetworkRegistrationInfo implements Parcelable { * Dual Connectivity(EN-DC). * @hide */ - public static final int NR_STATE_NONE = -1; + public static final int NR_STATE_NONE = 0; /** * The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java deleted file mode 100644 index 1ffed2543ee4..000000000000 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ /dev/null @@ -1,1268 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony; - -import android.Manifest; -import android.annotation.NonNull; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.annotation.UnsupportedAppUsage; -import android.os.Binder; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.Looper; -import android.telephony.emergency.EmergencyNumber; -import android.telephony.ims.ImsReasonInfo; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.telephony.IPhoneStateListener; - -import dalvik.system.VMRuntime; - -import java.lang.ref.WeakReference; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executor; - -/** - * A listener class for monitoring changes in specific telephony states - * on the device, including service state, signal strength, message - * waiting indicator (voicemail), and others. - * <p> - * Override the methods for the state that you wish to receive updates for, and - * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_ - * flags to {@link TelephonyManager#listen TelephonyManager.listen()}. Methods are - * called when the state changes, as well as once on initial registration. - * <p> - * Note that access to some telephony information is - * permission-protected. Your application won't receive updates for protected - * information unless it has the appropriate permissions declared in - * its manifest file. Where permissions apply, they are noted in the - * appropriate LISTEN_ flags. - */ -public class PhoneStateListener { - private static final String LOG_TAG = "PhoneStateListener"; - private static final boolean DBG = false; // STOPSHIP if true - - /** - * Stop listening for updates. - * - * The PhoneStateListener is not tied to any subscription and unregistered for any update. - */ - public static final int LISTEN_NONE = 0; - - /** - * Listen for changes to the network service state (cellular). - * - * @see #onServiceStateChanged - * @see ServiceState - */ - public static final int LISTEN_SERVICE_STATE = 0x00000001; - - /** - * Listen for changes to the network signal strength (cellular). - * {@more} - * - * @see #onSignalStrengthChanged - * - * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS} - */ - @Deprecated - public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002; - - /** - * Listen for changes to the message-waiting indicator. - * {@more} - * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE - * READ_PHONE_STATE} or that the calling app has carrier privileges (see - * {@link TelephonyManager#hasCarrierPrivileges}). - * <p> - * Example: The status bar uses this to determine when to display the - * voicemail icon. - * - * @see #onMessageWaitingIndicatorChanged - */ - public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004; - - /** - * Listen for changes to the call-forwarding indicator. - * {@more} - * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE - * READ_PHONE_STATE} or that the calling app has carrier privileges (see - * {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see #onCallForwardingIndicatorChanged - */ - public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008; - - /** - * Listen for changes to the device's cell location. Note that - * this will result in frequent callbacks to the listener. - * {@more} - * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION - * ACCESS_COARSE_LOCATION} - * <p> - * If you need regular location updates but want more control over - * the update interval or location precision, you can set up a listener - * through the {@link android.location.LocationManager location manager} - * instead. - * - * @see #onCellLocationChanged - */ - public static final int LISTEN_CELL_LOCATION = 0x00000010; - - /** - * Listen for changes to the device call state. - * {@more} - * - * @see #onCallStateChanged - */ - public static final int LISTEN_CALL_STATE = 0x00000020; - - /** - * Listen for changes to the data connection state (cellular). - * - * @see #onDataConnectionStateChanged - */ - public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040; - - /** - * Listen for changes to the direction of data traffic on the data - * connection (cellular). - * {@more} - * Example: The status bar uses this to display the appropriate - * data-traffic icon. - * - * @see #onDataActivity - */ - public static final int LISTEN_DATA_ACTIVITY = 0x00000080; - - /** - * Listen for changes to the network signal strengths (cellular). - * <p> - * Example: The status bar uses this to control the signal-strength - * icon. - * - * @see #onSignalStrengthsChanged - */ - public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100; - - /** - * Listen for changes to OTASP mode. - * - * @see #onOtaspChanged - * @hide - */ - public static final int LISTEN_OTASP_CHANGED = 0x00000200; - - /** - * Listen for changes to observed cell info. - * - * @see #onCellInfoChanged - */ - public static final int LISTEN_CELL_INFO = 0x00000400; - - /** - * Listen for {@link PreciseCallState.State} of ringing, background and foreground calls. - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public static final int LISTEN_PRECISE_CALL_STATE = 0x00000800; - - /** - * Listen for {@link PreciseDataConnectionState} on the data connection (cellular). - * - * @see #onPreciseDataConnectionStateChanged - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000; - - /** - * Listen for real time info for all data connections (cellular)). - * {@more} - * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE - * READ_PRECISE_PHONE_STATE} - * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) - * - * @deprecated Use {@link TelephonyManager#getModemActivityInfo()} - * @hide - */ - @Deprecated - public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000; - - /** - * Listen for changes to the SRVCC state of the active call. - * @see #onServiceStateChanged(ServiceState) - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public static final int LISTEN_SRVCC_STATE_CHANGED = 0x00004000; - - /** - * Listen for OEM hook raw event - * - * @see #onOemHookRawEvent - * @hide - * @deprecated OEM needs a vendor-extension hal and their apps should use that instead - */ - @Deprecated - public static final int LISTEN_OEM_HOOK_RAW_EVENT = 0x00008000; - - /** - * Listen for carrier network changes indicated by a carrier app. - * - * @see #onCarrierNetworkRequest - * @see TelephonyManager#notifyCarrierNetworkChange(boolean) - * @hide - */ - public static final int LISTEN_CARRIER_NETWORK_CHANGE = 0x00010000; - - /** - * Listen for changes to the sim voice activation state - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED - * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN - * {@more} - * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been - * fully activated - * - * @see #onVoiceActivationStateChanged - * @hide - */ - @SystemApi - public static final int LISTEN_VOICE_ACTIVATION_STATE = 0x00020000; - - /** - * Listen for changes to the sim data activation state - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED - * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN - * {@more} - * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been - * fully activated - * - * @see #onDataActivationStateChanged - * @hide - */ - public static final int LISTEN_DATA_ACTIVATION_STATE = 0x00040000; - - /** - * Listen for changes to the user mobile data state - * - * @see #onUserMobileDataStateChanged - */ - public static final int LISTEN_USER_MOBILE_DATA_STATE = 0x00080000; - - /** - * Listen for changes to the physical channel configuration. - * - * @see #onPhysicalChannelConfigurationChanged - * @hide - */ - public static final int LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 0x00100000; - - /** - * Listen for changes to the phone capability. - * - * @see #onPhoneCapabilityChanged - * @hide - */ - public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000; - - /** - * Listen for changes to active data subId. Active data subscription is - * the current subscription used to setup Cellular Internet data. For example, - * it could be the current active opportunistic subscription in use, or the - * subscription user selected as default data subscription in DSDS mode. - * - * @see #onActiveDataSubscriptionIdChanged - */ - public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000; - - /** - * Listen for changes to the radio power state. - * - * @see #onRadioPowerStateChanged - * @hide - */ - @SystemApi - public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 0x00800000; - - /** - * Listen for changes to emergency number list based on all active subscriptions. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling - * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see #onEmergencyNumberListChanged - */ - public static final int LISTEN_EMERGENCY_NUMBER_LIST = 0x01000000; - - /** - * Listen for call disconnect causes which contains {@link DisconnectCause} and - * {@link PreciseDisconnectCause}. - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public static final int LISTEN_CALL_DISCONNECT_CAUSES = 0x02000000; - - /** - * Listen for changes to the call attributes of a currently active call. - * {@more} - * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE - * READ_PRECISE_PHONE_STATE} - * - * @see #onCallAttributesChanged - * @hide - */ - @SystemApi - public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 0x04000000; - - /** - * Listen for IMS call disconnect causes which contains - * {@link android.telephony.ims.ImsReasonInfo} - * - * @see #onImsCallDisconnectCauseChanged(ImsReasonInfo) - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 0x08000000; - - /** - * Listen for the emergency number placed from an outgoing call. - * - * <p>Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} - * - * @see #onOutgoingEmergencyCall - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - public static final int LISTEN_OUTGOING_CALL_EMERGENCY_NUMBER = 0x10000000; - - /** - * Listen for the emergency number placed from an outgoing SMS. - * - * <p>Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} - * - * @see #onOutgoingEmergencySms - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - public static final int LISTEN_OUTGOING_SMS_EMERGENCY_NUMBER = 0x20000000; - - /* - * Subscription used to listen to the phone state changes - * @hide - */ - /** @hide */ - @UnsupportedAppUsage - protected Integer mSubId; - - /** - * @hide - */ - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - @UnsupportedAppUsage - public final IPhoneStateListener callback; - - /** - * Create a PhoneStateListener for the Phone with the default subscription. - * This class requires Looper.myLooper() not return null. - */ - public PhoneStateListener() { - this(null, Looper.myLooper()); - } - - /** - * Create a PhoneStateListener for the Phone with the default subscription - * using a particular non-null Looper. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public PhoneStateListener(Looper looper) { - this(null, looper); - } - - /** - * Create a PhoneStateListener for the Phone using the specified subscription. - * This class requires Looper.myLooper() not return null. To supply your - * own non-null Looper use PhoneStateListener(int subId, Looper looper) below. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public PhoneStateListener(Integer subId) { - this(subId, Looper.myLooper()); - if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion() - >= Build.VERSION_CODES.Q) { - throw new IllegalArgumentException("PhoneStateListener with subId: " - + subId + " is not supported, use default constructor"); - } - } - /** - * Create a PhoneStateListener for the Phone using the specified subscription - * and non-null Looper. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public PhoneStateListener(Integer subId, Looper looper) { - this(subId, new HandlerExecutor(new Handler(looper))); - if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion() - >= Build.VERSION_CODES.Q) { - throw new IllegalArgumentException("PhoneStateListener with subId: " - + subId + " is not supported, use default constructor"); - } - } - - /** - * Create a PhoneStateListener for the Phone using the specified Executor - * - * <p>Create a PhoneStateListener with a specified Executor for handling necessary callbacks. - * The Executor must not be null. - * - * @param executor a non-null Executor that will execute callbacks for the PhoneStateListener. - */ - public PhoneStateListener(@NonNull Executor executor) { - this(null, executor); - } - - private PhoneStateListener(Integer subId, Executor e) { - if (e == null) { - throw new IllegalArgumentException("PhoneStateListener Executor must be non-null"); - } - mSubId = subId; - callback = new IPhoneStateListenerStub(this, e); - } - - /** - * Callback invoked when device service state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see ServiceState#STATE_EMERGENCY_ONLY - * @see ServiceState#STATE_IN_SERVICE - * @see ServiceState#STATE_OUT_OF_SERVICE - * @see ServiceState#STATE_POWER_OFF - */ - public void onServiceStateChanged(ServiceState serviceState) { - // default implementation empty - } - - /** - * Callback invoked when network signal strength changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see ServiceState#STATE_EMERGENCY_ONLY - * @see ServiceState#STATE_IN_SERVICE - * @see ServiceState#STATE_OUT_OF_SERVICE - * @see ServiceState#STATE_POWER_OFF - * @deprecated Use {@link #onSignalStrengthsChanged(SignalStrength)} - */ - @Deprecated - public void onSignalStrengthChanged(int asu) { - // default implementation empty - } - - /** - * Callback invoked when the message-waiting indicator changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - public void onMessageWaitingIndicatorChanged(boolean mwi) { - // default implementation empty - } - - /** - * Callback invoked when the call-forwarding indicator changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - public void onCallForwardingIndicatorChanged(boolean cfi) { - // default implementation empty - } - - /** - * Callback invoked when device cell location changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - public void onCellLocationChanged(CellLocation location) { - // default implementation empty - } - - /** - * Callback invoked when device call state changes. - * <p> - * Reports the state of Telephony (mobile) calls on the device for the registered subscription. - * <p> - * Note: the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * <p> - * Note: The state returned here may differ from that returned by - * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that - * calling {@link TelephonyManager#getCallState()} from within this callback may return a - * different state than the callback reports. - * - * @param state call state - * @param phoneNumber call phone number. If application does not have - * {@link android.Manifest.permission#READ_CALL_LOG READ_CALL_LOG} permission or carrier - * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be - * passed as an argument. - */ - public void onCallStateChanged(@TelephonyManager.CallState int state, String phoneNumber) { - // default implementation empty - } - - /** - * Callback invoked when connection state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see TelephonyManager#DATA_DISCONNECTED - * @see TelephonyManager#DATA_CONNECTING - * @see TelephonyManager#DATA_CONNECTED - * @see TelephonyManager#DATA_SUSPENDED - */ - public void onDataConnectionStateChanged(int state) { - // default implementation empty - } - - /** - * same as above, but with the network type. Both called. - */ - public void onDataConnectionStateChanged(int state, int networkType) { - } - - /** - * Callback invoked when data activity state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see TelephonyManager#DATA_ACTIVITY_NONE - * @see TelephonyManager#DATA_ACTIVITY_IN - * @see TelephonyManager#DATA_ACTIVITY_OUT - * @see TelephonyManager#DATA_ACTIVITY_INOUT - * @see TelephonyManager#DATA_ACTIVITY_DORMANT - */ - public void onDataActivity(int direction) { - // default implementation empty - } - - /** - * Callback invoked when network signal strengths changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - // default implementation empty - } - - - /** - * The Over The Air Service Provisioning (OTASP) has changed on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * Requires the READ_PHONE_STATE permission. - * @param otaspMode is integer <code>OTASP_UNKNOWN=1<code> - * means the value is currently unknown and the system should wait until - * <code>OTASP_NEEDED=2<code> or <code>OTASP_NOT_NEEDED=3<code> is received before - * making the decision to perform OTASP or not. - * - * @hide - */ - @UnsupportedAppUsage - public void onOtaspChanged(int otaspMode) { - // default implementation empty - } - - /** - * Callback invoked when a observed cell info has changed or new cells have been added - * or removed on the registered subscription. - * Note, the registration subId s from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param cellInfo is the list of currently visible cells. - */ - public void onCellInfoChanged(List<CellInfo> cellInfo) { - } - - /** - * Callback invoked when precise device call state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * @param callState {@link PreciseCallState} - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public void onPreciseCallStateChanged(@NonNull PreciseCallState callState) { - // default implementation empty - } - - /** - * Callback invoked when call disconnect cause changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param disconnectCause {@link DisconnectCause}. - * @param preciseDisconnectCause {@link PreciseDisconnectCause}. - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { - // default implementation empty - } - - /** - * Callback invoked when Ims call disconnect cause changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) { - // default implementation empty - } - - /** - * Callback invoked when data connection state changes with precise information - * on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param dataConnectionState {@link PreciseDataConnectionState} - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public void onPreciseDataConnectionStateChanged( - @NonNull PreciseDataConnectionState dataConnectionState) { - // default implementation empty - } - - /** - * Callback invoked when data connection real time info changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @hide - */ - @UnsupportedAppUsage - public void onDataConnectionRealTimeInfoChanged( - DataConnectionRealTimeInfo dcRtInfo) { - // default implementation empty - } - - /** - * Callback invoked when there has been a change in the Single Radio Voice Call Continuity - * (SRVCC) state for the currently active call on the registered subscription. - * - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @hide - */ - @SystemApi - public void onSrvccStateChanged(@TelephonyManager.SrvccState int srvccState) { - - } - - /** - * Callback invoked when the SIM voice activation state has changed on the registered - * subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param state is the current SIM voice activation state - * @hide - */ - @SystemApi - public void onVoiceActivationStateChanged(@TelephonyManager.SimActivationState int state) { - } - - /** - * Callback invoked when the SIM data activation state has changed on the registered - * subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param state is the current SIM data activation state - * @hide - */ - public void onDataActivationStateChanged(@TelephonyManager.SimActivationState int state) { - } - - /** - * Callback invoked when the user mobile data state has changed on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param enabled indicates whether the current user mobile data state is enabled or disabled. - */ - public void onUserMobileDataStateChanged(boolean enabled) { - // default implementation empty - } - - /** - * Callback invoked when the current physical channel configuration has changed on the - * registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param configs List of the current {@link PhysicalChannelConfig}s - * @hide - */ - public void onPhysicalChannelConfigurationChanged( - @NonNull List<PhysicalChannelConfig> configs) { - // default implementation empty - } - - /** - * Callback invoked when the current emergency number list has changed on the registered - * subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param emergencyNumberList Map including the key as the active subscription ID - * (Note: if there is no active subscription, the key is - * {@link SubscriptionManager#getDefaultSubscriptionId}) - * and the value as the list of {@link EmergencyNumber}; - * null if this information is not available. - * @hide - */ - public void onEmergencyNumberListChanged( - @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList) { - // default implementation empty - } - - /** - * Callback invoked when an outgoing call is placed to an emergency number. - * - * @param placedEmergencyNumber the emergency number {@link EmergencyNumber} the call is placed - * to. - * @hide - */ - public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) { - // default implementation empty - } - - /** - * Callback invoked when an outgoing SMS is placed to an emergency number. - * - * @param sentEmergencyNumber the emergency number {@link EmergencyNumber} the SMS is sent to. - * @hide - */ - public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) { - // default implementation empty - } - - /** - * Callback invoked when OEM hook raw event is received on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * Requires the READ_PRIVILEGED_PHONE_STATE permission. - * @param rawData is the byte array of the OEM hook raw data. - * @hide - */ - @UnsupportedAppUsage - public void onOemHookRawEvent(byte[] rawData) { - // default implementation empty - } - - /** - * Callback invoked when phone capability changes. - * Note, this callback triggers regardless of registered subscription. - * - * Requires the READ_PRIVILEGED_PHONE_STATE permission. - * @param capability the new phone capability - * @hide - */ - public void onPhoneCapabilityChanged(PhoneCapability capability) { - // default implementation empty - } - - /** - * Callback invoked when active data subId changes. - * Note, this callback triggers regardless of registered subscription. - * - * Requires the READ_PHONE_STATE permission. - * @param subId current subscription used to setup Cellular Internet data. - * For example, it could be the current active opportunistic subscription in use, - * or the subscription user selected as default data subscription in DSDS mode. - */ - public void onActiveDataSubscriptionIdChanged(int subId) { - // default implementation empty - } - - /** - * Callback invoked when the call attributes changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * Requires the READ_PRIVILEGED_PHONE_STATE permission. - * @param callAttributes the call attributes - * @hide - */ - @SystemApi - public void onCallAttributesChanged(@NonNull CallAttributes callAttributes) { - // default implementation empty - } - - /** - * Callback invoked when modem radio power state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * Requires - * the READ_PRIVILEGED_PHONE_STATE permission. - * @param state the modem radio power state - * @hide - */ - @SystemApi - public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { - // default implementation empty - } - - /** - * Callback invoked when telephony has received notice from a carrier - * app that a network action that could result in connectivity loss - * has been requested by an app using - * {@link android.telephony.TelephonyManager#notifyCarrierNetworkChange(boolean)} - * - * Note, this callback is pinned to the registered subscription and will be invoked when - * the notifying carrier app has carrier privilege rule on the registered - * subscription. {@link android.telephony.TelephonyManager#hasCarrierPrivileges} - * - * @param active Whether the carrier network change is or shortly - * will be active. This value is true to indicate - * showing alternative UI and false to stop. - * - * @hide - */ - public void onCarrierNetworkChange(boolean active) { - // default implementation empty - } - - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - * - * Using a static class and weak reference here to avoid memory leak caused by the - * IPhoneStateListener.Stub callback retaining references to the outside PhoneStateListeners: - * even caller has been destroyed and "un-registered" the PhoneStateListener, it is still not - * eligible for GC given the references coming from: - * Native Stack --> PhoneStateListener --> Context (Activity). - * memory of caller's context will be collected after GC from service side get triggered - */ - private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub { - private WeakReference<PhoneStateListener> mPhoneStateListenerWeakRef; - private Executor mExecutor; - - IPhoneStateListenerStub(PhoneStateListener phoneStateListener, Executor executor) { - mPhoneStateListenerWeakRef = new WeakReference<PhoneStateListener>(phoneStateListener); - mExecutor = executor; - } - - public void onServiceStateChanged(ServiceState serviceState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onServiceStateChanged(serviceState))); - } - - public void onSignalStrengthChanged(int asu) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onSignalStrengthChanged(asu))); - } - - public void onMessageWaitingIndicatorChanged(boolean mwi) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onMessageWaitingIndicatorChanged(mwi))); - } - - public void onCallForwardingIndicatorChanged(boolean cfi) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallForwardingIndicatorChanged(cfi))); - } - - public void onCellLocationChanged(Bundle bundle) { - CellLocation location = CellLocation.newFromBundle(bundle); - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCellLocationChanged(location))); - } - - public void onCallStateChanged(int state, String incomingNumber) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallStateChanged(state, incomingNumber))); - } - - public void onDataConnectionStateChanged(int state, int networkType) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity(() -> mExecutor.execute( - () -> { - psl.onDataConnectionStateChanged(state, networkType); - psl.onDataConnectionStateChanged(state); - })); - } - - public void onDataActivity(int direction) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onDataActivity(direction))); - } - - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onSignalStrengthsChanged(signalStrength))); - } - - public void onOtaspChanged(int otaspMode) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onOtaspChanged(otaspMode))); - } - - public void onCellInfoChanged(List<CellInfo> cellInfo) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCellInfoChanged(cellInfo))); - } - - public void onPreciseCallStateChanged(PreciseCallState callState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onPreciseCallStateChanged(callState))); - } - - public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallDisconnectCauseChanged( - disconnectCause, preciseDisconnectCause))); - } - - public void onPreciseDataConnectionStateChanged( - PreciseDataConnectionState dataConnectionState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onPreciseDataConnectionStateChanged(dataConnectionState))); - } - - public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onDataConnectionRealTimeInfoChanged(dcRtInfo))); - } - - public void onSrvccStateChanged(int state) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onSrvccStateChanged(state))); - } - - public void onVoiceActivationStateChanged(int activationState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onVoiceActivationStateChanged(activationState))); - } - - public void onDataActivationStateChanged(int activationState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onDataActivationStateChanged(activationState))); - } - - public void onUserMobileDataStateChanged(boolean enabled) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onUserMobileDataStateChanged(enabled))); - } - - public void onOemHookRawEvent(byte[] rawData) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onOemHookRawEvent(rawData))); - } - - public void onCarrierNetworkChange(boolean active) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCarrierNetworkChange(active))); - } - - public void onPhysicalChannelConfigurationChanged(List<PhysicalChannelConfig> configs) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onPhysicalChannelConfigurationChanged(configs))); - } - - public void onEmergencyNumberListChanged(Map emergencyNumberList) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onEmergencyNumberListChanged(emergencyNumberList))); - } - - public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber))); - } - - public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onOutgoingEmergencySms(sentEmergencyNumber))); - } - - public void onPhoneCapabilityChanged(PhoneCapability capability) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onPhoneCapabilityChanged(capability))); - } - - public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onRadioPowerStateChanged(state))); - } - - public void onCallAttributesChanged(CallAttributes callAttributes) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallAttributesChanged(callAttributes))); - } - - public void onActiveDataSubIdChanged(int subId) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onActiveDataSubscriptionIdChanged(subId))); - } - - public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onImsCallDisconnectCauseChanged(disconnectCause))); - - } - } - - - private void log(String s) { - Rlog.d(LOG_TAG, s); - } -} diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java index e1763ab44fba..4273f5a4a16e 100644 --- a/telephony/java/android/telephony/PhysicalChannelConfig.java +++ b/telephony/java/android/telephony/PhysicalChannelConfig.java @@ -19,8 +19,8 @@ package android.telephony; import android.annotation.IntDef; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.TelephonyManager.NetworkType; +import android.telephony.Annotation.NetworkType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java index 701a375a3039..9f75332c4a03 100644 --- a/telephony/java/android/telephony/PreciseCallState.java +++ b/telephony/java/android/telephony/PreciseCallState.java @@ -23,6 +23,7 @@ import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.PreciseCallStates; import android.telephony.DisconnectCause; import android.telephony.PreciseDisconnectCause; @@ -41,29 +42,13 @@ import java.util.Objects; * <li>Precise background call state. * </ul> * - * @see android.telephony.TelephonyManager.CallState which contains generic call states. + * @see android.telephony.Annotation.CallState which contains generic call states. * * @hide */ @SystemApi public final class PreciseCallState implements Parcelable { - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"PRECISE_CALL_STATE_"}, - value = { - PRECISE_CALL_STATE_NOT_VALID, - PRECISE_CALL_STATE_IDLE, - PRECISE_CALL_STATE_ACTIVE, - PRECISE_CALL_STATE_HOLDING, - PRECISE_CALL_STATE_DIALING, - PRECISE_CALL_STATE_ALERTING, - PRECISE_CALL_STATE_INCOMING, - PRECISE_CALL_STATE_WAITING, - PRECISE_CALL_STATE_DISCONNECTED, - PRECISE_CALL_STATE_DISCONNECTING}) - public @interface State {} - /** Call state is not valid (Not received a call state). */ public static final int PRECISE_CALL_STATE_NOT_VALID = -1; /** Call state: No activity. */ @@ -85,9 +70,9 @@ public final class PreciseCallState implements Parcelable { /** Call state: Disconnecting. */ public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; - private @State int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID; - private @State int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID; - private @State int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID; + private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID; + private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID; + private @PreciseCallStates int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID; private int mDisconnectCause = DisconnectCause.NOT_VALID; private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID; @@ -97,8 +82,9 @@ public final class PreciseCallState implements Parcelable { * @hide */ @UnsupportedAppUsage - public PreciseCallState(@State int ringingCall, @State int foregroundCall, - @State int backgroundCall, int disconnectCause, + public PreciseCallState(@PreciseCallStates int ringingCall, + @PreciseCallStates int foregroundCall, + @PreciseCallStates int backgroundCall, int disconnectCause, int preciseDisconnectCause) { mRingingCallState = ringingCall; mForegroundCallState = foregroundCall; @@ -131,21 +117,21 @@ public final class PreciseCallState implements Parcelable { /** * Returns the precise ringing call state. */ - public @State int getRingingCallState() { + public @PreciseCallStates int getRingingCallState() { return mRingingCallState; } /** * Returns the precise foreground call state. */ - public @State int getForegroundCallState() { + public @PreciseCallStates int getForegroundCallState() { return mForegroundCallState; } /** * Returns the precise background call state. */ - public @State int getBackgroundCallState() { + public @PreciseCallStates int getBackgroundCallState() { return mBackgroundCallState; } diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index 90d443a6d8ee..257d634f1577 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -23,6 +23,10 @@ import android.annotation.UnsupportedAppUsage; import android.net.LinkProperties; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.DataFailureCause; +import android.telephony.Annotation.DataState; +import android.telephony.Annotation.NetworkType; import android.telephony.data.ApnSetting; import java.util.Objects; @@ -47,10 +51,10 @@ import java.util.Objects; @SystemApi public final class PreciseDataConnectionState implements Parcelable { - private @TelephonyManager.DataState int mState = TelephonyManager.DATA_UNKNOWN; - private @TelephonyManager.NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; - private @DataFailCause.FailCause int mFailCause = DataFailCause.NONE; - private @ApnSetting.ApnType int mAPNTypes = ApnSetting.TYPE_NONE; + private @DataState int mState = TelephonyManager.DATA_UNKNOWN; + private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + private @DataFailureCause int mFailCause = DataFailCause.NONE; + private @ApnType int mAPNTypes = ApnSetting.TYPE_NONE; private String mAPN = ""; private LinkProperties mLinkProperties = null; @@ -60,11 +64,11 @@ public final class PreciseDataConnectionState implements Parcelable { * @hide */ @UnsupportedAppUsage - public PreciseDataConnectionState(@TelephonyManager.DataState int state, - @TelephonyManager.NetworkType int networkType, - @ApnSetting.ApnType int apnTypes, String apn, + public PreciseDataConnectionState(@DataState int state, + @NetworkType int networkType, + @ApnType int apnTypes, String apn, LinkProperties linkProperties, - @DataFailCause.FailCause int failCause) { + @DataFailureCause int failCause) { mState = state; mNetworkType = networkType; mAPNTypes = apnTypes; @@ -99,7 +103,7 @@ public final class PreciseDataConnectionState implements Parcelable { * Returns the state of data connection that supported the apn types returned by * {@link #getDataConnectionApnTypeBitMask()} */ - public @TelephonyManager.DataState int getDataConnectionState() { + public @DataState int getDataConnectionState() { return mState; } @@ -107,7 +111,7 @@ public final class PreciseDataConnectionState implements Parcelable { * Returns the network type associated with this data connection. * @hide */ - public @TelephonyManager.NetworkType int getDataConnectionNetworkType() { + public @NetworkType int getDataConnectionNetworkType() { return mNetworkType; } @@ -115,7 +119,7 @@ public final class PreciseDataConnectionState implements Parcelable { * Returns the data connection APN types supported by this connection and triggers * {@link PreciseDataConnectionState} change. */ - public @ApnSetting.ApnType int getDataConnectionApnTypeBitMask() { + public @ApnType int getDataConnectionApnTypeBitMask() { return mAPNTypes; } @@ -139,7 +143,7 @@ public final class PreciseDataConnectionState implements Parcelable { /** * Returns data connection fail cause, in case there was a failure. */ - public @DataFailCause.FailCause int getDataConnectionFailCause() { + public @Annotation.DataFailureCause int getDataConnectionFailCause() { return mFailCause; } diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 811db06d5e37..91c917ceae45 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -29,6 +29,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.AccessNetworkConstants.TransportType; +import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.RilRadioTechnology; import android.telephony.NetworkRegistrationInfo.Domain; import android.telephony.NetworkRegistrationInfo.NRState; import android.text.TextUtils; @@ -100,7 +102,7 @@ public class ServiceState implements Parcelable { * Indicates frequency range is unknown. * @hide */ - public static final int FREQUENCY_RANGE_UNKNOWN = -1; + public static final int FREQUENCY_RANGE_UNKNOWN = 0; /** * Indicates the frequency range is below 1GHz. @@ -154,32 +156,6 @@ public class ServiceState implements Parcelable { */ public static final int DUPLEX_MODE_TDD = 2; - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "RIL_RADIO_TECHNOLOGY_" }, - value = { - RIL_RADIO_TECHNOLOGY_UNKNOWN, - RIL_RADIO_TECHNOLOGY_GPRS, - RIL_RADIO_TECHNOLOGY_EDGE, - RIL_RADIO_TECHNOLOGY_UMTS, - RIL_RADIO_TECHNOLOGY_IS95A, - RIL_RADIO_TECHNOLOGY_IS95B, - RIL_RADIO_TECHNOLOGY_1xRTT, - RIL_RADIO_TECHNOLOGY_EVDO_0, - RIL_RADIO_TECHNOLOGY_EVDO_A, - RIL_RADIO_TECHNOLOGY_HSDPA, - RIL_RADIO_TECHNOLOGY_HSUPA, - RIL_RADIO_TECHNOLOGY_HSPA, - RIL_RADIO_TECHNOLOGY_EVDO_B, - RIL_RADIO_TECHNOLOGY_EHRPD, - RIL_RADIO_TECHNOLOGY_LTE, - RIL_RADIO_TECHNOLOGY_HSPAP, - RIL_RADIO_TECHNOLOGY_GSM, - RIL_RADIO_TECHNOLOGY_TD_SCDMA, - RIL_RADIO_TECHNOLOGY_IWLAN, - RIL_RADIO_TECHNOLOGY_LTE_CA, - RIL_RADIO_TECHNOLOGY_NR}) - public @interface RilRadioTechnology {} /** * Available radio technologies for GSM, UMTS and CDMA. * Duplicates the constants from hardware/radio/include/ril.h @@ -988,7 +964,7 @@ public class ServiceState implements Parcelable { rtString = "LTE_CA"; break; case RIL_RADIO_TECHNOLOGY_NR: - rtString = "NR"; + rtString = "LTE_NR"; break; default: rtString = "Unexpected"; @@ -1623,7 +1599,7 @@ public class ServiceState implements Parcelable { * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public @TelephonyManager.NetworkType int getDataNetworkType() { + public @NetworkType int getDataNetworkType() { final NetworkRegistrationInfo iwlanRegInfo = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN); final NetworkRegistrationInfo wwanRegInfo = getNetworkRegistrationInfo( @@ -1650,7 +1626,7 @@ public class ServiceState implements Parcelable { /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public @TelephonyManager.NetworkType int getVoiceNetworkType() { + public @NetworkType int getVoiceNetworkType() { final NetworkRegistrationInfo regState = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); if (regState != null) { diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java index c078764cfa24..dc991b9a3ea7 100644 --- a/telephony/java/android/telephony/SmsCbMessage.java +++ b/telephony/java/android/telephony/SmsCbMessage.java @@ -207,17 +207,19 @@ public final class SmsCbMessage implements Parcelable { /** CMAS warning area coordinates. */ private final List<Geometry> mGeometries; + private int mSlotIndex = 0; + /** * Create a new SmsCbMessage with the specified data. */ public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber, @NonNull SmsCbLocation location, int serviceCategory, @Nullable String language, @Nullable String body, int priority, @Nullable SmsCbEtwsInfo etwsWarningInfo, - @Nullable SmsCbCmasInfo cmasWarningInfo) { + @Nullable SmsCbCmasInfo cmasWarningInfo, int slotIndex) { this(messageFormat, geographicalScope, serialNumber, location, serviceCategory, language, body, priority, etwsWarningInfo, cmasWarningInfo, 0 /* maximumWaitingTime */, - null /* geometries */, System.currentTimeMillis()); + null /* geometries */, System.currentTimeMillis(), slotIndex); } /** @@ -227,7 +229,8 @@ public final class SmsCbMessage implements Parcelable { public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber, SmsCbLocation location, int serviceCategory, String language, String body, int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo, - int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis) { + int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis, + int slotIndex) { mMessageFormat = messageFormat; mGeographicalScope = geographicalScope; mSerialNumber = serialNumber; @@ -241,6 +244,7 @@ public final class SmsCbMessage implements Parcelable { mReceivedTimeMillis = receivedTimeMillis; mGeometries = geometries; mMaximumWaitTimeSec = maximumWaitTimeSec; + mSlotIndex = slotIndex; } /** @@ -278,6 +282,7 @@ public final class SmsCbMessage implements Parcelable { String geoStr = in.readString(); mGeometries = geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null; mMaximumWaitTimeSec = in.readInt(); + mSlotIndex = in.readInt(); } /** @@ -312,6 +317,7 @@ public final class SmsCbMessage implements Parcelable { dest.writeString( mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : null); dest.writeInt(mMaximumWaitTimeSec); + dest.writeInt(mSlotIndex); } @NonNull @@ -423,6 +429,14 @@ public final class SmsCbMessage implements Parcelable { } /** + * Get the slotIndex associated with this message. + * @return the slotIndex associated with this message + */ + public int getSlotIndex() { + return mSlotIndex; + } + + /** * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}). * @return an integer representing 3GPP or 3GPP2 message format */ @@ -502,6 +516,7 @@ public final class SmsCbMessage implements Parcelable { + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "") + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + ", maximumWaitingTime = " + mMaximumWaitTimeSec + + ", slotIndex = " + mSlotIndex + ", geo=" + (mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : "null") + '}'; @@ -522,6 +537,7 @@ public final class SmsCbMessage implements Parcelable { @NonNull public ContentValues getContentValues() { ContentValues cv = new ContentValues(16); + cv.put(CellBroadcasts.SLOT_INDEX, mSlotIndex); cv.put(CellBroadcasts.GEOGRAPHICAL_SCOPE, mGeographicalScope); if (mLocation.getPlmn() != null) { cv.put(CellBroadcasts.PLMN, mLocation.getPlmn()); @@ -563,6 +579,7 @@ public final class SmsCbMessage implements Parcelable { } cv.put(CellBroadcasts.MAXIMUM_WAIT_TIME, mMaximumWaitTimeSec); + cv.put(CellBroadcasts.SLOT_INDEX, mSlotIndex); return cv; } @@ -584,6 +601,7 @@ public final class SmsCbMessage implements Parcelable { String body = cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY)); int format = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_FORMAT)); int priority = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY)); + int slotIndex = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SLOT_INDEX)); String plmn; int plmnColumn = cursor.getColumnIndex(CellBroadcasts.PLMN); @@ -681,7 +699,7 @@ public final class SmsCbMessage implements Parcelable { return new SmsCbMessage(format, geoScope, serialNum, location, category, language, body, priority, etwsInfo, cmasInfo, maximumWaitTimeSec, geometries, - receivedTimeMillis); + receivedTimeMillis, slotIndex); } /** diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 678d32ef47ce..ae6831b3fdba 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -27,14 +27,13 @@ import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.PendingIntent; -import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.database.CursorWindow; import android.net.Uri; -import android.os.BaseBundle; import android.os.Binder; +import android.os.BaseBundle; import android.os.Build; import android.os.Bundle; import android.os.RemoteException; @@ -45,7 +44,6 @@ import android.util.ArrayMap; import android.util.Log; import com.android.internal.telephony.IIntegerConsumer; -import com.android.internal.telephony.IMms; import com.android.internal.telephony.ISms; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.SmsRawData; @@ -358,6 +356,68 @@ public final class SmsManager { true /* persistMessage*/, ActivityThread.currentPackageName()); } + /** + * Send a text based SMS with messaging options. + * + * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this + * manager on a multi-SIM device, this operation may fail sending the SMS message because no + * suitable default subscription could be found. In this case, if {@code sentIntent} is + * non-null, then the {@link PendingIntent} will be sent with an error code + * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the + * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions + * where this operation may fail. + * </p> + * + * @param destinationAddress the address to send the message to + * @param scAddress is the service center address or null to use + * the current default SMSC + * @param text the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is successfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK</code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + * @param priority Priority level of the message + * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 + * --------------------------------- + * PRIORITY | Level of Priority + * --------------------------------- + * '00' | Normal + * '01' | Interactive + * '10' | Urgent + * '11' | Emergency + * ---------------------------------- + * Any Other values included Negative considered as Invalid Priority Indicator of the message. + * @param expectMore is a boolean to indicate the sending messages through same link or not. + * @param validityPeriod Validity Period of the message in mins. + * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. + * Validity Period(Minimum) -> 5 mins + * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). + * Any Other values included Negative considered as Invalid Validity Period of the message. + * + * @throws IllegalArgumentException if destinationAddress or text are empty + * {@hide} + */ + @UnsupportedAppUsage + public void sendTextMessage( + String destinationAddress, String scAddress, String text, + PendingIntent sentIntent, PendingIntent deliveryIntent, + int priority, boolean expectMore, int validityPeriod) { + sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, + true /* persistMessage*/, priority, expectMore, validityPeriod); + } + private void sendTextMessageInternal(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, String packageName) { @@ -456,110 +516,6 @@ public final class SmsManager { false /* persistMessage */, ActivityThread.currentPackageName()); } - /** - * A variant of {@link SmsManager#sendTextMessage} that allows self to be the caller. This is - * for internal use only. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the SMS being sent on the subscription associated with logical - * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the - * correct subscription. - * </p> - * - * @param persistMessage whether to persist the sent message in the SMS app. the caller must be - * the Phone process if set to false. - * - * @hide - */ - public void sendTextMessageWithSelfPermissions( - String destinationAddress, String scAddress, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage) { - android.util.SeempLog.record_str(75, destinationAddress); - if (TextUtils.isEmpty(destinationAddress)) { - throw new IllegalArgumentException("Invalid destinationAddress"); - } - - if (TextUtils.isEmpty(text)) { - throw new IllegalArgumentException("Invalid message body"); - } - - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendTextForSubscriberWithSelfPermissions(getSubscriptionId(), - ActivityThread.currentPackageName(), - destinationAddress, - scAddress, text, sentIntent, deliveryIntent, persistMessage); - } catch (RemoteException ex) { - notifySmsGenericError(sentIntent); - } - } - - /** - * Send a text based SMS with messaging options. - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param text the body of the message to send - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * @param priority Priority level of the message - * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 - * --------------------------------- - * PRIORITY | Level of Priority - * --------------------------------- - * '00' | Normal - * '01' | Interactive - * '10' | Urgent - * '11' | Emergency - * ---------------------------------- - * Any Other values included Negative considered as Invalid Priority Indicator of the message. - * @param expectMore is a boolean to indicate the sending messages through same link or not. - * @param validityPeriod Validity Period of the message in mins. - * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. - * Validity Period(Minimum) -> 5 mins - * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). - * Any Other values included Negative considered as Invalid Validity Period of the message. - * - * @throws IllegalArgumentException if destinationAddress or text are empty - * {@hide} - */ - @UnsupportedAppUsage - public void sendTextMessage( - String destinationAddress, String scAddress, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent, - int priority, boolean expectMore, int validityPeriod) { - sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, - true /* persistMessage*/, priority, expectMore, validityPeriod); - } - private void sendTextMessageInternal( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, @@ -1080,37 +1036,6 @@ public final class SmsManager { } /** - * Send a multi-part text based SMS without writing it into the SMS Provider. - * - * <p>Requires Permission: - * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier - * privileges. - * </p> - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use the Telephony - * framework and will never trigger an SMS disambiguation dialog. If this method is called on a - * device that has multiple active subscriptions, this {@link SmsManager} instance has been - * created with {@link #getDefault()}, and no user-defined default subscription is defined, the - * subscription ID associated with this message will be INVALID, which will result in the SMS - * being sent on the subscription associated with logical slot 0. Use - * {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the correct - * subscription. - * </p> - * - * @see #sendMultipartTextMessage(String, String, ArrayList, ArrayList, - * ArrayList, int, boolean, int) - * @hide - **/ - public void sendMultipartTextMessageWithoutPersisting( - String destinationAddress, String scAddress, List<String> parts, - List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, - int priority, boolean expectMore, int validityPeriod) { - sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, false /* persistMessage*/, priority, expectMore, - validityPeriod); - } - - /** * Send a data based SMS to a specific application port. * * <p class="note"><strong>Note:</strong> Using this method requires that your app has the @@ -1183,46 +1108,6 @@ public final class SmsManager { } /** - * A variant of {@link SmsManager#sendDataMessage} that allows self to be the caller. This is - * for internal use only. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the SMS being sent on the subscription associated with logical - * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the - * correct subscription. - * </p> - * - * @hide - */ - public void sendDataMessageWithSelfPermissions( - String destinationAddress, String scAddress, short destinationPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { - android.util.SeempLog.record_str(73, destinationAddress); - if (TextUtils.isEmpty(destinationAddress)) { - throw new IllegalArgumentException("Invalid destinationAddress"); - } - - if (data == null || data.length == 0) { - throw new IllegalArgumentException("Invalid message data"); - } - - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendDataForSubscriberWithSelfPermissions(getSubscriptionId(), - ActivityThread.currentPackageName(), destinationAddress, scAddress, - destinationPort & 0xFFFF, data, sentIntent, deliveryIntent); - } catch (RemoteException e) { - Log.e(TAG, "sendDataMessageWithSelfPermissions: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntent); - } - } - - /** * Get the SmsManager associated with the default subscription id. The instance will always be * associated with the default subscription id, even if the default subscription id changes. * @@ -1657,100 +1542,6 @@ public final class SmsManager { /** * Enable reception of cell broadcast (SMS-CB) messages with the given - * message identifier and RAN type. The RAN type specify this message ID - * belong to 3GPP (GSM) or 3GPP2(CDMA).Note that if two different clients - * enable the same message identifier, they must both disable it for the device to stop - * receiving those messages. All received messages will be broadcast in an - * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED". - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. - * </p> - * - * @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) - * or C.R1001-G (3GPP2) - * @param ranType the message format as defined in {@link SmsCbMessage] - * @return true if successful, false otherwise - * @see #disableCellBroadcast(int, int) - * - * {@hide} - */ - public boolean enableCellBroadcast(int messageIdentifier, - @android.telephony.SmsCbMessage.MessageFormat int ranType) { - boolean success = false; - - try { - ISms iSms = getISmsService(); - if (iSms != null) { - // If getSubscriptionId() returns INVALID or an inactive subscription, we will use - // the default phone internally. - success = iSms.enableCellBroadcastForSubscriber(getSubscriptionId(), - messageIdentifier, ranType); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Disable reception of cell broadcast (SMS-CB) messages with the given - * message identifier and RAN type. The RAN type specify this message ID - * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients - * enable the same message identifier, they must both disable it for the - * device to stop receiving those messages. - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. - * </p> - * - * @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) - * or C.R1001-G (3GPP2) - * @param ranType the message format as defined in {@link SmsCbMessage} - * @return true if successful, false otherwise - * - * @see #enableCellBroadcast(int, int) - * - * {@hide} - */ - public boolean disableCellBroadcast(int messageIdentifier, - @android.telephony.SmsCbMessage.MessageFormat int ranType) { - boolean success = false; - - try { - ISms iSms = getISmsService(); - if (iSms != null) { - // If getSubscriptionId() returns INVALID or an inactive subscription, we will use - // the default phone internally. - success = iSms.disableCellBroadcastForSubscriber(getSubscriptionId(), - messageIdentifier, ranType); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Enable reception of cell broadcast (SMS-CB) messages with the given * message identifier range and RAN type. The RAN type specifies if this message ID * belongs to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable * the same message identifier, they must both disable it for the device to stop @@ -2047,6 +1838,36 @@ public final class SmsManager { // SMS send failure result codes + /** @hide */ + @IntDef(prefix = { "RESULT" }, value = { + RESULT_ERROR_NONE, + RESULT_ERROR_GENERIC_FAILURE, + RESULT_ERROR_RADIO_OFF, + RESULT_ERROR_NULL_PDU, + RESULT_ERROR_NO_SERVICE, + RESULT_ERROR_LIMIT_EXCEEDED, + RESULT_ERROR_FDN_CHECK_FAILURE, + RESULT_ERROR_SHORT_CODE_NOT_ALLOWED, + RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED, + RESULT_RADIO_NOT_AVAILABLE, + RESULT_NETWORK_REJECT, + RESULT_INVALID_ARGUMENTS, + RESULT_INVALID_STATE, + RESULT_NO_MEMORY, + RESULT_INVALID_SMS_FORMAT, + RESULT_SYSTEM_ERROR, + RESULT_MODEM_ERROR, + RESULT_NETWORK_ERROR, + RESULT_INVALID_SMSC_ADDRESS, + RESULT_OPERATION_NOT_ALLOWED, + RESULT_INTERNAL_ERROR, + RESULT_NO_RESOURCES, + RESULT_CANCELLED, + RESULT_REQUEST_NOT_SUPPORTED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Result {} + /** * No error. * @hide @@ -2170,9 +1991,6 @@ public final class SmsManager { @SystemApi static public final int RESULT_REQUEST_NOT_SUPPORTED = 24; - - static private final String PHONE_PACKAGE_NAME = "com.android.phone"; - /** * Send an MMS message * @@ -2199,17 +2017,8 @@ public final class SmsManager { if (contentUri == null) { throw new IllegalArgumentException("Uri contentUri null"); } - try { - final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms == null) { - return; - } - - iMms.sendMessage(getSubscriptionId(), ActivityThread.currentPackageName(), contentUri, + MmsManager.getInstance().sendMultimediaMessage(getSubscriptionId(), contentUri, locationUrl, configOverrides, sentIntent); - } catch (RemoteException e) { - // Ignore it - } } /** @@ -2242,16 +2051,8 @@ public final class SmsManager { if (contentUri == null) { throw new IllegalArgumentException("Uri contentUri null"); } - try { - final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms == null) { - return; - } - iMms.downloadMessage(getSubscriptionId(), ActivityThread.currentPackageName(), - locationUrl, contentUri, configOverrides, downloadedIntent); - } catch (RemoteException e) { - // Ignore it - } + MmsManager.getInstance().downloadMultimediaMessage(getSubscriptionId(), locationUrl, + contentUri, configOverrides, downloadedIntent); } // MMS send/download failure result codes @@ -2269,434 +2070,17 @@ public final class SmsManager { /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */ public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS"; - /** - * Import a text message into system's SMS store - * - * Only default SMS apps can import SMS - * - * @param address the destination(source) address of the sent(received) message - * @param type the type of the message - * @param text the message text - * @param timestampMillis the message timestamp in milliseconds - * @param seen if the message is seen - * @param read if the message is read - * @return the message URI, null if failed - * @hide - */ - public Uri importTextMessage(String address, int type, String text, long timestampMillis, - boolean seen, boolean read) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.importTextMessage(ActivityThread.currentPackageName(), - address, type, text, timestampMillis, seen, read); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - /** Represents the received SMS message for importing {@hide} */ public static final int SMS_TYPE_INCOMING = 0; /** Represents the sent SMS message for importing {@hide} */ public static final int SMS_TYPE_OUTGOING = 1; - /** - * Import a multimedia message into system's MMS store. Only the following PDU type is - * supported: Retrieve.conf, Send.req, Notification.ind, Delivery.ind, Read-Orig.ind - * - * Only default SMS apps can import MMS - * - * @param contentUri the content uri from which to read the PDU of the message to import - * @param messageId the optional message id. Use null if not specifying - * @param timestampSecs the optional message timestamp. Use -1 if not specifying - * @param seen if the message is seen - * @param read if the message is read - * @return the message URI, null if failed - * @throws IllegalArgumentException if pdu is empty - * {@hide} - */ - public Uri importMultimediaMessage(Uri contentUri, String messageId, long timestampSecs, - boolean seen, boolean read) { - if (contentUri == null) { - throw new IllegalArgumentException("Uri contentUri null"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.importMultimediaMessage(ActivityThread.currentPackageName(), - contentUri, messageId, timestampSecs, seen, read); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Delete a system stored SMS or MMS message - * - * Only default SMS apps can delete system stored SMS and MMS messages - * - * @param messageUri the URI of the stored message - * @return true if deletion is successful, false otherwise - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public boolean deleteStoredMessage(Uri messageUri) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.deleteStoredMessage(ActivityThread.currentPackageName(), messageUri); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Delete a system stored SMS or MMS thread - * - * Only default SMS apps can delete system stored SMS and MMS conversations - * - * @param conversationId the ID of the message conversation - * @return true if deletion is successful, false otherwise - * {@hide} - */ - public boolean deleteStoredConversation(long conversationId) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.deleteStoredConversation( - ActivityThread.currentPackageName(), conversationId); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Update the status properties of a system stored SMS or MMS message, e.g. - * the read status of a message, etc. - * - * @param messageUri the URI of the stored message - * @param statusValues a list of status properties in key-value pairs to update - * @return true if update is successful, false otherwise - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public boolean updateStoredMessageStatus(Uri messageUri, ContentValues statusValues) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.updateStoredMessageStatus(ActivityThread.currentPackageName(), - messageUri, statusValues); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - /** Message status property: whether the message has been seen. 1 means seen, 0 not {@hide} */ public static final String MESSAGE_STATUS_SEEN = "seen"; /** Message status property: whether the message has been read. 1 means read, 0 not {@hide} */ public static final String MESSAGE_STATUS_READ = "read"; /** - * Archive or unarchive a stored conversation - * - * @param conversationId the ID of the message conversation - * @param archived true to archive the conversation, false to unarchive - * @return true if update is successful, false otherwise - * {@hide} - */ - public boolean archiveStoredConversation(long conversationId, boolean archived) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.archiveStoredConversation(ActivityThread.currentPackageName(), - conversationId, archived); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Add a text message draft to system SMS store - * - * Only default SMS apps can add SMS draft - * - * @param address the destination address of message - * @param text the body of the message to send - * @return the URI of the stored draft message - * {@hide} - */ - public Uri addTextMessageDraft(String address, String text) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.addTextMessageDraft(ActivityThread.currentPackageName(), address, text); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Add a multimedia message draft to system MMS store - * - * Only default SMS apps can add MMS draft - * - * @param contentUri the content uri from which to read the PDU data of the draft MMS - * @return the URI of the stored draft message - * @throws IllegalArgumentException if pdu is empty - * {@hide} - */ - public Uri addMultimediaMessageDraft(Uri contentUri) { - if (contentUri == null) { - throw new IllegalArgumentException("Uri contentUri null"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.addMultimediaMessageDraft(ActivityThread.currentPackageName(), - contentUri); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Send a system stored text message. - * - * You can only send a failed text message or a draft text message. - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param messageUri the URI of the stored message - * @param scAddress is the service center address or null to use the current default SMSC - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredTextMessage(Uri messageUri, String scAddress, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - final Context context = ActivityThread.currentApplication().getApplicationContext(); - resolveSubscriptionForOperation(new SubscriptionResolverResult() { - @Override - public void onSuccess(int subId) { - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendStoredText(subId, ActivityThread.currentPackageName(), messageUri, - scAddress, sentIntent, deliveryIntent); - } catch (RemoteException e) { - Log.e(TAG, "sendStoredTextMessage: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntent); - } - } - @Override - public void onFailure() { - notifySmsErrorNoDefaultSet(context, sentIntent); - } - }); - } - - /** - * Send a system stored multi-part text message. - * - * You can only send a failed text message or a draft text message. - * The provided <code>PendingIntent</code> lists should match the part number of the - * divided text of the stored message by using <code>divideMessage</code> - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param messageUri the URI of the stored message - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param sentIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been delivered - * to the recipient. The raw pdu of the status report is in the - * extended data ("pdu"). - * - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredMultipartTextMessage(Uri messageUri, String scAddress, - ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - final Context context = ActivityThread.currentApplication().getApplicationContext(); - resolveSubscriptionForOperation(new SubscriptionResolverResult() { - @Override - public void onSuccess(int subId) { - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendStoredMultipartText(subId, ActivityThread.currentPackageName(), - messageUri, scAddress, sentIntents, deliveryIntents); - } catch (RemoteException e) { - Log.e(TAG, "sendStoredTextMessage: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntents); - } - } - @Override - public void onFailure() { - notifySmsErrorNoDefaultSet(context, sentIntents); - } - }); - } - - /** - * Send a system stored MMS message - * - * This is used for sending a previously sent, but failed-to-send, message or - * for sending a text message that has been stored as a draft. - * - * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. - * </p> - * - * @param messageUri the URI of the stored message - * @param configOverrides the carrier-specific messaging configuration values to override for - * sending the message. - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredMultimediaMessage(Uri messageUri, Bundle configOverrides, - PendingIntent sentIntent) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - iMms.sendStoredMessage( - getSubscriptionId(), ActivityThread.currentPackageName(), messageUri, - configOverrides, sentIntent); - } - } catch (RemoteException ex) { - // ignore it - } - } - - /** - * Turns on/off the flag to automatically write sent/received SMS/MMS messages into system - * - * When this flag is on, all SMS/MMS sent/received are stored by system automatically - * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system - * automatically - * - * This flag can only be changed by default SMS apps - * - * @param enabled Whether to enable message auto persisting - * {@hide} - */ - public void setAutoPersisting(boolean enabled) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - iMms.setAutoPersisting(ActivityThread.currentPackageName(), enabled); - } - } catch (RemoteException ex) { - // ignore it - } - } - - /** - * Get the value of the flag to automatically write sent/received SMS/MMS messages into system - * - * When this flag is on, all SMS/MMS sent/received are stored by system automatically - * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system - * automatically - * - * @return the current value of the auto persist flag - * {@hide} - */ - public boolean getAutoPersisting() { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.getAutoPersisting(); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** * Get carrier-dependent configuration values. * * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier @@ -2712,15 +2096,7 @@ public final class SmsManager { * @return bundle key/values pairs of configuration values */ public Bundle getCarrierConfigValues() { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.getCarrierConfigValues(getSubscriptionId()); - } - } catch (RemoteException ex) { - // ignore it - } - return null; + return MmsManager.getInstance().getCarrierConfigValues(getSubscriptionId()); } /** @@ -2759,7 +2135,9 @@ public final class SmsManager { } } - /** callback for providing asynchronous sms messages for financial app. */ + /** + * callback for providing asynchronous sms messages for financial app. + */ public abstract static class FinancialSmsCallback { /** * Callback to send sms messages back to financial app asynchronously. @@ -2785,59 +2163,49 @@ public final class SmsManager { * @param params the parameters to filter SMS messages returned. * @param executor the executor on which callback will be invoked. * @param callback a callback to receive CursorWindow with SMS messages. + * */ @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS) public void getSmsMessagesForFinancialApp( Bundle params, @NonNull @CallbackExecutor Executor executor, @NonNull FinancialSmsCallback callback) { - try { - ISms iccSms = getISmsServiceOrThrow(); - iccSms.getSmsMessagesForFinancialApp( - getSubscriptionId(), ActivityThread.currentPackageName(), params, - new IFinancialSmsCallback.Stub() { - public void onGetSmsMessagesForFinancialApp(CursorWindow msgs) { - Binder.withCleanCallingIdentity(() -> executor.execute( - () -> callback.onFinancialSmsMessages(msgs))); - }}); - } catch (RemoteException ex) { - ex.rethrowFromSystemServer(); - } + // This API is not functional and thus removed to avoid future confusion. } /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The prefixes is a list of prefix {@code String} separated by this delimiter. * @hide */ public static final String REGEX_PREFIX_DELIMITER = ","; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The success status to be added into the intent to be sent to the calling package. * @hide */ public static final int RESULT_STATUS_SUCCESS = 0; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The timeout status to be added into the intent to be sent to the calling package. * @hide */ public static final int RESULT_STATUS_TIMEOUT = 1; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * Intent extra key of the retrieved SMS message as a {@code String}. * @hide */ public static final String EXTRA_SMS_MESSAGE = "android.telephony.extra.SMS_MESSAGE"; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * Intent extra key of SMS retriever status, which indicates whether the request for the * coming SMS message is SUCCESS or TIMEOUT * @hide */ public static final String EXTRA_STATUS = "android.telephony.extra.STATUS"; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * [Optional] Intent extra key of the retrieved Sim card subscription Id if any. {@code int} * @hide */ @@ -2887,74 +2255,6 @@ public final class SmsManager { } } - /** - * Filters a bundle to only contain MMS config variables. - * - * This is for use with bundles returned by {@link CarrierConfigManager} which contain MMS - * config and unrelated config. It is assumed that all MMS_CONFIG_* keys are present in the - * supplied bundle. - * - * @param config a Bundle that contains MMS config variables and possibly more. - * @return a new Bundle that only contains the MMS_CONFIG_* keys defined above. - * @hide - */ - public static Bundle getMmsConfig(BaseBundle config) { - Bundle filtered = new Bundle(); - filtered.putBoolean(MMS_CONFIG_APPEND_TRANSACTION_ID, - config.getBoolean(MMS_CONFIG_APPEND_TRANSACTION_ID)); - filtered.putBoolean(MMS_CONFIG_MMS_ENABLED, config.getBoolean(MMS_CONFIG_MMS_ENABLED)); - filtered.putBoolean(MMS_CONFIG_GROUP_MMS_ENABLED, - config.getBoolean(MMS_CONFIG_GROUP_MMS_ENABLED)); - filtered.putBoolean(MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED, - config.getBoolean(MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED)); - filtered.putBoolean(MMS_CONFIG_ALIAS_ENABLED, config.getBoolean(MMS_CONFIG_ALIAS_ENABLED)); - filtered.putBoolean(MMS_CONFIG_ALLOW_ATTACH_AUDIO, - config.getBoolean(MMS_CONFIG_ALLOW_ATTACH_AUDIO)); - filtered.putBoolean(MMS_CONFIG_MULTIPART_SMS_ENABLED, - config.getBoolean(MMS_CONFIG_MULTIPART_SMS_ENABLED)); - filtered.putBoolean(MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED, - config.getBoolean(MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED)); - filtered.putBoolean(MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION, - config.getBoolean(MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION)); - filtered.putBoolean(MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES, - config.getBoolean(MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES)); - filtered.putBoolean(MMS_CONFIG_MMS_READ_REPORT_ENABLED, - config.getBoolean(MMS_CONFIG_MMS_READ_REPORT_ENABLED)); - filtered.putBoolean(MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED, - config.getBoolean(MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED)); - filtered.putBoolean(MMS_CONFIG_CLOSE_CONNECTION, - config.getBoolean(MMS_CONFIG_CLOSE_CONNECTION)); - filtered.putInt(MMS_CONFIG_MAX_MESSAGE_SIZE, config.getInt(MMS_CONFIG_MAX_MESSAGE_SIZE)); - filtered.putInt(MMS_CONFIG_MAX_IMAGE_WIDTH, config.getInt(MMS_CONFIG_MAX_IMAGE_WIDTH)); - filtered.putInt(MMS_CONFIG_MAX_IMAGE_HEIGHT, config.getInt(MMS_CONFIG_MAX_IMAGE_HEIGHT)); - filtered.putInt(MMS_CONFIG_RECIPIENT_LIMIT, config.getInt(MMS_CONFIG_RECIPIENT_LIMIT)); - filtered.putInt(MMS_CONFIG_ALIAS_MIN_CHARS, config.getInt(MMS_CONFIG_ALIAS_MIN_CHARS)); - filtered.putInt(MMS_CONFIG_ALIAS_MAX_CHARS, config.getInt(MMS_CONFIG_ALIAS_MAX_CHARS)); - filtered.putInt(MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD, - config.getInt(MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD)); - filtered.putInt(MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD, - config.getInt(MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD)); - filtered.putInt(MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE, - config.getInt(MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE)); - filtered.putInt(MMS_CONFIG_SUBJECT_MAX_LENGTH, - config.getInt(MMS_CONFIG_SUBJECT_MAX_LENGTH)); - filtered.putInt(MMS_CONFIG_HTTP_SOCKET_TIMEOUT, - config.getInt(MMS_CONFIG_HTTP_SOCKET_TIMEOUT)); - filtered.putString(MMS_CONFIG_UA_PROF_TAG_NAME, - config.getString(MMS_CONFIG_UA_PROF_TAG_NAME)); - filtered.putString(MMS_CONFIG_USER_AGENT, config.getString(MMS_CONFIG_USER_AGENT)); - filtered.putString(MMS_CONFIG_UA_PROF_URL, config.getString(MMS_CONFIG_UA_PROF_URL)); - filtered.putString(MMS_CONFIG_HTTP_PARAMS, config.getString(MMS_CONFIG_HTTP_PARAMS)); - filtered.putString(MMS_CONFIG_EMAIL_GATEWAY_NUMBER, - config.getString(MMS_CONFIG_EMAIL_GATEWAY_NUMBER)); - filtered.putString(MMS_CONFIG_NAI_SUFFIX, config.getString(MMS_CONFIG_NAI_SUFFIX)); - filtered.putBoolean(MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS, - config.getBoolean(MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS)); - filtered.putBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER, - config.getBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER)); - return filtered; - } - /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SMS_CATEGORY_"}, diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 51de903ed37e..8425ec13b282 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -47,22 +47,20 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; -import android.telephony.TelephonyManager.NetworkType; import android.telephony.euicc.EuiccManager; import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; import android.util.Log; -import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ISetOpportunisticDataCallback; import com.android.internal.telephony.ISub; -import com.android.internal.telephony.ITelephonyRegistry; import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.Preconditions; @@ -896,6 +894,11 @@ public class SubscriptionManager { */ public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX"; + /** + * Integer extra to specify SIM slot index. + */ + public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX"; + private final Context mContext; private volatile INetworkPolicyManager mNetworkPolicy; @@ -919,20 +922,24 @@ public class SubscriptionManager { OnSubscriptionsChangedListenerHandler(Looper looper) { super(looper); } - - @Override - public void handleMessage(Message msg) { - if (DBG) { - log("handleMessage: invoke the overriden onSubscriptionsChanged()"); - } - OnSubscriptionsChangedListener.this.onSubscriptionsChanged(); - } } - private final Handler mHandler; + /** + * Posted executor callback on the handler associated with a given looper. + * The looper can be the calling thread's looper or the looper passed from the + * constructor {@link #OnSubscriptionsChangedListener(Looper)}. + */ + private final HandlerExecutor mExecutor; + + /** + * @hide + */ + public HandlerExecutor getHandlerExecutor() { + return mExecutor; + } public OnSubscriptionsChangedListener() { - mHandler = new OnSubscriptionsChangedListenerHandler(); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler()); } /** @@ -941,7 +948,7 @@ public class SubscriptionManager { * @hide */ public OnSubscriptionsChangedListener(Looper looper) { - mHandler = new OnSubscriptionsChangedListenerHandler(looper); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper)); } /** @@ -953,18 +960,6 @@ public class SubscriptionManager { if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN"); } - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - */ - IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { - @Override - public void onSubscriptionsChanged() { - if (DBG) log("callback: received, sendEmptyMessage(0) to handler"); - mHandler.sendEmptyMessage(0); - } - }; - private void log(String s) { Rlog.d(LOG_TAG, s); } @@ -1006,21 +1001,19 @@ public class SubscriptionManager { * onSubscriptionsChanged overridden. */ public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + if (listener == null) return; String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (DBG) { logd("register OnSubscriptionsChangedListener pkgName=" + pkgName + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available. Where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.addOnSubscriptionsChangedListener(pkgName, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available. Where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.addOnSubscriptionsChangedListener(listener, + listener.mExecutor); } } @@ -1032,21 +1025,18 @@ public class SubscriptionManager { * @param listener that is to be unregistered. */ public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + if (listener == null) return; String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (DBG) { logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener); } } @@ -1065,7 +1055,6 @@ public class SubscriptionManager { * for #onOpportunisticSubscriptionsChanged to be invoked. */ public static class OnOpportunisticSubscriptionsChangedListener { - private Executor mExecutor; /** * Callback invoked when there is any change to any SubscriptionInfo. Typically * this method would invoke {@link #getActiveSubscriptionInfoList} @@ -1074,27 +1063,6 @@ public class SubscriptionManager { if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN"); } - private void setExecutor(Executor executor) { - mExecutor = executor; - } - - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - */ - IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { - @Override - public void onSubscriptionsChanged() { - final long identity = Binder.clearCallingIdentity(); - try { - if (DBG) log("onOpportunisticSubscriptionsChanged callback received."); - mExecutor.execute(() -> onOpportunisticSubscriptionsChanged()); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - }; - private void log(String s) { Rlog.d(LOG_TAG, s); } @@ -1121,18 +1089,13 @@ public class SubscriptionManager { + " listener=" + listener); } - listener.setExecutor(executor); - - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available. Where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.addOnOpportunisticSubscriptionsChangedListener(pkgName, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener( + listener, executor); } } @@ -1152,16 +1115,10 @@ public class SubscriptionManager { logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener); } } @@ -2096,13 +2053,13 @@ public class SubscriptionManager { /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static boolean isValidSlotIndex(int slotIndex) { - return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSimCount(); + return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSupportedModemCount(); } /** @hide */ @UnsupportedAppUsage public static boolean isValidPhoneId(int phoneId) { - return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount(); + return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getSupportedModemCount(); } /** @hide */ @@ -2123,6 +2080,7 @@ public class SubscriptionManager { if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId); intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId); + intent.putExtra(EXTRA_SLOT_INDEX, phoneId); intent.putExtra(PhoneConstants.PHONE_KEY, phoneId); } @@ -2414,8 +2372,12 @@ public class SubscriptionManager { * @param plans the list of plans. The first plan is always the primary and * most important plan. Any additional plans are secondary and * may not be displayed or used by decision making logic. + * The list of all plans must meet the requirements defined in + * {@link SubscriptionPlan.Builder#setNetworkTypes(int[])}. * @throws SecurityException if the caller doesn't meet the requirements * outlined above. + * @throws IllegalArgumentException if plans don't meet the requirements + * mentioned above. */ public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) { try { @@ -2460,51 +2422,10 @@ public class SubscriptionManager { */ public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @DurationMillisLong long timeoutMillis) { - setSubscriptionOverrideUnmetered(subId, null, overrideUnmetered, timeoutMillis); - } - - /** - * Temporarily override the billing relationship between a carrier and - * a specific subscriber to be considered unmetered for the given network - * types. This will be reflected to apps via - * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}. - * This method is only accessible to the following narrow set of apps: - * <ul> - * <li>The carrier app for this subscriberId, as determined by - * {@link TelephonyManager#hasCarrierPrivileges()}. - * <li>The carrier app explicitly delegated access through - * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. - * </ul> - * - * @param subId the subscriber this override applies to. - * @param networkTypes all network types to set an override for. A null - * network type means to apply the override to all network types. - * Any unspecified network types will default to metered. - * @param overrideUnmetered set if the billing relationship should be - * considered unmetered. - * @param timeoutMillis the timeout after which the requested override will - * be automatically cleared, or {@code 0} to leave in the - * requested state until explicitly cleared, or the next reboot, - * whichever happens first. - * @throws SecurityException if the caller doesn't meet the requirements - * outlined above. - * {@hide} - */ - public void setSubscriptionOverrideUnmetered(int subId, - @Nullable @NetworkType int[] networkTypes, boolean overrideUnmetered, - @DurationMillisLong long timeoutMillis) { try { - long networkTypeMask = 0; - if (networkTypes != null) { - for (int networkType : networkTypes) { - networkTypeMask |= TelephonyManager.getBitMaskForNetworkType(networkType); - } - } else { - networkTypeMask = ~0; - } final int overrideValue = overrideUnmetered ? OVERRIDE_UNMETERED : 0; getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_UNMETERED, overrideValue, - networkTypeMask, timeoutMillis, mContext.getOpPackageName()); + timeoutMillis, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2536,52 +2457,10 @@ public class SubscriptionManager { */ public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @DurationMillisLong long timeoutMillis) { - setSubscriptionOverrideCongested(subId, null, overrideCongested, timeoutMillis); - } - - /** - * Temporarily override the billing relationship plan between a carrier and - * a specific subscriber to be considered congested. This will cause the - * device to delay certain network requests when possible, such as developer - * jobs that are willing to run in a flexible time window. - * <p> - * This method is only accessible to the following narrow set of apps: - * <ul> - * <li>The carrier app for this subscriberId, as determined by - * {@link TelephonyManager#hasCarrierPrivileges()}. - * <li>The carrier app explicitly delegated access through - * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}. - * </ul> - * - * @param subId the subscriber this override applies to. - * @param networkTypes all network types to set an override for. A null - * network type means to apply the override to all network types. - * Any unspecified network types will default to not congested. - * @param overrideCongested set if the subscription should be considered - * congested. - * @param timeoutMillis the timeout after which the requested override will - * be automatically cleared, or {@code 0} to leave in the - * requested state until explicitly cleared, or the next reboot, - * whichever happens first. - * @throws SecurityException if the caller doesn't meet the requirements - * outlined above. - * @hide - */ - public void setSubscriptionOverrideCongested(int subId, - @Nullable @NetworkType int[] networkTypes, boolean overrideCongested, - @DurationMillisLong long timeoutMillis) { try { - long networkTypeMask = 0; - if (networkTypes != null) { - for (int networkType : networkTypes) { - networkTypeMask |= TelephonyManager.getBitMaskForNetworkType(networkType); - } - } else { - networkTypeMask = ~0; - } final int overrideValue = overrideCongested ? OVERRIDE_CONGESTED : 0; getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_CONGESTED, overrideValue, - networkTypeMask, timeoutMillis, mContext.getOpPackageName()); + timeoutMillis, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/telephony/java/android/telephony/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java index ec2050fb1a44..e24eb2696c6c 100644 --- a/telephony/java/android/telephony/SubscriptionPlan.java +++ b/telephony/java/android/telephony/SubscriptionPlan.java @@ -24,6 +24,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.NetworkType; import android.util.Range; import android.util.RecurrenceRule; @@ -33,6 +34,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Period; import java.time.ZonedDateTime; +import java.util.Arrays; import java.util.Iterator; import java.util.Objects; @@ -80,6 +82,8 @@ public final class SubscriptionPlan implements Parcelable { private int dataLimitBehavior = LIMIT_BEHAVIOR_UNKNOWN; private long dataUsageBytes = BYTES_UNKNOWN; private long dataUsageTime = TIME_UNKNOWN; + private @NetworkType int[] networkTypes; + private long networkTypesBitMask; private SubscriptionPlan(RecurrenceRule cycleRule) { this.cycleRule = Preconditions.checkNotNull(cycleRule); @@ -93,6 +97,7 @@ public final class SubscriptionPlan implements Parcelable { dataLimitBehavior = source.readInt(); dataUsageBytes = source.readLong(); dataUsageTime = source.readLong(); + networkTypes = source.createIntArray(); } @Override @@ -109,6 +114,7 @@ public final class SubscriptionPlan implements Parcelable { dest.writeInt(dataLimitBehavior); dest.writeLong(dataUsageBytes); dest.writeLong(dataUsageTime); + dest.writeIntArray(networkTypes); } @Override @@ -121,13 +127,14 @@ public final class SubscriptionPlan implements Parcelable { .append(" dataLimitBehavior=").append(dataLimitBehavior) .append(" dataUsageBytes=").append(dataUsageBytes) .append(" dataUsageTime=").append(dataUsageTime) + .append(" networkTypes=").append(Arrays.toString(networkTypes)) .append("}").toString(); } @Override public int hashCode() { return Objects.hash(cycleRule, title, summary, dataLimitBytes, dataLimitBehavior, - dataUsageBytes, dataUsageTime); + dataUsageBytes, dataUsageTime, Arrays.hashCode(networkTypes)); } @Override @@ -140,7 +147,8 @@ public final class SubscriptionPlan implements Parcelable { && dataLimitBytes == other.dataLimitBytes && dataLimitBehavior == other.dataLimitBehavior && dataUsageBytes == other.dataUsageBytes - && dataUsageTime == other.dataUsageTime; + && dataUsageTime == other.dataUsageTime + && Arrays.equals(networkTypes, other.networkTypes); } return false; } @@ -204,6 +212,32 @@ public final class SubscriptionPlan implements Parcelable { } /** + * Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to. + * A null array means this SubscriptionPlan applies to all network types. + */ + public @Nullable @NetworkType int[] getNetworkTypes() { + return networkTypes; + } + + /** + * Return the networkTypes array converted to a {@link TelephonyManager.NetworkTypeBitMask} + * @hide + */ + public long getNetworkTypesBitMask() { + // calculate bitmask the first time and save for future calls + if (networkTypesBitMask == 0) { + if (networkTypes == null) { + networkTypesBitMask = ~0; + } else { + for (int networkType : networkTypes) { + networkTypesBitMask |= TelephonyManager.getBitMaskForNetworkType(networkType); + } + } + } + return networkTypesBitMask; + } + + /** * Return an iterator that will return all valid data usage cycles based on * any recurrence rules. The iterator starts from the currently active cycle * and walks backwards through time. @@ -335,5 +369,24 @@ public final class SubscriptionPlan implements Parcelable { plan.dataUsageTime = dataUsageTime; return this; } + + /** + * Set the network types this SubscriptionPlan applies to. + * The developer must supply at least one plan that applies to all network types (default), + * and all additional plans may not include a particular network type more than once. + * Plan selection will prefer plans that have specific network types defined + * over plans that apply to all network types. + * + * @param networkTypes a set of all {@link NetworkType}s that apply to this plan. + * A null value or empty array means the plan applies to all network types. + */ + public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) { + if (networkTypes == null || networkTypes.length == 0) { + plan.networkTypes = null; + } else { + plan.networkTypes = networkTypes; + } + return this; + } } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index a0f0552f7a84..7549adc616c8 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -63,8 +63,12 @@ import android.telecom.InCallService; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; +import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.CallState; +import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.RadioPowerState; +import android.telephony.Annotation.SimActivationState; import android.telephony.VisualVoicemailService.VisualVoicemailTask; -import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories; import android.telephony.ims.ImsMmTelManager; @@ -254,17 +258,6 @@ public class TelephonyManager { */ public static final int UNINITIALIZED_CARD_ID = -2; - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"SRVCC_STATE_"}, - value = { - SRVCC_STATE_HANDOVER_NONE, - SRVCC_STATE_HANDOVER_STARTED, - SRVCC_STATE_HANDOVER_COMPLETED, - SRVCC_STATE_HANDOVER_FAILED, - SRVCC_STATE_HANDOVER_CANCELED}) - public @interface SrvccState {} - private final Context mContext; private final int mSubId; @UnsupportedAppUsage @@ -289,6 +282,21 @@ public class TelephonyManager { }; /** @hide */ + @IntDef(prefix = {"MODEM_COUNT_"}, + value = { + MODEM_COUNT_NO_MODEM, + MODEM_COUNT_SINGLE_MODEM, + MODEM_COUNT_DUAL_MODEM, + MODEM_COUNT_TRI_MODEM + }) + public @interface ModemCount {} + + public static final int MODEM_COUNT_NO_MODEM = 0; + public static final int MODEM_COUNT_SINGLE_MODEM = 1; + public static final int MODEM_COUNT_DUAL_MODEM = 2; + public static final int MODEM_COUNT_TRI_MODEM = 3; + + /** @hide */ @UnsupportedAppUsage public TelephonyManager(Context context) { this(context, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); @@ -365,12 +373,26 @@ public class TelephonyManager { /** * Returns the number of phones available. * Returns 0 if none of voice, sms, data is not supported - * Returns 1 for Single standby mode (Single SIM functionality) - * Returns 2 for Dual standby mode.(Dual SIM functionality) - * Returns 3 for Tri standby mode.(Tri SIM functionality) + * Returns 1 for Single standby mode (Single SIM functionality). + * Returns 2 for Dual standby mode (Dual SIM functionality). + * Returns 3 for Tri standby mode (Tri SIM functionality). + * @deprecated Use {@link #getActiveModemCount} instead. */ + @Deprecated public int getPhoneCount() { - int phoneCount = 1; + return getActiveModemCount(); + } + + /** + * Returns the number of logical modems currently configured to be activated. + * + * Returns 0 if none of voice, sms, data is not supported + * Returns 1 for Single standby mode (Single SIM functionality). + * Returns 2 for Dual standby mode (Dual SIM functionality). + * Returns 3 for Tri standby mode (Tri SIM functionality). + */ + public @ModemCount int getActiveModemCount() { + int modemCount = 1; switch (getMultiSimConfiguration()) { case UNKNOWN: ConnectivityManager cm = mContext == null ? null : (ConnectivityManager) mContext @@ -378,33 +400,30 @@ public class TelephonyManager { // check for voice and data support, 0 if not supported if (!isVoiceCapable() && !isSmsCapable() && cm != null && !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) { - phoneCount = 0; + modemCount = MODEM_COUNT_NO_MODEM; } else { - phoneCount = 1; + modemCount = MODEM_COUNT_SINGLE_MODEM; } break; case DSDS: case DSDA: - phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM; + modemCount = MODEM_COUNT_DUAL_MODEM; break; case TSTS: - phoneCount = PhoneConstants.MAX_PHONE_COUNT_TRI_SIM; + modemCount = MODEM_COUNT_TRI_MODEM; break; } - return phoneCount; + return modemCount; } /** - * - * Return how many phone / logical modem can be active simultaneously, in terms of device + * Return how many logical modem can be potentially active simultaneously, in terms of hardware * capability. - * For example, for a dual-SIM capable device, it always returns 2, even if only one logical - * modem / SIM is active (aka in single SIM mode). - * - * TODO: b/139642279 publicize and rename. - * @hide + * It might return different value from {@link #getActiveModemCount}. For example, for a + * dual-SIM capable device operating in single SIM mode (only one logical modem is turned on), + * {@link #getActiveModemCount} returns 1 while this API returns 2. */ - public static int getMaxPhoneCount() { + public @ModemCount int getSupportedModemCount() { // TODO: b/139642279 when turning on this feature, remove dependency of // PROPERTY_REBOOT_REQUIRED_ON_MODEM_CHANGE and always return result based on // PROPERTY_MAX_ACTIVE_MODEMS. @@ -413,9 +432,9 @@ public class TelephonyManager { if (rebootRequired.equals("false")) { // If no reboot is required, return max possible active modems. return SystemProperties.getInt( - TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS, getDefault().getPhoneCount()); + TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS, getPhoneCount()); } else { - return getDefault().getPhoneCount(); + return getPhoneCount(); } } @@ -1177,6 +1196,35 @@ public class TelephonyManager { "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; /** + * Broadcast intent that indicates multi-SIM configuration is changed. For example, it changed + * from single SIM capable to dual-SIM capable (DSDS or DSDA) or triple-SIM mode. + * + * It doesn't indicate how many subscriptions are actually active, or which states SIMs are, + * or that all steps during multi-SIM change are done. To know those information you still need + * to listen to SIM_STATE changes or active subscription changes. + * + * See extra of {@link #EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED} for updated value. + */ + public static final String ACTION_MULTI_SIM_CONFIG_CHANGED = + "android.telephony.action.MULTI_SIM_CONFIG_CHANGED"; + + + /** + * The number of active SIM supported by current multi-SIM config. It's not related to how many + * SIM/subscriptions are currently active. + * + * For single SIM mode, it's 1. + * For DSDS or DSDA mode, it's 2. + * For triple-SIM mode, it's 3. + * + * Extra of {@link #ACTION_MULTI_SIM_CONFIG_CHANGED}. + * + * type: integer + */ + public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = + "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED"; + + /** * @hide */ public static final String USSD_RESPONSE = "USSD_RESPONSE"; @@ -1571,12 +1619,11 @@ public class TelephonyManager { * Returns the software version number for the device, for example, * the IMEI/SV for GSM phones. Return null if the software version is * not available. - * - * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} - * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * <p> + * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}. */ - @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + @Nullable public String getDeviceSoftwareVersion() { return getDeviceSoftwareVersion(getSlotIndex()); } @@ -1585,12 +1632,16 @@ public class TelephonyManager { * Returns the software version number for the device, for example, * the IMEI/SV for GSM phones. Return null if the software version is * not available. + * <p> + * Requires Permission: READ_PRIVILEGED_PHONE_STATE. * * @param slotIndex of which deviceID is returned + * + * @hide */ - /** {@hide} */ - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - @UnsupportedAppUsage + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @Nullable public String getDeviceSoftwareVersion(int slotIndex) { ITelephony telephony = getITelephony(); if (telephony == null) return null; @@ -1873,11 +1924,23 @@ public class TelephonyManager { /** * Returns the Network Access Identifier (NAI). Return null if NAI is not available. * - * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} - * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or + * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier + * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a + * managed profile on the device; for more details see <a + * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner + * access is deprecated and will be removed in a future release. + * + * <ul> + * <li>If the calling app's target SDK is API level 28 or lower and the app has the + * READ_PHONE_STATE permission then null is returned.</li> + * <li>If the calling app's target SDK is API level 28 or lower and the app does not have + * the READ_PHONE_STATE permission, or if the calling app is targeting API level 29 or + * higher, then a SecurityException is thrown.</li> + * </ul> */ - @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236). + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getNai() { return getNaiBySubscriberId(getSubId()); } @@ -1885,6 +1948,21 @@ public class TelephonyManager { /** * Returns the NAI. Return null if NAI is not available. * + * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or + * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier + * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a + * managed profile on the device; for more details see <a + * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner + * access is deprecated and will be removed in a future release. + * + * <ul> + * <li>If the calling app's target SDK is API level 28 or lower and the app has the + * READ_PHONE_STATE permission then null is returned.</li> + * <li>If the calling app's target SDK is API level 28 or lower and the app does not have + * the READ_PHONE_STATE permission, or if the calling app is targeting API level 29 or + * higher, then a SecurityException is thrown.</li> + * </ul> + * * @param slotIndex of which Nai is returned */ /** {@hide}*/ @@ -2452,41 +2530,45 @@ public class TelephonyManager { * @return the lowercase 2 character ISO-3166 country code, or empty string if not available. */ public String getNetworkCountryIso() { - return getNetworkCountryIsoForPhone(getPhoneId()); + try { + ITelephony telephony = getITelephony(); + if (telephony == null) return ""; + return telephony.getNetworkCountryIsoForPhone(getPhoneId(), + null /* no permission check */); + } catch (RemoteException ex) { + return ""; + } } /** - * Returns the ISO country code equivalent of the MCC (Mobile Country Code) of the current + * Returns the ISO-3166 country code equivalent of the MCC (Mobile Country Code) of the current * registered operator or the cell nearby, if available. * <p> + * The ISO-3166 country code is provided in lowercase 2 character format. + * <p> + * Note: In multi-sim, this returns a shared emergency network country iso from other + * subscription if the subscription used to create the TelephonyManager doesn't camp on + * a network due to some reason (e.g. pin/puk locked), or sim is absent in the corresponding + * slot. * Note: Result may be unreliable on CDMA networks (use {@link #getPhoneType()} to determine * if on a CDMA network). - * - * @param subId for which Network CountryIso is returned - * @hide - */ - @UnsupportedAppUsage - public String getNetworkCountryIso(int subId) { - return getNetworkCountryIsoForPhone(getPhoneId(subId)); - } - - /** - * Returns the ISO country code equivalent of the current registered - * operator's MCC (Mobile Country Code) of a subscription. * <p> - * Availability: Only when user is registered to a network. Result may be - * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if - * on a CDMA network). * - * @param phoneId for which Network CountryIso is returned + * @param slotIndex the SIM slot index to get network country ISO. + * + * @return the lowercase 2 character ISO-3166 country code, or empty string if not available. + * + * {@hide} */ - /** {@hide} */ - @UnsupportedAppUsage - public String getNetworkCountryIsoForPhone(int phoneId) { + @SystemApi + @TestApi + @NonNull + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public String getNetworkCountryIso(int slotIndex) { try { ITelephony telephony = getITelephony(); if (telephony == null) return ""; - return telephony.getNetworkCountryIsoForPhone(phoneId); + return telephony.getNetworkCountryIsoForPhone(slotIndex, getOpPackageName()); } catch (RemoteException ex) { return ""; } @@ -2545,33 +2627,6 @@ public class TelephonyManager { /** Max network type number. Update as new types are added. Don't add negative types. {@hide} */ public static final int MAX_NETWORK_TYPE = NETWORK_TYPE_NR; - /** @hide */ - @IntDef({ - NETWORK_TYPE_UNKNOWN, - NETWORK_TYPE_GPRS, - NETWORK_TYPE_EDGE, - NETWORK_TYPE_UMTS, - NETWORK_TYPE_CDMA, - NETWORK_TYPE_EVDO_0, - NETWORK_TYPE_EVDO_A, - NETWORK_TYPE_1xRTT, - NETWORK_TYPE_HSDPA, - NETWORK_TYPE_HSUPA, - NETWORK_TYPE_HSPA, - NETWORK_TYPE_IDEN, - NETWORK_TYPE_EVDO_B, - NETWORK_TYPE_LTE, - NETWORK_TYPE_EHRPD, - NETWORK_TYPE_HSPAP, - NETWORK_TYPE_GSM, - NETWORK_TYPE_TD_SCDMA, - NETWORK_TYPE_IWLAN, - NETWORK_TYPE_LTE_CA, - NETWORK_TYPE_NR, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface NetworkType{} - /** * Return the current data network type. * @@ -2748,6 +2803,8 @@ public class TelephonyManager { /** Class of broadly defined "4G" networks. {@hide} */ @UnsupportedAppUsage public static final int NETWORK_CLASS_4_G = 3; + /** Class of broadly defined "5G" networks. {@hide} */ + public static final int NETWORK_CLASS_5_G = 4; /** * Return general class of network type, such as "3G" or "4G". In cases @@ -2780,6 +2837,8 @@ public class TelephonyManager { case NETWORK_TYPE_IWLAN: case NETWORK_TYPE_LTE_CA: return NETWORK_CLASS_4_G; + case NETWORK_TYPE_NR: + return NETWORK_CLASS_5_G; default: return NETWORK_CLASS_UNKNOWN; } @@ -4568,6 +4627,17 @@ public class TelephonyManager { } /** + * Sim activation type: voice + * @hide + */ + public static final int SIM_ACTIVATION_TYPE_VOICE = 0; + /** + * Sim activation type: data + * @hide + */ + public static final int SIM_ACTIVATION_TYPE_DATA = 1; + + /** * Initial SIM activation state, unknown. Not set by any carrier apps. * @hide */ @@ -4610,17 +4680,6 @@ public class TelephonyManager { @SystemApi public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4; - /** @hide */ - @IntDef({ - SIM_ACTIVATION_STATE_UNKNOWN, - SIM_ACTIVATION_STATE_ACTIVATING, - SIM_ACTIVATION_STATE_ACTIVATED, - SIM_ACTIVATION_STATE_DEACTIVATED, - SIM_ACTIVATION_STATE_RESTRICTED - }) - @Retention(RetentionPolicy.SOURCE) - public @interface SimActivationState{} - /** * Sets the voice activation state * @@ -5005,15 +5064,6 @@ public class TelephonyManager { */ public static final int CALL_STATE_OFFHOOK = 2; - /** @hide */ - @IntDef(prefix = { "CALL_STATE_" }, value = { - CALL_STATE_IDLE, - CALL_STATE_RINGING, - CALL_STATE_OFFHOOK - }) - @Retention(RetentionPolicy.SOURCE) - public @interface CallState{} - /** * Returns the state of all calls on the device. * <p> @@ -5529,18 +5579,20 @@ public class TelephonyManager { telephony.requestCellInfoUpdate( getSubId(), new ICellInfoCallback.Stub() { + @Override public void onCellInfo(List<CellInfo> cellInfo) { Binder.withCleanCallingIdentity(() -> executor.execute(() -> callback.onCellInfo(cellInfo))); } - public void onError(int errorCode, android.os.ParcelableException detail) { + @Override + public void onError(int errorCode, String exceptionName, String message) { Binder.withCleanCallingIdentity(() -> executor.execute(() -> callback.onError( - errorCode, detail.getCause()))); + errorCode, + createThrowableByClassName(exceptionName, message)))); } }, getOpPackageName()); - } catch (RemoteException ex) { } } @@ -5569,21 +5621,36 @@ public class TelephonyManager { telephony.requestCellInfoUpdateWithWorkSource( getSubId(), new ICellInfoCallback.Stub() { + @Override public void onCellInfo(List<CellInfo> cellInfo) { Binder.withCleanCallingIdentity(() -> executor.execute(() -> callback.onCellInfo(cellInfo))); } - public void onError(int errorCode, android.os.ParcelableException detail) { + @Override + public void onError(int errorCode, String exceptionName, String message) { Binder.withCleanCallingIdentity(() -> executor.execute(() -> callback.onError( - errorCode, detail.getCause()))); + errorCode, + createThrowableByClassName(exceptionName, message)))); } }, getOpPackageName(), workSource); } catch (RemoteException ex) { } } + private static Throwable createThrowableByClassName(String className, String message) { + if (className == null) { + return null; + } + try { + Class<?> c = Class.forName(className); + return (Throwable) c.getConstructor(String.class).newInstance(message); + } catch (ReflectiveOperationException | ClassCastException e) { + } + return new RuntimeException(className + ": " + message); + } + /** * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged * PhoneStateListener.onCellInfoChanged} will be invoked. @@ -6836,6 +6903,40 @@ public class TelephonyManager { } /** + * Replace the contents of the forbidden PLMN SIM file with the provided values. + * Passing an empty list will clear the contents of the EFfplmn file. + * If the provided list is shorter than the size of EFfplmn, then the list will be padded + * up to the file size with 'FFFFFF'. (required by 3GPP TS 31.102 spec 4.2.16) + * If the list is longer than the size of EFfplmn, then the file will be written from the + * beginning of the list up to the file size. + * + * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). + * + * @param fplmns a list of PLMNs to be forbidden. + * + * @return number of PLMNs that were successfully written to the SIM FPLMN list. + * This may be less than the number of PLMNs passed in where the SIM file does not have enough + * room for all of the values passed in. Return -1 in the event of an unexpected failure + */ + @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public int setForbiddenPlmns(@NonNull List<String> fplmns) { + try { + ITelephony telephony = getITelephony(); + if (telephony == null) return 0; + return telephony.setForbiddenPlmns( + getSubId(), APPTYPE_USIM, fplmns, getOpPackageName()); + } catch (RemoteException ex) { + Rlog.e(TAG, "setForbiddenPlmns RemoteException: " + ex.getMessage()); + } catch (NullPointerException ex) { + // This could happen before phone starts + Rlog.e(TAG, "setForbiddenPlmns NullPointerException: " + ex.getMessage()); + } + return 0; + } + + /** * Get P-CSCF address from PCO after data connection is established or modified. * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN * @return array of P-CSCF address @@ -8309,15 +8410,6 @@ public class TelephonyManager { return false; } - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"RADIO_POWER_"}, - value = {RADIO_POWER_OFF, - RADIO_POWER_ON, - RADIO_POWER_UNAVAILABLE, - }) - public @interface RadioPowerState {} - /** * Radio explicitly powered off (e.g, airplane mode). * @hide @@ -10151,11 +10243,13 @@ public class TelephonyManager { /** * Action set from carrier signalling broadcast receivers to enable/disable radio - * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required + * Permissions {@link android.Manifest.permission.MODIFY_PHONE_STATE} is required. * @param subId the subscription ID that this action applies to. * @param enabled control enable or disable radio. * @hide */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void carrierActionSetRadioEnabled(int subId, boolean enabled) { try { ITelephony service = getITelephony(); @@ -10170,11 +10264,13 @@ public class TelephonyManager { /** * Action set from carrier signalling broadcast receivers to start/stop reporting default * network available events - * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required + * Permissions {@link android.Manifest.permission.MODIFY_PHONE_STATE} is required. * @param subId the subscription ID that this action applies to. * @param report control start/stop reporting network status. * @hide */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) { try { ITelephony service = getITelephony(); @@ -10188,10 +10284,12 @@ public class TelephonyManager { /** * Action set from carrier signalling broadcast receivers to reset all carrier actions - * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required + * Permissions {@link android.Manifest.permission.MODIFY_PHONE_STATE} is required. * @param subId the subscription ID that this action applies to. * @hide */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void carrierActionResetAll(int subId) { try { ITelephony service = getITelephony(); @@ -11427,11 +11525,14 @@ public class TelephonyManager { * 3) APN type is whitelisted. E.g. MMS is whitelisted if * {@link SubscriptionManager#setAlwaysAllowMmsData} is turned on. * + * @param apnType Value indicating the apn type. Apn types are defined in {@link ApnSetting}. * @return whether data is enabled for a apn type. * * @hide */ - public boolean isDataEnabledForApn(@ApnSetting.ApnType int apnType) { + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public boolean isDataEnabledForApn(@ApnType int apnType) { String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; try { ITelephony service = getITelephony(); @@ -11452,7 +11553,7 @@ public class TelephonyManager { * * @hide */ - public boolean isApnMetered(@ApnSetting.ApnType int apnType) { + public boolean isApnMetered(@ApnType int apnType) { try { ITelephony service = getITelephony(); if (service != null) { diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java index 28747dab38db..9ff851598648 100644 --- a/telephony/java/android/telephony/TelephonyScanManager.java +++ b/telephony/java/android/telephony/TelephonyScanManager.java @@ -104,7 +104,7 @@ public final class TelephonyScanManager { private final Looper mLooper; private final Messenger mMessenger; - private SparseArray<NetworkScanInfo> mScanInfo = new SparseArray<NetworkScanInfo>(); + private final SparseArray<NetworkScanInfo> mScanInfo = new SparseArray<NetworkScanInfo>(); public TelephonyScanManager() { HandlerThread thread = new HandlerThread(TAG); @@ -204,14 +204,16 @@ public final class TelephonyScanManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - int scanId = telephony.requestNetworkScan( - subId, request, mMessenger, new Binder(), callingPackage); - if (scanId == INVALID_SCAN_ID) { - Rlog.e(TAG, "Failed to initiate network scan"); - return null; + synchronized (mScanInfo) { + int scanId = telephony.requestNetworkScan( + subId, request, mMessenger, new Binder(), callingPackage); + if (scanId == INVALID_SCAN_ID) { + Rlog.e(TAG, "Failed to initiate network scan"); + return null; + } + saveScanInfo(scanId, request, executor, callback); + return new NetworkScan(scanId, subId); } - saveScanInfo(scanId, request, executor, callback); - return new NetworkScan(scanId, subId); } } catch (RemoteException ex) { Rlog.e(TAG, "requestNetworkScan RemoteException", ex); @@ -223,9 +225,7 @@ public final class TelephonyScanManager { private void saveScanInfo( int id, NetworkScanRequest request, Executor executor, NetworkScanCallback callback) { - synchronized (mScanInfo) { - mScanInfo.put(id, new NetworkScanInfo(request, executor, callback)); - } + mScanInfo.put(id, new NetworkScanInfo(request, executor, callback)); } private ITelephony getITelephony() { diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java index 5f2f75da5c41..02429b5c2a2c 100644 --- a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java +++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java @@ -16,12 +16,19 @@ package android.telephony.cdma; +import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** - * CDMA Service Category Program Data from SCPT teleservice SMS. + * CDMA Service Category Program Data from SCPT (Service Category Programming Teleservice) SMS, + * as defined in 3GPP2 C.S0015-B section 4.5.19. + * <p> * The CellBroadcastReceiver app receives an Intent with action * {@link android.provider.Telephony.Sms.Intents#SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION} * containing an array of these objects to update its list of cell broadcast service categories @@ -29,6 +36,7 @@ import android.os.Parcelable; * * {@hide} */ +@SystemApi public final class CdmaSmsCbProgramData implements Parcelable { /** Delete the specified service category from the list of enabled categories. */ @@ -40,40 +48,83 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** Clear all service categories from the list of enabled categories. */ public static final int OPERATION_CLEAR_CATEGORIES = 2; - /** Alert option: no alert. */ + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"OPERATION_"}, + value = { + OPERATION_DELETE_CATEGORY, + OPERATION_ADD_CATEGORY, + OPERATION_CLEAR_CATEGORIES, + }) + public @interface Operation {} + + // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1 + /** Indicates a presidential-level alert */ + public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 0x1000; + + /** Indicates an extreme threat to life and property */ + public static final int CATEGORY_CMAS_EXTREME_THREAT = 0x1001; + + /** Indicates an severe threat to life and property */ + public static final int CATEGORY_CMAS_SEVERE_THREAT = 0x1002; + + /** Indicates an AMBER child abduction emergency */ + public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003; + + /** Indicates a CMAS test message */ + public static final int CATEGORY_CMAS_TEST_MESSAGE = 0x1004; + + /** The last reserved value of a CMAS service category according to 3GPP C.R1001 table + * 9.3.3-1. */ + public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 0x10ff; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"CATEGORY_"}, + value = { + CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, + CATEGORY_CMAS_EXTREME_THREAT, + CATEGORY_CMAS_SEVERE_THREAT, + CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY, + CATEGORY_CMAS_TEST_MESSAGE, + CATEGORY_CMAS_LAST_RESERVED_VALUE, + }) + public @interface Category {} + + /** Alert option: no alert. @hide */ public static final int ALERT_OPTION_NO_ALERT = 0; - /** Alert option: default alert. */ + /** Alert option: default alert. @hide */ public static final int ALERT_OPTION_DEFAULT_ALERT = 1; - /** Alert option: vibrate alert once. */ + /** Alert option: vibrate alert once. @hide */ public static final int ALERT_OPTION_VIBRATE_ONCE = 2; - /** Alert option: vibrate alert - repeat. */ + /** Alert option: vibrate alert - repeat. @hide */ public static final int ALERT_OPTION_VIBRATE_REPEAT = 3; - /** Alert option: visual alert once. */ + /** Alert option: visual alert once. @hide */ public static final int ALERT_OPTION_VISUAL_ONCE = 4; - /** Alert option: visual alert - repeat. */ + /** Alert option: visual alert - repeat. @hide */ public static final int ALERT_OPTION_VISUAL_REPEAT = 5; - /** Alert option: low-priority alert once. */ + /** Alert option: low-priority alert once. @hide */ public static final int ALERT_OPTION_LOW_PRIORITY_ONCE = 6; - /** Alert option: low-priority alert - repeat. */ + /** Alert option: low-priority alert - repeat. @hide */ public static final int ALERT_OPTION_LOW_PRIORITY_REPEAT = 7; - /** Alert option: medium-priority alert once. */ + /** Alert option: medium-priority alert once. @hide */ public static final int ALERT_OPTION_MED_PRIORITY_ONCE = 8; - /** Alert option: medium-priority alert - repeat. */ + /** Alert option: medium-priority alert - repeat. @hide */ public static final int ALERT_OPTION_MED_PRIORITY_REPEAT = 9; - /** Alert option: high-priority alert once. */ + /** Alert option: high-priority alert once. @hide */ public static final int ALERT_OPTION_HIGH_PRIORITY_ONCE = 10; - /** Alert option: high-priority alert - repeat. */ + /** Alert option: high-priority alert - repeat. @hide */ public static final int ALERT_OPTION_HIGH_PRIORITY_REPEAT = 11; /** Service category operation (add/delete/clear). */ @@ -94,9 +145,12 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** Name of service category. */ private final String mCategoryName; - /** Create a new CdmaSmsCbProgramData object with the specified values. */ - public CdmaSmsCbProgramData(int operation, int category, int language, int maxMessages, - int alertOption, @NonNull String categoryName) { + /** + * Create a new CdmaSmsCbProgramData object with the specified values. + * @hide + */ + public CdmaSmsCbProgramData(@Operation int operation, @Category int category, int language, + int maxMessages, int alertOption, @NonNull String categoryName) { mOperation = operation; mCategory = category; mLanguage = language; @@ -105,7 +159,10 @@ public final class CdmaSmsCbProgramData implements Parcelable { mCategoryName = categoryName; } - /** Create a new CdmaSmsCbProgramData object from a Parcel. */ + /** + * Create a new CdmaSmsCbProgramData object from a Parcel. + * @hide + */ CdmaSmsCbProgramData(Parcel in) { mOperation = in.readInt(); mCategory = in.readInt(); @@ -133,23 +190,28 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** * Returns the service category operation, e.g. {@link #OPERATION_ADD_CATEGORY}. - * @return one of the {@code OPERATION_*} values + * + * @return the service category operation */ - public int getOperation() { + public @Operation int getOperation() { return mOperation; } /** - * Returns the CDMA service category to modify. + * Returns the CDMA service category to modify. See 3GPP2 C.S0015-B section 3.4.3.2 for more + * information on the service category. Currently only CMAS service categories 0x1000 through + * 0x10FF are supported. + * * @return a 16-bit CDMA service category value */ - public int getCategory() { + public @Category int getCategory() { return mCategory; } /** * Returns the CDMA language code for this service category. * @return one of the language values defined in BearerData.LANGUAGE_* + * @hide */ public int getLanguage() { return mLanguage; @@ -158,6 +220,7 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** * Returns the maximum number of messages to store for this service category. * @return the maximum number of messages to store for this service category + * @hide */ public int getMaxMessages() { return mMaxMessages; @@ -166,6 +229,7 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** * Returns the service category alert option, e.g. {@link #ALERT_OPTION_DEFAULT_ALERT}. * @return one of the {@code ALERT_OPTION_*} values + * @hide */ public int getAlertOption() { return mAlertOption; @@ -174,6 +238,7 @@ public final class CdmaSmsCbProgramData implements Parcelable { /** * Returns the service category name, in the language specified by {@link #getLanguage()}. * @return an optional service category name + * @hide */ @NonNull public String getCategoryName() { @@ -196,7 +261,10 @@ public final class CdmaSmsCbProgramData implements Parcelable { return 0; } - /** Creator for unparcelling objects. */ + /** + * Creator for unparcelling objects. + */ + @NonNull public static final Parcelable.Creator<CdmaSmsCbProgramData> CREATOR = new Parcelable.Creator<CdmaSmsCbProgramData>() { @Override diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index a3c37db6f381..ae739334b9bf 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -26,6 +26,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.provider.Telephony; import android.provider.Telephony.Carriers; +import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.NetworkType; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.TelephonyManager; @@ -109,23 +111,6 @@ public class ApnSetting implements Parcelable { /** APN type for MCX (Mission Critical Service) where X can be PTT/Video/Data */ public static final int TYPE_MCX = ApnTypes.MCX; - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_DEFAULT, - TYPE_MMS, - TYPE_SUPL, - TYPE_DUN, - TYPE_HIPRI, - TYPE_FOTA, - TYPE_IMS, - TYPE_CBS, - TYPE_IA, - TYPE_EMERGENCY, - TYPE_MCX - }) - @Retention(RetentionPolicy.SOURCE) - public @interface ApnType {} - // Possible values for authentication types. /** No authentication type. */ public static final int AUTH_TYPE_NONE = 0; @@ -1430,7 +1415,7 @@ public class ApnSetting implements Parcelable { * * @hide */ - public boolean canSupportNetworkType(@TelephonyManager.NetworkType int networkType) { + public boolean canSupportNetworkType(@NetworkType int networkType) { // Do a special checking for GSM. In reality, GSM is a voice only network type and can never // be used for data. We allow it here because in some DSDS corner cases, on the non-DDS // sub, modem reports data rat unknown. In that case if voice is GSM and this APN supports diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 9170e88ce832..49625bbecf4f 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -24,8 +24,8 @@ import android.annotation.SystemApi; import android.net.LinkAddress; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.DataFailureCause; import android.telephony.DataFailCause; -import android.telephony.DataFailCause.FailCause; import android.telephony.data.ApnSetting.ProtocolType; import com.android.internal.annotations.VisibleForTesting; @@ -67,7 +67,7 @@ public final class DataCallResponse implements Parcelable { /** Indicates the data connection is active with physical link up. */ public static final int LINK_STATUS_ACTIVE = 2; - private final @FailCause int mCause; + private final @DataFailureCause int mCause; private final int mSuggestedRetryTime; private final int mId; private final @LinkStatus int mLinkStatus; @@ -103,7 +103,7 @@ public final class DataCallResponse implements Parcelable { * * @removed Use the {@link Builder()} instead. */ - public DataCallResponse(@FailCause int cause, int suggestedRetryTime, int id, + public DataCallResponse(@DataFailureCause int cause, int suggestedRetryTime, int id, @LinkStatus int linkStatus, @ProtocolType int protocolType, @Nullable String interfaceName, @Nullable List<LinkAddress> addresses, @@ -150,7 +150,7 @@ public final class DataCallResponse implements Parcelable { /** * @return Data call fail cause. {@link DataFailCause#NONE} indicates no error. */ - @FailCause + @DataFailureCause public int getCause() { return mCause; } /** @@ -314,7 +314,7 @@ public final class DataCallResponse implements Parcelable { * </code></pre> */ public static final class Builder { - private @FailCause int mCause; + private @DataFailureCause int mCause; private int mSuggestedRetryTime; @@ -348,7 +348,7 @@ public final class DataCallResponse implements Parcelable { * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. * @return The same instance of the builder. */ - public @NonNull Builder setCause(@FailCause int cause) { + public @NonNull Builder setCause(@DataFailureCause int cause) { mCause = cause; return this; } diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java index 0d79ec98fcbb..30c209b28a4d 100644 --- a/telephony/java/android/telephony/data/DataProfile.java +++ b/telephony/java/android/telephony/data/DataProfile.java @@ -25,8 +25,8 @@ import android.annotation.SystemApi; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.ApnType; import android.telephony.TelephonyManager.NetworkTypeBitMask; -import android.telephony.data.ApnSetting.ApnType; import android.telephony.data.ApnSetting.AuthType; import android.text.TextUtils; diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java index 0e1751d50949..e793979a61c9 100644 --- a/telephony/java/android/telephony/data/QualifiedNetworksService.java +++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java @@ -27,8 +27,8 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.telephony.AccessNetworkConstants.AccessNetworkType; +import android.telephony.Annotation.ApnType; import android.telephony.Rlog; -import android.telephony.data.ApnSetting.ApnType; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; @@ -133,7 +133,7 @@ public abstract class QualifiedNetworksService extends Service { * service. * * @param apnTypes APN types of the qualified networks. This must be a bitmask combination - * of {@link ApnSetting.ApnType}. + * of {@link ApnType}. * @param qualifiedNetworkTypes List of network types which are qualified for data * connection setup for {@link @apnType} in the preferred order. Each element in the list * is a {@link AccessNetworkType}. An empty list indicates no networks are qualified diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java index 19d07242132b..16662652847d 100644 --- a/telephony/java/android/telephony/emergency/EmergencyNumber.java +++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java @@ -18,6 +18,7 @@ package android.telephony.emergency; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.TestApi; import android.hardware.radio.V1_4.EmergencyNumberSource; import android.hardware.radio.V1_4.EmergencyServiceCategory; import android.os.Parcel; @@ -184,6 +185,7 @@ public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNu * * @hide */ + @TestApi public static final int EMERGENCY_NUMBER_SOURCE_TEST = 1 << 5; /** Bit-field which indicates the number is from the modem config. */ public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG = diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index cabd4dfd91f1..5a90cb13a548 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -32,6 +32,7 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.TelephonyManager; +import android.telephony.euicc.EuiccCardManager.ResetOption; import com.android.internal.telephony.euicc.IEuiccController; @@ -821,17 +822,22 @@ public class EuiccManager { } /** - * Erase all subscriptions and reset the eUICC. + * Erase all operational subscriptions and reset the eUICC. * * <p>Requires that the calling app has the * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. * * @param callbackIntent a PendingIntent to launch when the operation completes. + * + * @deprecated From R, callers should specify a flag for specific set of subscriptions to erase + * and use @link{eraseSubscriptionsWithOptions} instead + * * @hide */ @SystemApi @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) - public void eraseSubscriptions(PendingIntent callbackIntent) { + @Deprecated + public void eraseSubscriptions(@NonNull PendingIntent callbackIntent) { if (!isEnabled()) { sendUnavailableError(callbackIntent); return; @@ -844,6 +850,32 @@ public class EuiccManager { } /** + * Erase all specific subscriptions and reset the eUICC. + * + * <p>Requires that the calling app has the + * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. + * + * @param options flag indicating specific set of subscriptions to erase + * @param callbackIntent a PendingIntent to launch when the operation completes. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) + public void eraseSubscriptionsWithOptions( + @ResetOption int options, @NonNull PendingIntent callbackIntent) { + if (!isEnabled()) { + sendUnavailableError(callbackIntent); + return; + } + try { + getIEuiccController().eraseSubscriptionsWithOptions(mCardId, options, callbackIntent); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Ensure that subscriptions will be retained on the next factory reset. * * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java index a1a7fcc5dd51..2fad8479178e 100644 --- a/telephony/java/android/telephony/ims/ImsMmTelManager.java +++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java @@ -183,19 +183,17 @@ public class ImsMmTelManager { /** * Notifies the framework when the IMS Provider is registered to the IMS network. * - * @param imsTransportType the radio access technology. Valid values are defined in - * {@link android.telephony.AccessNetworkConstants.TransportType}. + * @param imsTransportType the radio access technology. */ - public void onRegistered(int imsTransportType) { + public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) { } /** * Notifies the framework when the IMS Provider is trying to register the IMS network. * - * @param imsTransportType the radio access technology. Valid values are defined in - * {@link android.telephony.AccessNetworkConstants.TransportType}. + * @param imsTransportType the radio access technology. */ - public void onRegistering(int imsTransportType) { + public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) { } /** @@ -207,15 +205,14 @@ public class ImsMmTelManager { } /** - * A failure has occurred when trying to handover registration to another technology type, - * defined in {@link android.telephony.AccessNetworkConstants.TransportType} + * A failure has occurred when trying to handover registration to another technology type. * - * @param imsTransportType The - * {@link android.telephony.AccessNetworkConstants.TransportType} - * transport type that has failed to handover registration to. + * @param imsTransportType The transport type that has failed to handover registration to. * @param info A {@link ImsReasonInfo} that identifies the reason for failure. */ - public void onTechnologyChangeFailed(int imsTransportType, @Nullable ImsReasonInfo info) { + public void onTechnologyChangeFailed( + @AccessNetworkConstants.TransportType int imsTransportType, + @Nullable ImsReasonInfo info) { } /** diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java index 1e0d9a786acc..10251d707c22 100644 --- a/telephony/java/android/telephony/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -885,6 +885,12 @@ public final class ImsReasonInfo implements Parcelable { */ public static final int CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 1623; + /** + * The dialed RTT call should be retried without RTT + * @hide + */ + public static final int CODE_RETRY_ON_IMS_WITHOUT_RTT = 3001; + /* * OEM specific error codes. To be used by OEMs when they don't want to reveal error code which * would be replaced by ERROR_UNSPECIFIED. @@ -1065,6 +1071,7 @@ public final class ImsReasonInfo implements Parcelable { CODE_REJECT_VT_AVPF_NOT_ALLOWED, CODE_REJECT_ONGOING_ENCRYPTED_CALL, CODE_REJECT_ONGOING_CS_CALL, + CODE_RETRY_ON_IMS_WITHOUT_RTT, CODE_OEM_CAUSE_1, CODE_OEM_CAUSE_2, CODE_OEM_CAUSE_3, diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java index 175769bd34e4..36ece958d501 100644 --- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java @@ -17,6 +17,7 @@ package android.telephony.ims.stub; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.SystemApi; import android.os.RemoteException; import android.telephony.SmsManager; @@ -148,14 +149,16 @@ public class ImsSmsImplBase { * * @param token unique token generated by the platform that should be used when triggering * callbacks for this specific message. - * @param messageRef the message reference. - * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. + * @param messageRef the message reference, which may be 1 byte if it is in + * {@link SmsMessage#FORMAT_3GPP} format (see TS.123.040) or 2 bytes if it is in + * {@link SmsMessage#FORMAT_3GPP2} format (see 3GPP2 C.S0015-B). + * @param format the format of the message. * @param smsc the Short Message Service Center address. * @param isRetry whether it is a retry of an already attempted message or not. * @param pdu PDU representing the contents of the message. */ - public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry, + public void sendSms(int token, @IntRange(from = 0, to = 65535) int messageRef, + @SmsMessage.Format String format, String smsc, boolean isRetry, byte[] pdu) { // Base implementation returns error. Should be overridden. try { @@ -172,14 +175,13 @@ public class ImsSmsImplBase { * provider. * * @param token token provided in {@link #onSmsReceived(int, String, byte[])} - * @param messageRef the message reference - * @param result result of delivering the message. Valid values are: - * {@link #DELIVER_STATUS_OK}, - * {@link #DELIVER_STATUS_ERROR_GENERIC}, - * {@link #DELIVER_STATUS_ERROR_NO_MEMORY}, - * {@link #DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED} + * @param messageRef the message reference, which may be 1 byte if it is in + * {@link SmsMessage#FORMAT_3GPP} format (see TS.123.040) or 2 bytes if it is in + * {@link SmsMessage#FORMAT_3GPP2} format (see 3GPP2 C.S0015-B). + * @param result result of delivering the message. */ - public void acknowledgeSms(int token, int messageRef, @DeliverStatusResult int result) { + public void acknowledgeSms(int token, @IntRange(from = 0, to = 65535) int messageRef, + @DeliverStatusResult int result) { Log.e(LOG_TAG, "acknowledgeSms() not implemented."); } @@ -191,12 +193,13 @@ public class ImsSmsImplBase { * * @param token token provided in {@link #onSmsStatusReportReceived(int, int, String, byte[])} * or {@link #onSmsStatusReportReceived(int, String, byte[])} - * @param messageRef the message reference - * @param result result of delivering the message. Valid values are: - * {@link #STATUS_REPORT_STATUS_OK}, - * {@link #STATUS_REPORT_STATUS_ERROR} + * @param messageRef the message reference, which may be 1 byte if it is in + * {@link SmsMessage#FORMAT_3GPP} format (see TS.123.040) or 2 bytes if it is in + * {@link SmsMessage#FORMAT_3GPP2} format (see 3GPP2 C.S0015-B). + * @param result result of delivering the message. */ - public void acknowledgeSmsReport(int token, int messageRef, @StatusReportResult int result) { + public void acknowledgeSmsReport(int token, @IntRange(from = 0, to = 65535) int messageRef, + @StatusReportResult int result) { Log.e(LOG_TAG, "acknowledgeSmsReport() not implemented."); } @@ -210,12 +213,12 @@ public class ImsSmsImplBase { * {@link #DELIVER_STATUS_ERROR_GENERIC} result code. * @param token unique token generated by IMS providers that the platform will use to trigger * callbacks for this message. - * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. + * @param format the format of the message. * @param pdu PDU representing the contents of the message. * @throws RuntimeException if called before {@link #onReady()} is triggered. */ - public final void onSmsReceived(int token, String format, byte[] pdu) throws RuntimeException { + public final void onSmsReceived(int token, @SmsMessage.Format String format, byte[] pdu) + throws RuntimeException { synchronized (mLock) { if (mListener == null) { throw new RuntimeException("Feature not ready."); @@ -241,13 +244,16 @@ public class ImsSmsImplBase { * sent successfully. * * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} - * @param messageRef the message reference. Should be between 0 and 255 per TS.123.040 + * @param messageRef the message reference, which may be 1 byte if it is in + * {@link SmsMessage#FORMAT_3GPP} format (see TS.123.040) or 2 bytes if it is in + * {@link SmsMessage#FORMAT_3GPP2} format (see 3GPP2 C.S0015-B). * * @throws RuntimeException if called before {@link #onReady()} is triggered or if the * connection to the framework is not available. If this happens attempting to send the SMS * should be aborted. */ - public final void onSendSmsResultSuccess(int token, int messageRef) throws RuntimeException { + public final void onSendSmsResultSuccess(int token, + @IntRange(from = 0, to = 65535) int messageRef) throws RuntimeException { synchronized (mLock) { if (mListener == null) { throw new RuntimeException("Feature not ready."); @@ -266,34 +272,11 @@ public class ImsSmsImplBase { * to the platform. * * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} - * @param messageRef the message reference. Should be between 0 and 255 per TS.123.040 + * @param messageRef the message reference, which may be 1 byte if it is in + * {@link SmsMessage#FORMAT_3GPP} format (see TS.123.040) or 2 bytes if it is in + * {@link SmsMessage#FORMAT_3GPP2} format (see 3GPP2 C.S0015-B). * @param status result of sending the SMS. - * @param reason reason in case status is failure. Valid values are: - * {@link SmsManager#RESULT_ERROR_NONE}, - * {@link SmsManager#RESULT_ERROR_GENERIC_FAILURE}, - * {@link SmsManager#RESULT_ERROR_RADIO_OFF}, - * {@link SmsManager#RESULT_ERROR_NULL_PDU}, - * {@link SmsManager#RESULT_ERROR_NO_SERVICE}, - * {@link SmsManager#RESULT_ERROR_LIMIT_EXCEEDED}, - * {@link SmsManager#RESULT_ERROR_FDN_CHECK_FAILURE}, - * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NOT_ALLOWED}, - * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED}, - * {@link SmsManager#RESULT_RADIO_NOT_AVAILABLE}, - * {@link SmsManager#RESULT_NETWORK_REJECT}, - * {@link SmsManager#RESULT_INVALID_ARGUMENTS}, - * {@link SmsManager#RESULT_INVALID_STATE}, - * {@link SmsManager#RESULT_NO_MEMORY}, - * {@link SmsManager#RESULT_INVALID_SMS_FORMAT}, - * {@link SmsManager#RESULT_SYSTEM_ERROR}, - * {@link SmsManager#RESULT_MODEM_ERROR}, - * {@link SmsManager#RESULT_NETWORK_ERROR}, - * {@link SmsManager#RESULT_ENCODING_ERROR}, - * {@link SmsManager#RESULT_INVALID_SMSC_ADDRESS}, - * {@link SmsManager#RESULT_OPERATION_NOT_ALLOWED}, - * {@link SmsManager#RESULT_INTERNAL_ERROR}, - * {@link SmsManager#RESULT_NO_RESOURCES}, - * {@link SmsManager#RESULT_CANCELLED}, - * {@link SmsManager#RESULT_REQUEST_NOT_SUPPORTED} + * @param reason reason in case status is failure. * * @throws RuntimeException if called before {@link #onReady()} is triggered or if the * connection to the framework is not available. If this happens attempting to send the SMS @@ -303,8 +286,8 @@ public class ImsSmsImplBase { * send result. */ @Deprecated - public final void onSendSmsResult(int token, int messageRef, @SendStatusResult int status, - int reason) throws RuntimeException { + public final void onSendSmsResult(int token, @IntRange(from = 0, to = 65535) int messageRef, + @SendStatusResult int status, @SmsManager.Result int reason) throws RuntimeException { synchronized (mLock) { if (mListener == null) { throw new RuntimeException("Feature not ready."); @@ -324,34 +307,10 @@ public class ImsSmsImplBase { * network. * * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} - * @param messageRef the message reference. Should be between 0 and 255 per TS.123.040 + * @param messageRef the message reference, which may be 1 byte if it is in + * {@link SmsMessage#FORMAT_3GPP} format (see TS.123.040) or 2 bytes if it is in + * {@link SmsMessage#FORMAT_3GPP2} format (see 3GPP2 C.S0015-B). * @param status result of sending the SMS. - * @param reason Valid values are: - * {@link SmsManager#RESULT_ERROR_NONE}, - * {@link SmsManager#RESULT_ERROR_GENERIC_FAILURE}, - * {@link SmsManager#RESULT_ERROR_RADIO_OFF}, - * {@link SmsManager#RESULT_ERROR_NULL_PDU}, - * {@link SmsManager#RESULT_ERROR_NO_SERVICE}, - * {@link SmsManager#RESULT_ERROR_LIMIT_EXCEEDED}, - * {@link SmsManager#RESULT_ERROR_FDN_CHECK_FAILURE}, - * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NOT_ALLOWED}, - * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED}, - * {@link SmsManager#RESULT_RADIO_NOT_AVAILABLE}, - * {@link SmsManager#RESULT_NETWORK_REJECT}, - * {@link SmsManager#RESULT_INVALID_ARGUMENTS}, - * {@link SmsManager#RESULT_INVALID_STATE}, - * {@link SmsManager#RESULT_NO_MEMORY}, - * {@link SmsManager#RESULT_INVALID_SMS_FORMAT}, - * {@link SmsManager#RESULT_SYSTEM_ERROR}, - * {@link SmsManager#RESULT_MODEM_ERROR}, - * {@link SmsManager#RESULT_NETWORK_ERROR}, - * {@link SmsManager#RESULT_ENCODING_ERROR}, - * {@link SmsManager#RESULT_INVALID_SMSC_ADDRESS}, - * {@link SmsManager#RESULT_OPERATION_NOT_ALLOWED}, - * {@link SmsManager#RESULT_INTERNAL_ERROR}, - * {@link SmsManager#RESULT_NO_RESOURCES}, - * {@link SmsManager#RESULT_CANCELLED}, - * {@link SmsManager#RESULT_REQUEST_NOT_SUPPORTED} * @param networkErrorCode the error code reported by the carrier network if sending this SMS * has resulted in an error or {@link #RESULT_NO_NETWORK_ERROR} if no network error was * generated. See 3GPP TS 24.011 Section 7.3.4 for valid error codes and more information. @@ -360,9 +319,9 @@ public class ImsSmsImplBase { * connection to the framework is not available. If this happens attempting to send the SMS * should be aborted. */ - public final void onSendSmsResultError(int token, int messageRef, @SendStatusResult int status, - int reason, int networkErrorCode) - throws RuntimeException { + public final void onSendSmsResultError(int token, + @IntRange(from = 0, to = 65535) int messageRef, @SendStatusResult int status, + @SmsManager.Result int reason, int networkErrorCode) throws RuntimeException { synchronized (mLock) { if (mListener == null) { throw new RuntimeException("Feature not ready."); @@ -384,9 +343,10 @@ public class ImsSmsImplBase { * the platform is not available, {@link #acknowledgeSmsReport(int, int, int)} will be called * with the {@link #STATUS_REPORT_STATUS_ERROR} result code. * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} - * @param messageRef the message reference. - * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. + * @param messageRef the message reference, which may be 1 byte if it is in + * {@link SmsMessage#FORMAT_3GPP} format or 2 bytes if it is in + * {@link SmsMessage#FORMAT_3GPP2} format (see 3GPP2 C.S0015-B). + * @param format the format of the message. * @param pdu PDU representing the content of the status report. * @throws RuntimeException if called before {@link #onReady()} is triggered * @@ -394,7 +354,8 @@ public class ImsSmsImplBase { * message reference. */ @Deprecated - public final void onSmsStatusReportReceived(int token, int messageRef, String format, + public final void onSmsStatusReportReceived(int token, + @IntRange(from = 0, to = 65535) int messageRef, @SmsMessage.Format String format, byte[] pdu) throws RuntimeException { synchronized (mLock) { if (mListener == null) { @@ -419,13 +380,12 @@ public class ImsSmsImplBase { * with the {@link #STATUS_REPORT_STATUS_ERROR} result code. * @param token unique token generated by IMS providers that the platform will use to trigger * callbacks for this message. - * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. + * @param format the format of the message. * @param pdu PDU representing the content of the status report. * @throws RuntimeException if called before {@link #onReady()} is triggered */ - public final void onSmsStatusReportReceived(int token, String format, byte[] pdu) - throws RuntimeException { + public final void onSmsStatusReportReceived(int token, @SmsMessage.Format String format, + byte[] pdu) throws RuntimeException { synchronized (mLock) { if (mListener == null) { throw new RuntimeException("Feature not ready."); @@ -450,13 +410,11 @@ public class ImsSmsImplBase { } /** - * Returns the SMS format. Default is {@link SmsMessage#FORMAT_3GPP} unless overridden by IMS - * Provider. + * Returns the SMS format that the ImsService expects. * - * @return the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. + * @return The expected format of the SMS messages. */ - public String getSmsFormat() { + public @SmsMessage.Format String getSmsFormat() { return SmsMessage.FORMAT_3GPP; } diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index 668a6af08145..9e786ce32792 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -111,7 +111,7 @@ public class DctConstants { public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49; public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50; public static final int EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51; - public static final int EVENT_5G_NETWORK_CHANGED = BASE + 52; + public static final int EVENT_SERVICE_STATE_CHANGED = BASE + 52; public static final int EVENT_5G_TIMER_HYSTERESIS = BASE + 53; public static final int EVENT_5G_TIMER_WATCHDOG = BASE + 54; diff --git a/telephony/java/com/android/internal/telephony/IMms.aidl b/telephony/java/com/android/internal/telephony/IMms.aidl deleted file mode 100644 index fa5073ef1c7e..000000000000 --- a/telephony/java/com/android/internal/telephony/IMms.aidl +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.app.PendingIntent; -import android.content.ContentValues; -import android.net.Uri; -import android.os.Bundle; - -/** - * Service interface to handle MMS API requests - */ -interface IMms { - /** - * Send an MMS message - * - * @param subId the SIM id - * @param callingPkg the package name of the calling app - * @param contentUri the content uri from which to read MMS message encoded in standard MMS - * PDU format - * @param locationUrl the optional location url for where this message should be sent to - * @param configOverrides the carrier-specific messaging configuration values to override for - * sending the message. See {@link android.telephony.SmsManager} for the value names and types. - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed - */ - void sendMessage(int subId, String callingPkg, in Uri contentUri, - String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent); - - /** - * Download an MMS message using known location and transaction id - * - * @param subId the SIM id - * @param callingPkg the package name of the calling app - * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained - * from the MMS WAP push notification - * @param contentUri a contentUri to which the downloaded MMS message will be written - * @param configOverrides the carrier-specific messaging configuration values to override for - * downloading the message. See {@link android.telephony.SmsManager} for the value names and - * types. - * @param downloadedIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is downloaded, or the download is failed - */ - void downloadMessage(int subId, String callingPkg, String locationUrl, - in Uri contentUri, in Bundle configOverrides, - in PendingIntent downloadedIntent); - - /** - * Get carrier-dependent configuration values. - * - * @param subId the SIM id - */ - Bundle getCarrierConfigValues(int subId); - - /** - * Import a text message into system's SMS store - * - * @param callingPkg the calling app's package name - * @param address the destination address of the message - * @param type the type of the message - * @param text the message text - * @param timestampMillis the message timestamp in milliseconds - * @param seen if the message is seen - * @param read if the message is read - * @return the message URI, null if failed - */ - Uri importTextMessage(String callingPkg, String address, int type, String text, - long timestampMillis, boolean seen, boolean read); - - /** - * Import a multimedia message into system's MMS store - * - * @param callingPkg the package name of the calling app - * @param contentUri the content uri from which to read PDU of the message to import - * @param messageId the optional message id - * @param timestampSecs the message timestamp in seconds - * @param seen if the message is seen - * @param read if the message is read - * @return the message URI, null if failed - */ - Uri importMultimediaMessage(String callingPkg, in Uri contentUri, String messageId, - long timestampSecs, boolean seen, boolean read); - - /** - * Delete a system stored SMS or MMS message - * - * @param callingPkg the package name of the calling app - * @param messageUri the URI of the stored message - * @return true if deletion is successful, false otherwise - */ - boolean deleteStoredMessage(String callingPkg, in Uri messageUri); - - /** - * Delete a system stored SMS or MMS thread - * - * @param callingPkg the package name of the calling app - * @param conversationId the ID of the message conversation - * @return true if deletion is successful, false otherwise - */ - boolean deleteStoredConversation(String callingPkg, long conversationId); - - /** - * Update the status properties of a system stored SMS or MMS message, e.g. - * the read status of a message, etc. - * - * @param callingPkg the package name of the calling app - * @param messageUri the URI of the stored message - * @param statusValues a list of status properties in key-value pairs to update - * @return true if deletion is successful, false otherwise - */ - boolean updateStoredMessageStatus(String callingPkg, in Uri messageUri, - in ContentValues statusValues); - - /** - * Archive or unarchive a stored conversation - * - * @param callingPkg the package name of the calling app - * @param conversationId the ID of the message conversation - * @param archived true to archive the conversation, false otherwise - * @return true if update is successful, false otherwise - */ - boolean archiveStoredConversation(String callingPkg, long conversationId, boolean archived); - - /** - * Add a text message draft to system SMS store - * - * @param callingPkg the package name of the calling app - * @param address the destination address of message - * @param text the body of the message to send - * @return the URI of the stored draft message - */ - Uri addTextMessageDraft(String callingPkg, String address, String text); - - /** - * Add a multimedia message draft to system MMS store - * - * @param callingPkg the package name of the calling app - * @param contentUri the content Uri from which to read PDU data of the draft MMS - * @return the URI of the stored draft message - */ - Uri addMultimediaMessageDraft(String callingPkg, in Uri contentUri); - - /** - * Send a system stored MMS message - * - * This is used for sending a previously sent, but failed-to-send, message or - * for sending a text message that has been stored as a draft. - * - * @param subId the SIM id - * @param callingPkg the package name of the calling app - * @param messageUri the URI of the stored message - * @param configOverrides the carrier-specific messaging configuration values to override for - * sending the message. See {@link android.telephony.SmsManager} for the value names and types. - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed - */ - void sendStoredMessage(int subId, String callingPkg, in Uri messageUri, - in Bundle configOverrides, in PendingIntent sentIntent); - - /** - * Turns on/off the flag to automatically write sent/received SMS/MMS messages into system - * - * When this flag is on, all SMS/MMS sent/received are stored by system automatically - * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system - * automatically - * - * This flag can only be changed by default SMS apps - * - * @param callingPkg the name of the calling app package - * @param enabled Whether to enable message auto persisting - */ - void setAutoPersisting(String callingPkg, boolean enabled); - - /** - * Get the value of the flag to automatically write sent/received SMS/MMS messages into system - * - * When this flag is on, all SMS/MMS sent/received are stored by system automatically - * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system - * automatically - * - * @return the current value of the auto persist flag - */ - boolean getAutoPersisting(); -} diff --git a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl b/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl deleted file mode 100644 index 493b1ff6aba7..000000000000 --- a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -oneway interface IOnSubscriptionsChangedListener { - void onSubscriptionsChanged(); -} - diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl deleted file mode 100644 index 90019eef62fd..000000000000 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.os.Bundle; -import android.telephony.CallAttributes; -import android.telephony.CellInfo; -import android.telephony.DataConnectionRealTimeInfo; -import android.telephony.PhoneCapability; -import android.telephony.PhysicalChannelConfig; -import android.telephony.PreciseCallState; -import android.telephony.PreciseDataConnectionState; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.emergency.EmergencyNumber; -import android.telephony.ims.ImsReasonInfo; - -oneway interface IPhoneStateListener { - void onServiceStateChanged(in ServiceState serviceState); - void onSignalStrengthChanged(int asu); - void onMessageWaitingIndicatorChanged(boolean mwi); - void onCallForwardingIndicatorChanged(boolean cfi); - - // we use bundle here instead of CellLocation so it can get the right subclass - void onCellLocationChanged(in Bundle location); - void onCallStateChanged(int state, String incomingNumber); - void onDataConnectionStateChanged(int state, int networkType); - void onDataActivity(int direction); - void onSignalStrengthsChanged(in SignalStrength signalStrength); - void onPhysicalChannelConfigurationChanged(in List<PhysicalChannelConfig> configs); - void onOtaspChanged(in int otaspMode); - void onCellInfoChanged(in List<CellInfo> cellInfo); - void onPreciseCallStateChanged(in PreciseCallState callState); - void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState); - void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo); - void onSrvccStateChanged(in int state); - void onVoiceActivationStateChanged(int activationState); - void onDataActivationStateChanged(int activationState); - void onOemHookRawEvent(in byte[] rawData); - void onCarrierNetworkChange(in boolean active); - void onUserMobileDataStateChanged(in boolean enabled); - void onPhoneCapabilityChanged(in PhoneCapability capability); - void onActiveDataSubIdChanged(in int subId); - void onRadioPowerStateChanged(in int state); - void onCallAttributesChanged(in CallAttributes callAttributes); - void onEmergencyNumberListChanged(in Map emergencyNumberList); - void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber); - void onOutgoingEmergencySms(in EmergencyNumber sentEmergencyNumber); - void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause); - void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo); -} - diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl index 21570a6ef708..6289c0eadc41 100644 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ b/telephony/java/com/android/internal/telephony/ISms.aidl @@ -19,7 +19,6 @@ package com.android.internal.telephony; import android.app.PendingIntent; import android.net.Uri; import android.os.Bundle; -import android.telephony.IFinancialSmsCallback; import com.android.internal.telephony.SmsRawData; /** @@ -570,17 +569,6 @@ interface ISms { int subId, String callingPkg, String prefixes, in PendingIntent intent); /** - * Get sms inbox messages for the calling financial app. - * - * @param subId the SIM id. - * @param callingPkg the package name of the calling app. - * @param params parameters to filter the sms messages. - * @param callback the callback interface to deliver the result. - */ - void getSmsMessagesForFinancialApp( - int subId, String callingPkg, in Bundle params, in IFinancialSmsCallback callback); - - /** * Get the capacity count of sms on Icc card. * * @param subId for subId which getSmsCapacityOnIcc is queried. diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java index 6a717d71572f..b7ec9fcef11a 100644 --- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java +++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java @@ -19,7 +19,6 @@ package com.android.internal.telephony; import android.app.PendingIntent; import android.net.Uri; import android.os.Bundle; -import android.telephony.IFinancialSmsCallback; import java.util.List; @@ -198,12 +197,6 @@ public class ISmsImplBase extends ISms.Stub { } @Override - public void getSmsMessagesForFinancialApp( - int subId, String callingPkg, Bundle params, IFinancialSmsCallback callback) { - throw new UnsupportedOperationException(); - } - - @Override public int getSmsCapacityOnIccForSubscriber(int subId) { throw new UnsupportedOperationException(); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 866e936a1211..f79a5c654a63 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -302,7 +302,7 @@ interface ITelephony { * operator's MCC (Mobile Country Code). * @see android.telephony.TelephonyManager#getNetworkCountryIso */ - String getNetworkCountryIsoForPhone(int phoneId); + String getNetworkCountryIsoForPhone(int phoneId, String callingPkg); /** * Returns the neighboring cell information of the device. @@ -1612,6 +1612,18 @@ interface ITelephony { String[] getForbiddenPlmns(int subId, int appType, String callingPackage); /** + * Set the forbidden PLMN list from the givven app type (ex APPTYPE_USIM) on a particular + * subscription. + * + * @param subId subId the id of the subscription + * @param appType appType the uicc app type, must be USIM or SIM. + * @param fplmns plmns the Forbiden plmns list that needed to be written to the SIM. + * @param content callingPackage the op Package name. + * @return number of fplmns that is successfully written to the SIM + */ + int setForbiddenPlmns(int subId, int appType, in List<String> fplmns, String callingPackage); + + /** * Check if phone is in emergency callback mode * @return true if phone is in emergency callback mode * @param subId the subscription ID that this action applies to. @@ -1766,21 +1778,6 @@ interface ITelephony { boolean isInEmergencySmsMode(); /** - * Get a list of SMS apps on a user. - */ - String[] getSmsApps(int userId); - - /** - * Get the default SMS app on a given user. - */ - String getDefaultSmsApp(int userId); - - /** - * Set the default SMS app to a given package on a given user. - */ - void setDefaultSmsApp(int userId, String packageName); - - /** * Return the modem radio power state for slot index. * */ @@ -2051,4 +2048,9 @@ interface ITelephony { * data might be disabled on non-default data subscription but explicitly turned on by settings. */ boolean isDataAllowedInVoiceCall(int subId); + + /** + * Command line command to enable or disable handling of CEP data for test purposes. + */ + oneway void setCepEnabled(boolean isCepEnabled); } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl deleted file mode 100644 index 98fee83d83a9..000000000000 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.content.Intent; -import android.net.LinkProperties; -import android.net.NetworkCapabilities; -import android.os.Bundle; -import android.telephony.CallQuality; -import android.telephony.CellInfo; -import android.telephony.ims.ImsReasonInfo; -import android.telephony.PhoneCapability; -import android.telephony.PhysicalChannelConfig; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.emergency.EmergencyNumber; -import com.android.internal.telephony.IPhoneStateListener; -import com.android.internal.telephony.IOnSubscriptionsChangedListener; - -interface ITelephonyRegistry { - void addOnSubscriptionsChangedListener(String pkg, - IOnSubscriptionsChangedListener callback); - void addOnOpportunisticSubscriptionsChangedListener(String pkg, - IOnSubscriptionsChangedListener callback); - void removeOnSubscriptionsChangedListener(String pkg, - IOnSubscriptionsChangedListener callback); - @UnsupportedAppUsage - void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); - void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events, - boolean notifyNow); - @UnsupportedAppUsage - void notifyCallState(int state, String incomingNumber); - void notifyCallStateForPhoneId(in int phoneId, in int subId, int state, String incomingNumber); - void notifyServiceStateForPhoneId(in int phoneId, in int subId, in ServiceState state); - void notifySignalStrengthForPhoneId(in int phoneId, in int subId, - in SignalStrength signalStrength); - void notifyMessageWaitingChangedForPhoneId(in int phoneId, in int subId, in boolean mwi); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyCallForwardingChanged(boolean cfi); - void notifyCallForwardingChangedForSubscriber(in int subId, boolean cfi); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyDataActivity(int state); - void notifyDataActivityForSubscriber(in int subId, int state); - void notifyDataConnection(int state, boolean isDataConnectivityPossible, - String apn, String apnType, in LinkProperties linkProperties, - in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); - void notifyDataConnectionForSubscriber(int phoneId, int subId, int state, - boolean isDataConnectivityPossible, - String apn, String apnType, in LinkProperties linkProperties, - in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); - @UnsupportedAppUsage - void notifyDataConnectionFailed(String apnType); - void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyCellLocation(in Bundle cellLocation); - void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyOtaspChanged(in int subId, in int otaspMode); - @UnsupportedAppUsage - void notifyCellInfo(in List<CellInfo> cellInfo); - void notifyPhysicalChannelConfigurationForSubscriber(in int phoneId, in int subId, - in List<PhysicalChannelConfig> configs); - void notifyPreciseCallState(int phoneId, int subId, int ringingCallState, - int foregroundCallState, int backgroundCallState); - void notifyDisconnectCause(int phoneId, int subId, int disconnectCause, - int preciseDisconnectCause); - void notifyPreciseDataConnectionFailed(int phoneId, int subId, String apnType, String apn, - int failCause); - void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); - void notifySrvccStateChanged(in int subId, in int lteState); - void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, - int activationState, int activationType); - void notifyOemHookRawEventForSubscriber(in int phoneId, in int subId, in byte[] rawData); - void notifySubscriptionInfoChanged(); - void notifyOpportunisticSubscriptionInfoChanged(); - void notifyCarrierNetworkChange(in boolean active); - void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state); - void notifyPhoneCapabilityChanged(in PhoneCapability capability); - void notifyActiveDataSubIdChanged(int activeDataSubId); - void notifyRadioPowerStateChanged(in int phoneId, in int subId, in int state); - void notifyEmergencyNumberList(in int phoneId, in int subId); - void notifyCallQualityChanged(in CallQuality callQuality, int phoneId, int subId, - int callNetworkType); - void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo); -} diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index ee1a4766bf68..c19ae7b3916a 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -89,10 +89,6 @@ public class PhoneConstants { @UnsupportedAppUsage public static final int PRESENTATION_PAYPHONE = 4; // show pay phone info - // Sim activation type - public static final int SIM_ACTIVATION_TYPE_VOICE = 0; - public static final int SIM_ACTIVATION_TYPE_DATA = 1; - public static final String PHONE_NAME_KEY = "phoneName"; public static final String DATA_NETWORK_TYPE_KEY = "networkType"; public static final String DATA_FAILURE_CAUSE_KEY = "failCause"; @@ -174,7 +170,7 @@ public class PhoneConstants { public static final int RIL_CARD_MAX_APPS = 8; - public static final int DEFAULT_CARD_INDEX = 0; + public static final int DEFAULT_SLOT_INDEX = 0; public static final int MAX_PHONE_COUNT_SINGLE_SIM = 1; diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java deleted file mode 100644 index f10398f09603..000000000000 --- a/telephony/java/com/android/internal/telephony/SmsApplication.java +++ /dev/null @@ -1,1081 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.Manifest.permission; -import android.annotation.Nullable; -import android.app.AppOpsManager; -import android.app.role.RoleManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Binder; -import android.os.Debug; -import android.os.Process; -import android.os.UserHandle; -import android.provider.Telephony; -import android.provider.Telephony.Sms.Intents; -import android.telephony.Rlog; -import android.telephony.SmsManager; -import android.telephony.TelephonyManager; -import android.util.Log; - -import com.android.internal.content.PackageMonitor; -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Consumer; - -/** - * Class for managing the primary application that we will deliver SMS/MMS messages to - * - * {@hide} - */ -public final class SmsApplication { - static final String LOG_TAG = "SmsApplication"; - private static final String PHONE_PACKAGE_NAME = "com.android.phone"; - private static final String BLUETOOTH_PACKAGE_NAME = "com.android.bluetooth"; - private static final String MMS_SERVICE_PACKAGE_NAME = "com.android.mms.service"; - private static final String TELEPHONY_PROVIDER_PACKAGE_NAME = "com.android.providers.telephony"; - - private static final String SCHEME_SMS = "sms"; - private static final String SCHEME_SMSTO = "smsto"; - private static final String SCHEME_MMS = "mms"; - private static final String SCHEME_MMSTO = "mmsto"; - private static final boolean DEBUG = false; - private static final boolean DEBUG_MULTIUSER = false; - - private static final int[] DEFAULT_APP_EXCLUSIVE_APPOPS = { - AppOpsManager.OP_READ_SMS, - AppOpsManager.OP_WRITE_SMS, - AppOpsManager.OP_RECEIVE_SMS, - AppOpsManager.OP_RECEIVE_WAP_PUSH, - AppOpsManager.OP_SEND_SMS, - AppOpsManager.OP_READ_CELL_BROADCASTS - }; - - private static SmsPackageMonitor sSmsPackageMonitor = null; - - public static class SmsApplicationData { - /** - * Name of this SMS app for display. - */ - @UnsupportedAppUsage - private String mApplicationName; - - /** - * Package name for this SMS app. - */ - public String mPackageName; - - /** - * The class name of the SMS_DELIVER_ACTION receiver in this app. - */ - private String mSmsReceiverClass; - - /** - * The class name of the WAP_PUSH_DELIVER_ACTION receiver in this app. - */ - private String mMmsReceiverClass; - - /** - * The class name of the ACTION_RESPOND_VIA_MESSAGE intent in this app. - */ - private String mRespondViaMessageClass; - - /** - * The class name of the ACTION_SENDTO intent in this app. - */ - private String mSendToClass; - - /** - * The class name of the ACTION_DEFAULT_SMS_PACKAGE_CHANGED receiver in this app. - */ - private String mSmsAppChangedReceiverClass; - - /** - * The class name of the ACTION_EXTERNAL_PROVIDER_CHANGE receiver in this app. - */ - private String mProviderChangedReceiverClass; - - /** - * The class name of the SIM_FULL_ACTION receiver in this app. - */ - private String mSimFullReceiverClass; - - /** - * The user-id for this application - */ - private int mUid; - - /** - * Returns true if this SmsApplicationData is complete (all intents handled). - * @return - */ - public boolean isComplete() { - return (mSmsReceiverClass != null && mMmsReceiverClass != null - && mRespondViaMessageClass != null && mSendToClass != null); - } - - public SmsApplicationData(String packageName, int uid) { - mPackageName = packageName; - mUid = uid; - } - - public String getApplicationName(Context context) { - if (mApplicationName == null) { - PackageManager pm = context.getPackageManager(); - ApplicationInfo appInfo; - try { - appInfo = pm.getApplicationInfoAsUser(mPackageName, 0, - UserHandle.getUserHandleForUid(mUid)); - } catch (NameNotFoundException e) { - return null; - } - if (appInfo != null) { - CharSequence label = pm.getApplicationLabel(appInfo); - mApplicationName = (label == null) ? null : label.toString(); - } - } - return mApplicationName; - } - - @Override - public String toString() { - return " mPackageName: " + mPackageName - + " mSmsReceiverClass: " + mSmsReceiverClass - + " mMmsReceiverClass: " + mMmsReceiverClass - + " mRespondViaMessageClass: " + mRespondViaMessageClass - + " mSendToClass: " + mSendToClass - + " mSmsAppChangedClass: " + mSmsAppChangedReceiverClass - + " mProviderChangedReceiverClass: " + mProviderChangedReceiverClass - + " mSimFullReceiverClass: " + mSimFullReceiverClass - + " mUid: " + mUid; - } - } - - /** - * Returns the userId of the Context object, if called from a system app, - * otherwise it returns the caller's userId - * @param context The context object passed in by the caller. - * @return - */ - private static int getIncomingUserId(Context context) { - int contextUserId = UserHandle.myUserId(); - final int callingUid = Binder.getCallingUid(); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getIncomingUserHandle caller=" + callingUid + ", myuid=" - + android.os.Process.myUid() + "\n\t" + Debug.getCallers(4)); - } - if (UserHandle.getAppId(callingUid) - < android.os.Process.FIRST_APPLICATION_UID) { - return contextUserId; - } else { - return UserHandle.getUserId(callingUid); - } - } - - /** - * Returns the list of available SMS apps defined as apps that are registered for both the - * SMS_RECEIVED_ACTION (SMS) and WAP_PUSH_RECEIVED_ACTION (MMS) broadcasts (and their broadcast - * receivers are enabled) - * - * Requirements to be an SMS application: - * Implement SMS_DELIVER_ACTION broadcast receiver. - * Require BROADCAST_SMS permission. - * - * Implement WAP_PUSH_DELIVER_ACTION broadcast receiver. - * Require BROADCAST_WAP_PUSH permission. - * - * Implement RESPOND_VIA_MESSAGE intent. - * Support smsto Uri scheme. - * Require SEND_RESPOND_VIA_MESSAGE permission. - * - * Implement ACTION_SENDTO intent. - * Support smsto Uri scheme. - */ - @UnsupportedAppUsage - public static Collection<SmsApplicationData> getApplicationCollection(Context context) { - return getApplicationCollectionAsUser(context, getIncomingUserId(context)); - } - - /** - * Same as {@link #getApplicationCollection} but it takes a target user ID. - */ - public static Collection<SmsApplicationData> getApplicationCollectionAsUser(Context context, - int userId) { - final long token = Binder.clearCallingIdentity(); - try { - return getApplicationCollectionInternal(context, userId); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - private static Collection<SmsApplicationData> getApplicationCollectionInternal( - Context context, int userId) { - PackageManager packageManager = context.getPackageManager(); - - // Get the list of apps registered for SMS - Intent intent = new Intent(Intents.SMS_DELIVER_ACTION); - if (DEBUG) { - intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); - } - List<ResolveInfo> smsReceivers = packageManager.queryBroadcastReceiversAsUser(intent, - PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - userId); - - HashMap<String, SmsApplicationData> receivers = new HashMap<String, SmsApplicationData>(); - - // Add one entry to the map for every sms receiver (ignoring duplicate sms receivers) - for (ResolveInfo resolveInfo : smsReceivers) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - if (activityInfo == null) { - continue; - } - if (!permission.BROADCAST_SMS.equals(activityInfo.permission)) { - continue; - } - final String packageName = activityInfo.packageName; - if (!receivers.containsKey(packageName)) { - final SmsApplicationData smsApplicationData = new SmsApplicationData(packageName, - activityInfo.applicationInfo.uid); - smsApplicationData.mSmsReceiverClass = activityInfo.name; - receivers.put(packageName, smsApplicationData); - } - } - - // Update any existing entries with mms receiver class - intent = new Intent(Intents.WAP_PUSH_DELIVER_ACTION); - intent.setDataAndType(null, "application/vnd.wap.mms-message"); - List<ResolveInfo> mmsReceivers = packageManager.queryBroadcastReceiversAsUser(intent, - PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - userId); - for (ResolveInfo resolveInfo : mmsReceivers) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - if (activityInfo == null) { - continue; - } - if (!permission.BROADCAST_WAP_PUSH.equals(activityInfo.permission)) { - continue; - } - final String packageName = activityInfo.packageName; - final SmsApplicationData smsApplicationData = receivers.get(packageName); - if (smsApplicationData != null) { - smsApplicationData.mMmsReceiverClass = activityInfo.name; - } - } - - // Update any existing entries with respond via message intent class. - intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, - Uri.fromParts(SCHEME_SMSTO, "", null)); - List<ResolveInfo> respondServices = packageManager.queryIntentServicesAsUser(intent, - PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - UserHandle.of(userId)); - for (ResolveInfo resolveInfo : respondServices) { - final ServiceInfo serviceInfo = resolveInfo.serviceInfo; - if (serviceInfo == null) { - continue; - } - if (!permission.SEND_RESPOND_VIA_MESSAGE.equals(serviceInfo.permission)) { - continue; - } - final String packageName = serviceInfo.packageName; - final SmsApplicationData smsApplicationData = receivers.get(packageName); - if (smsApplicationData != null) { - smsApplicationData.mRespondViaMessageClass = serviceInfo.name; - } - } - - // Update any existing entries with supports send to. - intent = new Intent(Intent.ACTION_SENDTO, - Uri.fromParts(SCHEME_SMSTO, "", null)); - List<ResolveInfo> sendToActivities = packageManager.queryIntentActivitiesAsUser(intent, - PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, - userId); - for (ResolveInfo resolveInfo : sendToActivities) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - if (activityInfo == null) { - continue; - } - final String packageName = activityInfo.packageName; - final SmsApplicationData smsApplicationData = receivers.get(packageName); - if (smsApplicationData != null) { - smsApplicationData.mSendToClass = activityInfo.name; - } - } - - // Update any existing entries with the default sms changed handler. - intent = new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED); - List<ResolveInfo> smsAppChangedReceivers = - packageManager.queryBroadcastReceiversAsUser(intent, - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplicationCollectionInternal smsAppChangedActivities=" + - smsAppChangedReceivers); - } - for (ResolveInfo resolveInfo : smsAppChangedReceivers) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - if (activityInfo == null) { - continue; - } - final String packageName = activityInfo.packageName; - final SmsApplicationData smsApplicationData = receivers.get(packageName); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplicationCollectionInternal packageName=" + - packageName + " smsApplicationData: " + smsApplicationData + - " activityInfo.name: " + activityInfo.name); - } - if (smsApplicationData != null) { - smsApplicationData.mSmsAppChangedReceiverClass = activityInfo.name; - } - } - - // Update any existing entries with the external provider changed handler. - intent = new Intent(Telephony.Sms.Intents.ACTION_EXTERNAL_PROVIDER_CHANGE); - List<ResolveInfo> providerChangedReceivers = - packageManager.queryBroadcastReceiversAsUser(intent, - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplicationCollectionInternal providerChangedActivities=" + - providerChangedReceivers); - } - for (ResolveInfo resolveInfo : providerChangedReceivers) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - if (activityInfo == null) { - continue; - } - final String packageName = activityInfo.packageName; - final SmsApplicationData smsApplicationData = receivers.get(packageName); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplicationCollectionInternal packageName=" + - packageName + " smsApplicationData: " + smsApplicationData + - " activityInfo.name: " + activityInfo.name); - } - if (smsApplicationData != null) { - smsApplicationData.mProviderChangedReceiverClass = activityInfo.name; - } - } - - // Update any existing entries with the sim full handler. - intent = new Intent(Intents.SIM_FULL_ACTION); - List<ResolveInfo> simFullReceivers = - packageManager.queryBroadcastReceiversAsUser(intent, - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplicationCollectionInternal simFullReceivers=" - + simFullReceivers); - } - for (ResolveInfo resolveInfo : simFullReceivers) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - if (activityInfo == null) { - continue; - } - final String packageName = activityInfo.packageName; - final SmsApplicationData smsApplicationData = receivers.get(packageName); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplicationCollectionInternal packageName=" - + packageName + " smsApplicationData: " + smsApplicationData - + " activityInfo.name: " + activityInfo.name); - } - if (smsApplicationData != null) { - smsApplicationData.mSimFullReceiverClass = activityInfo.name; - } - } - - // Remove any entries for which we did not find all required intents. - for (ResolveInfo resolveInfo : smsReceivers) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - if (activityInfo == null) { - continue; - } - final String packageName = activityInfo.packageName; - final SmsApplicationData smsApplicationData = receivers.get(packageName); - if (smsApplicationData != null) { - if (!smsApplicationData.isComplete()) { - receivers.remove(packageName); - } - } - } - return receivers.values(); - } - - /** - * Checks to see if we have a valid installed SMS application for the specified package name - * @return Data for the specified package name or null if there isn't one - */ - public static SmsApplicationData getApplicationForPackage( - Collection<SmsApplicationData> applications, String packageName) { - if (packageName == null) { - return null; - } - // Is there an entry in the application list for the specified package? - for (SmsApplicationData application : applications) { - if (application.mPackageName.contentEquals(packageName)) { - return application; - } - } - return null; - } - - /** - * Get the application we will use for delivering SMS/MMS messages. - * - * We return the preferred sms application with the following order of preference: - * (1) User selected SMS app (if selected, and if still valid) - * (2) Android Messaging (if installed) - * (3) The currently configured highest priority broadcast receiver - * (4) Null - */ - private static SmsApplicationData getApplication(Context context, boolean updateIfNeeded, - int userId) { - TelephonyManager tm = (TelephonyManager) - context.getSystemService(Context.TELEPHONY_SERVICE); - RoleManager roleManager = (RoleManager) context.getSystemService(Context.ROLE_SERVICE); - // (b/134400042) RoleManager might be null in unit tests running older mockito versions - // that do not support mocking final classes. - if (!tm.isSmsCapable() && (roleManager == null || !roleManager.isRoleAvailable( - RoleManager.ROLE_SMS))) { - // No phone, no SMS - return null; - } - - Collection<SmsApplicationData> applications = getApplicationCollectionInternal(context, - userId); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplication userId=" + userId); - } - // Determine which application receives the broadcast - String defaultApplication = getDefaultSmsPackage(context, userId); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplication defaultApp=" + defaultApplication); - } - - SmsApplicationData applicationData = null; - if (defaultApplication != null) { - applicationData = getApplicationForPackage(applications, defaultApplication); - } - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplication appData=" + applicationData); - } - - // If we found a package, make sure AppOps permissions are set up correctly - if (applicationData != null) { - // We can only call checkOp if we are privileged (updateIfNeeded) or if the app we - // are checking is for our current uid. Doing this check from the unprivileged current - // SMS app allows us to tell the current SMS app that it is not in a good state and - // needs to ask to be the current SMS app again to work properly. - if (updateIfNeeded || applicationData.mUid == android.os.Process.myUid()) { - // Verify that the SMS app has permissions - boolean appOpsFixed = - tryFixExclusiveSmsAppops(context, applicationData, updateIfNeeded); - if (!appOpsFixed) { - // We can not return a package if permissions are not set up correctly - applicationData = null; - } - } - - // We can only verify the phone and BT app's permissions from a privileged caller - if (applicationData != null && updateIfNeeded) { - // Ensure this component is still configured as the preferred activity. Usually the - // current SMS app will already be the preferred activity - but checking whether or - // not this is true is just as expensive as reconfiguring the preferred activity so - // we just reconfigure every time. - defaultSmsAppChanged(context); - } - } - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "getApplication returning appData=" + applicationData); - } - return applicationData; - } - - private static String getDefaultSmsPackage(Context context, int userId) { - return context.getSystemService(RoleManager.class).getDefaultSmsPackage(userId); - } - - /** - * Grants various permissions and appops on sms app change - */ - private static void defaultSmsAppChanged(Context context) { - PackageManager packageManager = context.getPackageManager(); - AppOpsManager appOps = context.getSystemService(AppOpsManager.class); - - // Assign permission to special system apps - assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, - PHONE_PACKAGE_NAME); - assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, - BLUETOOTH_PACKAGE_NAME); - assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, - MMS_SERVICE_PACKAGE_NAME); - assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, - TELEPHONY_PROVIDER_PACKAGE_NAME); - - // Give AppOps permission to UID 1001 which contains multiple - // apps, all of them should be able to write to telephony provider. - // This is to allow the proxy package permission check in telephony provider - // to pass. - for (int appop : DEFAULT_APP_EXCLUSIVE_APPOPS) { - appOps.setUidMode(appop, Process.PHONE_UID, AppOpsManager.MODE_ALLOWED); - } - } - - private static boolean tryFixExclusiveSmsAppops(Context context, - SmsApplicationData applicationData, boolean updateIfNeeded) { - AppOpsManager appOps = context.getSystemService(AppOpsManager.class); - for (int appOp : DEFAULT_APP_EXCLUSIVE_APPOPS) { - int mode = appOps.checkOp(appOp, applicationData.mUid, - applicationData.mPackageName); - if (mode != AppOpsManager.MODE_ALLOWED) { - Rlog.e(LOG_TAG, applicationData.mPackageName + " lost " - + AppOpsManager.modeToName(appOp) + ": " - + (updateIfNeeded ? " (fixing)" : " (no permission to fix)")); - if (updateIfNeeded) { - appOps.setUidMode(appOp, applicationData.mUid, AppOpsManager.MODE_ALLOWED); - } else { - return false; - } - } - } - return true; - } - - /** - * Sets the specified package as the default SMS/MMS application. The caller of this method - * needs to have permission to set AppOps and write to secure settings. - */ - @UnsupportedAppUsage - public static void setDefaultApplication(String packageName, Context context) { - setDefaultApplicationAsUser(packageName, context, getIncomingUserId(context)); - } - - /** - * Same as {@link #setDefaultApplication} but takes a target user id. - */ - public static void setDefaultApplicationAsUser(String packageName, Context context, - int userId) { - TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); - RoleManager roleManager = (RoleManager) context.getSystemService(Context.ROLE_SERVICE); - // (b/134400042) RoleManager might be null in unit tests running older mockito versions - // that do not support mocking final classes. - if (!tm.isSmsCapable() && (roleManager == null || !roleManager.isRoleAvailable( - RoleManager.ROLE_SMS))) { - // No phone, no SMS - return; - } - - final long token = Binder.clearCallingIdentity(); - try { - setDefaultApplicationInternal(packageName, context, userId); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - private static void setDefaultApplicationInternal(String packageName, Context context, - int userId) { - final UserHandle userHandle = UserHandle.of(userId); - - // Get old package name - String oldPackageName = getDefaultSmsPackage(context, userId); - - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "setDefaultApplicationInternal old=" + oldPackageName + - " new=" + packageName); - } - - if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) { - // No change - return; - } - - // We only make the change if the new package is valid - PackageManager packageManager = context.getPackageManager(); - Collection<SmsApplicationData> applications = getApplicationCollectionInternal( - context, userId); - SmsApplicationData oldAppData = oldPackageName != null ? - getApplicationForPackage(applications, oldPackageName) : null; - SmsApplicationData applicationData = getApplicationForPackage(applications, packageName); - if (applicationData != null) { - // Ignore relevant appops for the previously configured default SMS app. - AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); - if (oldPackageName != null) { - try { - int uid = packageManager.getPackageInfoAsUser( - oldPackageName, 0, userId).applicationInfo.uid; - setExclusiveAppops(oldPackageName, appOps, uid, AppOpsManager.MODE_DEFAULT); - } catch (NameNotFoundException e) { - Rlog.w(LOG_TAG, "Old SMS package not found: " + oldPackageName); - } - } - - // Update the setting. - CompletableFuture<Void> future = new CompletableFuture<>(); - Consumer<Boolean> callback = successful -> { - if (successful) { - future.complete(null); - } else { - future.completeExceptionally(new RuntimeException()); - } - }; - context.getSystemService(RoleManager.class).addRoleHolderAsUser( - RoleManager.ROLE_SMS, applicationData.mPackageName, 0, UserHandle.of(userId), - AsyncTask.THREAD_POOL_EXECUTOR, callback); - try { - future.get(5, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - Log.e(LOG_TAG, "Exception while adding sms role holder " + applicationData, e); - return; - } - - defaultSmsAppChanged(context); - } - } - - /** - * Sends broadcasts on sms app change: - * {@link Intent#ACTION_DEFAULT_SMS_PACKAGE_CHANGED} - * {@link Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL} - */ - public static void broadcastSmsAppChange(Context context, - UserHandle userHandle, @Nullable String oldPackage, @Nullable String newPackage) { - Collection<SmsApplicationData> apps = getApplicationCollection(context); - - broadcastSmsAppChange(context, userHandle, - getApplicationForPackage(apps, oldPackage), - getApplicationForPackage(apps, newPackage)); - } - - private static void broadcastSmsAppChange(Context context, UserHandle userHandle, - @Nullable SmsApplicationData oldAppData, - @Nullable SmsApplicationData applicationData) { - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "setDefaultApplicationInternal oldAppData=" + oldAppData); - } - if (oldAppData != null && oldAppData.mSmsAppChangedReceiverClass != null) { - // Notify the old sms app that it's no longer the default - final Intent oldAppIntent = - new Intent(Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED); - final ComponentName component = new ComponentName(oldAppData.mPackageName, - oldAppData.mSmsAppChangedReceiverClass); - oldAppIntent.setComponent(component); - oldAppIntent.putExtra(Intents.EXTRA_IS_DEFAULT_SMS_APP, false); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "setDefaultApplicationInternal old=" + oldAppData.mPackageName); - } - context.sendBroadcastAsUser(oldAppIntent, userHandle); - } - // Notify the new sms app that it's now the default (if the new sms app has a receiver - // to handle the changed default sms intent). - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "setDefaultApplicationInternal new applicationData=" + - applicationData); - } - if (applicationData != null && applicationData.mSmsAppChangedReceiverClass != null) { - final Intent intent = - new Intent(Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED); - final ComponentName component = new ComponentName(applicationData.mPackageName, - applicationData.mSmsAppChangedReceiverClass); - intent.setComponent(component); - intent.putExtra(Intents.EXTRA_IS_DEFAULT_SMS_APP, true); - if (DEBUG_MULTIUSER) { - Log.i(LOG_TAG, "setDefaultApplicationInternal new=" + applicationData.mPackageName); - } - context.sendBroadcastAsUser(intent, userHandle); - } - - // Send an implicit broadcast for the system server. - // (or anyone with MONITOR_DEFAULT_SMS_PACKAGE, really.) - final Intent intent = - new Intent(Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL); - context.sendBroadcastAsUser(intent, userHandle, - permission.MONITOR_DEFAULT_SMS_PACKAGE); - - if (applicationData != null) { - MetricsLogger.action(context, MetricsEvent.ACTION_DEFAULT_SMS_APP_CHANGED, - applicationData.mPackageName); - } - } - - /** - * Assign WRITE_SMS AppOps permission to some special system apps. - * - * @param context The context - * @param packageManager The package manager instance - * @param appOps The AppOps manager instance - * @param packageName The package name of the system app - */ - private static void assignExclusiveSmsPermissionsToSystemApp(Context context, - PackageManager packageManager, AppOpsManager appOps, String packageName) { - // First check package signature matches the caller's package signature. - // Since this class is only used internally by the system, this check makes sure - // the package signature matches system signature. - final int result = packageManager.checkSignatures(context.getPackageName(), packageName); - if (result != PackageManager.SIGNATURE_MATCH) { - Rlog.e(LOG_TAG, packageName + " does not have system signature"); - return; - } - try { - PackageInfo info = packageManager.getPackageInfo(packageName, 0); - int mode = appOps.checkOp(AppOpsManager.OP_WRITE_SMS, info.applicationInfo.uid, - packageName); - if (mode != AppOpsManager.MODE_ALLOWED) { - Rlog.w(LOG_TAG, packageName + " does not have OP_WRITE_SMS: (fixing)"); - setExclusiveAppops(packageName, appOps, info.applicationInfo.uid, - AppOpsManager.MODE_ALLOWED); - } - } catch (NameNotFoundException e) { - // No whitelisted system app on this device - Rlog.e(LOG_TAG, "Package not found: " + packageName); - } - - } - - private static void setExclusiveAppops(String pkg, AppOpsManager appOpsManager, int uid, - int mode) { - for (int appop : DEFAULT_APP_EXCLUSIVE_APPOPS) { - appOpsManager.setUidMode(appop, uid, mode); - } - } - - /** - * Tracks package changes and ensures that the default SMS app is always configured to be the - * preferred activity for SENDTO sms/mms intents. - */ - private static final class SmsPackageMonitor extends PackageMonitor { - final Context mContext; - - public SmsPackageMonitor(Context context) { - super(); - mContext = context; - } - - @Override - public void onPackageDisappeared(String packageName, int reason) { - onPackageChanged(); - } - - @Override - public void onPackageAppeared(String packageName, int reason) { - onPackageChanged(); - } - - @Override - public void onPackageModified(String packageName) { - onPackageChanged(); - } - - private void onPackageChanged() { - PackageManager packageManager = mContext.getPackageManager(); - Context userContext = mContext; - final int userId = getSendingUserId(); - if (userId != UserHandle.USER_SYSTEM) { - try { - userContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0, - UserHandle.of(userId)); - } catch (NameNotFoundException nnfe) { - if (DEBUG_MULTIUSER) { - Log.w(LOG_TAG, "Unable to create package context for user " + userId); - } - } - } - // Ensure this component is still configured as the preferred activity - ComponentName componentName = getDefaultSendToApplication(userContext, true); - if (componentName != null) { - configurePreferredActivity(packageManager, componentName, userId); - } - } - } - - public static void initSmsPackageMonitor(Context context) { - sSmsPackageMonitor = new SmsPackageMonitor(context); - sSmsPackageMonitor.register(context, context.getMainLooper(), UserHandle.ALL, false); - } - - @UnsupportedAppUsage - private static void configurePreferredActivity(PackageManager packageManager, - ComponentName componentName, int userId) { - // Add the four activity preferences we want to direct to this app. - replacePreferredActivity(packageManager, componentName, userId, SCHEME_SMS); - replacePreferredActivity(packageManager, componentName, userId, SCHEME_SMSTO); - replacePreferredActivity(packageManager, componentName, userId, SCHEME_MMS); - replacePreferredActivity(packageManager, componentName, userId, SCHEME_MMSTO); - } - - /** - * Updates the ACTION_SENDTO activity to the specified component for the specified scheme. - */ - private static void replacePreferredActivity(PackageManager packageManager, - ComponentName componentName, int userId, String scheme) { - // Build the set of existing activities that handle this scheme - Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(scheme, "", null)); - List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivitiesAsUser( - intent, PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_RESOLVED_FILTER, - userId); - - // Build the set of ComponentNames for these activities - final int n = resolveInfoList.size(); - ComponentName[] set = new ComponentName[n]; - for (int i = 0; i < n; i++) { - ResolveInfo info = resolveInfoList.get(i); - set[i] = new ComponentName(info.activityInfo.packageName, info.activityInfo.name); - } - - // Update the preferred SENDTO activity for the specified scheme - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(Intent.ACTION_SENDTO); - intentFilter.addCategory(Intent.CATEGORY_DEFAULT); - intentFilter.addDataScheme(scheme); - packageManager.replacePreferredActivityAsUser(intentFilter, - IntentFilter.MATCH_CATEGORY_SCHEME + IntentFilter.MATCH_ADJUSTMENT_NORMAL, - set, componentName, userId); - } - - /** - * Returns SmsApplicationData for this package if this package is capable of being set as the - * default SMS application. - */ - @UnsupportedAppUsage - public static SmsApplicationData getSmsApplicationData(String packageName, Context context) { - Collection<SmsApplicationData> applications = getApplicationCollection(context); - return getApplicationForPackage(applications, packageName); - } - - /** - * Gets the default SMS application - * @param context context from the calling app - * @param updateIfNeeded update the default app if there is no valid default app configured. - * @return component name of the app and class to deliver SMS messages to - */ - @UnsupportedAppUsage - public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) { - return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserId(context)); - } - - /** - * Gets the default SMS application on a given user - * @param context context from the calling app - * @param updateIfNeeded update the default app if there is no valid default app configured. - * @param userId target user ID. - * @return component name of the app and class to deliver SMS messages to - */ - public static ComponentName getDefaultSmsApplicationAsUser(Context context, - boolean updateIfNeeded, int userId) { - final long token = Binder.clearCallingIdentity(); - try { - ComponentName component = null; - SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); - if (smsApplicationData != null) { - component = new ComponentName(smsApplicationData.mPackageName, - smsApplicationData.mSmsReceiverClass); - } - return component; - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** - * Gets the default MMS application - * @param context context from the calling app - * @param updateIfNeeded update the default app if there is no valid default app configured. - * @return component name of the app and class to deliver MMS messages to - */ - @UnsupportedAppUsage - public static ComponentName getDefaultMmsApplication(Context context, boolean updateIfNeeded) { - int userId = getIncomingUserId(context); - final long token = Binder.clearCallingIdentity(); - try { - ComponentName component = null; - SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); - if (smsApplicationData != null) { - component = new ComponentName(smsApplicationData.mPackageName, - smsApplicationData.mMmsReceiverClass); - } - return component; - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** - * Gets the default Respond Via Message application - * @param context context from the calling app - * @param updateIfNeeded update the default app if there is no valid default app configured. - * @return component name of the app and class to direct Respond Via Message intent to - */ - @UnsupportedAppUsage - public static ComponentName getDefaultRespondViaMessageApplication(Context context, - boolean updateIfNeeded) { - int userId = getIncomingUserId(context); - final long token = Binder.clearCallingIdentity(); - try { - ComponentName component = null; - SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); - if (smsApplicationData != null) { - component = new ComponentName(smsApplicationData.mPackageName, - smsApplicationData.mRespondViaMessageClass); - } - return component; - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** - * Gets the default Send To (smsto) application. - * <p> - * Caller must pass in the correct user context if calling from a singleton service. - * @param context context from the calling app - * @param updateIfNeeded update the default app if there is no valid default app configured. - * @return component name of the app and class to direct SEND_TO (smsto) intent to - */ - public static ComponentName getDefaultSendToApplication(Context context, - boolean updateIfNeeded) { - int userId = getIncomingUserId(context); - final long token = Binder.clearCallingIdentity(); - try { - ComponentName component = null; - SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); - if (smsApplicationData != null) { - component = new ComponentName(smsApplicationData.mPackageName, - smsApplicationData.mSendToClass); - } - return component; - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** - * Gets the default application that handles external changes to the SmsProvider and - * MmsProvider. - * @param context context from the calling app - * @param updateIfNeeded update the default app if there is no valid default app configured. - * @return component name of the app and class to deliver change intents to - */ - public static ComponentName getDefaultExternalTelephonyProviderChangedApplication( - Context context, boolean updateIfNeeded) { - int userId = getIncomingUserId(context); - final long token = Binder.clearCallingIdentity(); - try { - ComponentName component = null; - SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); - if (smsApplicationData != null - && smsApplicationData.mProviderChangedReceiverClass != null) { - component = new ComponentName(smsApplicationData.mPackageName, - smsApplicationData.mProviderChangedReceiverClass); - } - return component; - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** - * Gets the default application that handles sim full event. - * @param context context from the calling app - * @param updateIfNeeded update the default app if there is no valid default app configured. - * @return component name of the app and class to deliver change intents to - */ - public static ComponentName getDefaultSimFullApplication( - Context context, boolean updateIfNeeded) { - int userId = getIncomingUserId(context); - final long token = Binder.clearCallingIdentity(); - try { - ComponentName component = null; - SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded, - userId); - if (smsApplicationData != null - && smsApplicationData.mSimFullReceiverClass != null) { - component = new ComponentName(smsApplicationData.mPackageName, - smsApplicationData.mSimFullReceiverClass); - } - return component; - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** - * Returns whether need to write the SMS message to SMS database for this package. - * <p> - * Caller must pass in the correct user context if calling from a singleton service. - */ - @UnsupportedAppUsage - public static boolean shouldWriteMessageForPackage(String packageName, Context context) { - if (SmsManager.getDefault().getAutoPersisting()) { - return true; - } - return !isDefaultSmsApplication(context, packageName); - } - - /** - * Check if a package is default sms app (or equivalent, like bluetooth) - * - * @param context context from the calling app - * @param packageName the name of the package to be checked - * @return true if the package is default sms app or bluetooth - */ - @UnsupportedAppUsage - public static boolean isDefaultSmsApplication(Context context, String packageName) { - if (packageName == null) { - return false; - } - final String defaultSmsPackage = getDefaultSmsApplicationPackageName(context); - if ((defaultSmsPackage != null && defaultSmsPackage.equals(packageName)) - || BLUETOOTH_PACKAGE_NAME.equals(packageName)) { - return true; - } - return false; - } - - private static String getDefaultSmsApplicationPackageName(Context context) { - final ComponentName component = getDefaultSmsApplication(context, false); - if (component != null) { - return component.getPackageName(); - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index d892e559c899..b357fa43008f 100755 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -878,8 +878,9 @@ public class SmsMessage extends SmsMessageBase { * Parses a broadcast SMS, possibly containing a CMAS alert. * * @param plmn the PLMN for a broadcast SMS + * @param subId */ - public SmsCbMessage parseBroadcastSms(String plmn) { + public SmsCbMessage parseBroadcastSms(String plmn, int subId) { BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory); if (bData == null) { Rlog.w(LOG_TAG, "BearerData.decode() returned null"); @@ -895,7 +896,21 @@ public class SmsMessage extends SmsMessageBase { return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2, SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location, mEnvelope.serviceCategory, bData.getLanguage(), bData.userData.payloadStr, - bData.priority, null, bData.cmasWarningInfo); + bData.priority, null, bData.cmasWarningInfo, subId); + } + + /** + * @return the bearer data byte array + */ + public byte[] getEnvelopeBearerData() { + return mEnvelope.bearerData; + } + + /** + * @return the 16-bit CDMA SCPT service category + */ + public @CdmaSmsCbProgramData.Category int getEnvelopeServiceCategory() { + return mEnvelope.serviceCategory; } /** diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java index 98fa3af5c3c6..38154b8e6024 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java @@ -18,6 +18,7 @@ package com.android.internal.telephony.cdma.sms; import android.annotation.UnsupportedAppUsage; +import android.telephony.cdma.CdmaSmsCbProgramData; public final class SmsEnvelope { /** @@ -56,12 +57,18 @@ public final class SmsEnvelope { //... // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1 - public static final int SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 0x1000; - public static final int SERVICE_CATEGORY_CMAS_EXTREME_THREAT = 0x1001; - public static final int SERVICE_CATEGORY_CMAS_SEVERE_THREAT = 0x1002; - public static final int SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003; - public static final int SERVICE_CATEGORY_CMAS_TEST_MESSAGE = 0x1004; - public static final int SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE = 0x10ff; + public static final int SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = + CdmaSmsCbProgramData.CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT; // = 4096 + public static final int SERVICE_CATEGORY_CMAS_EXTREME_THREAT = + CdmaSmsCbProgramData.CATEGORY_CMAS_EXTREME_THREAT; // = 4097 + public static final int SERVICE_CATEGORY_CMAS_SEVERE_THREAT = + CdmaSmsCbProgramData.CATEGORY_CMAS_SEVERE_THREAT; // = 4098 + public static final int SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = + CdmaSmsCbProgramData.CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY; // = 4099 + public static final int SERVICE_CATEGORY_CMAS_TEST_MESSAGE = + CdmaSmsCbProgramData.CATEGORY_CMAS_TEST_MESSAGE; // = 4100 + public static final int SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE = + CdmaSmsCbProgramData.CATEGORY_CMAS_LAST_RESERVED_VALUE; // = 4351 /** * Provides the type of a SMS message like point to point, broadcast or acknowledge diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl index 20169152539e..7422863d862c 100644 --- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl +++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl @@ -44,5 +44,7 @@ interface IEuiccController { oneway void updateSubscriptionNickname(int cardId, int subscriptionId, String nickname, String callingPackage, in PendingIntent callbackIntent); oneway void eraseSubscriptions(int cardId, in PendingIntent callbackIntent); + oneway void eraseSubscriptionsWithOptions( + int cardId, int options, in PendingIntent callbackIntent); oneway void retainSubscriptionsForFactoryReset(int cardId, in PendingIntent callbackIntent); } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java index 6eea118787a7..c3d490a6d5cf 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java @@ -90,9 +90,10 @@ public class GsmSmsCbMessage { * Create a new SmsCbMessage object from a header object plus one or more received PDUs. * * @param pdus PDU bytes + * @slotIndex slotIndex for which received sms cb message */ public static SmsCbMessage createSmsCbMessage(Context context, SmsCbHeader header, - SmsCbLocation location, byte[][] pdus) + SmsCbLocation location, byte[][] pdus, int slotIndex) throws IllegalArgumentException { long receivedTimeMillis = System.currentTimeMillis(); if (header.isEtwsPrimaryNotification()) { @@ -104,7 +105,7 @@ public class GsmSmsCbMessage { header.getSerialNumber(), location, header.getServiceCategory(), null, getEtwsPrimaryMessage(context, header.getEtwsInfo().getWarningType()), SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, header.getEtwsInfo(), - header.getCmasInfo(), 0, null /* geometries */, receivedTimeMillis); + header.getCmasInfo(), 0, null /* geometries */, receivedTimeMillis, slotIndex); } else if (header.isUmtsFormat()) { // UMTS format has only 1 PDU byte[] pdu = pdus[0]; @@ -138,7 +139,7 @@ public class GsmSmsCbMessage { header.getGeographicalScope(), header.getSerialNumber(), location, header.getServiceCategory(), language, body, priority, header.getEtwsInfo(), header.getCmasInfo(), maximumWaitingTimeSec, geometries, - receivedTimeMillis); + receivedTimeMillis, slotIndex); } else { String language = null; StringBuilder sb = new StringBuilder(); @@ -154,7 +155,7 @@ public class GsmSmsCbMessage { header.getGeographicalScope(), header.getSerialNumber(), location, header.getServiceCategory(), language, sb.toString(), priority, header.getEtwsInfo(), header.getCmasInfo(), 0, null /* geometries */, - receivedTimeMillis); + receivedTimeMillis, slotIndex); } } @@ -461,7 +462,11 @@ public class GsmSmsCbMessage { } } - static final class GeoFencingTriggerMessage { + /** + * Part of a GSM SMS cell broadcast message which may trigger geo-fencing logic. + * @hide + */ + public static final class GeoFencingTriggerMessage { /** * Indicate the list of active alerts share their warning area coordinates which means the * broadcast area is the union of the broadcast areas of the active alerts in this list. @@ -476,6 +481,11 @@ public class GsmSmsCbMessage { this.cbIdentifiers = cbIdentifiers; } + /** + * Whether the trigger message indicates that the broadcast areas are shared between all + * active alerts. + * @return true if broadcast areas are to be shared + */ boolean shouldShareBroadcastArea() { return type == TYPE_ACTIVE_ALERT_SHARE_WAC; } diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java index 6bbff4b91ee7..cbe521182667 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java @@ -74,22 +74,22 @@ public class SmsCbHeader { /** * Length of SMS-CB header */ - static final int PDU_HEADER_LENGTH = 6; + public static final int PDU_HEADER_LENGTH = 6; /** * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1 */ - static final int FORMAT_GSM = 1; + public static final int FORMAT_GSM = 1; /** * UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2 */ - static final int FORMAT_UMTS = 2; + public static final int FORMAT_UMTS = 2; /** - * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3 + * ETWS pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3 */ - static final int FORMAT_ETWS_PRIMARY = 3; + public static final int FORMAT_ETWS_PRIMARY = 3; /** * Message type value as defined in 3gpp TS 25.324, section 11.1. @@ -230,43 +230,43 @@ public class SmsCbHeader { } @UnsupportedAppUsage - int getGeographicalScope() { + public int getGeographicalScope() { return mGeographicalScope; } @UnsupportedAppUsage - int getSerialNumber() { + public int getSerialNumber() { return mSerialNumber; } @UnsupportedAppUsage - int getServiceCategory() { + public int getServiceCategory() { return mMessageIdentifier; } - int getDataCodingScheme() { + public int getDataCodingScheme() { return mDataCodingScheme; } - DataCodingScheme getDataCodingSchemeStructedData() { + public DataCodingScheme getDataCodingSchemeStructedData() { return mDataCodingSchemeStructedData; } @UnsupportedAppUsage - int getPageIndex() { + public int getPageIndex() { return mPageIndex; } @UnsupportedAppUsage - int getNumberOfPages() { + public int getNumberOfPages() { return mNrOfPages; } - SmsCbEtwsInfo getEtwsInfo() { + public SmsCbEtwsInfo getEtwsInfo() { return mEtwsInfo; } - SmsCbCmasInfo getCmasInfo() { + public SmsCbCmasInfo getCmasInfo() { return mCmasInfo; } @@ -274,7 +274,7 @@ public class SmsCbHeader { * Return whether this broadcast is an emergency (PWS) message type. * @return true if this message is emergency type; false otherwise */ - boolean isEmergencyMessage() { + public boolean isEmergencyMessage() { return mMessageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER && mMessageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER; } @@ -292,7 +292,7 @@ public class SmsCbHeader { * Return whether this broadcast is an ETWS primary notification. * @return true if this message is an ETWS primary notification; false otherwise */ - boolean isEtwsPrimaryNotification() { + public boolean isEtwsPrimaryNotification() { return mFormat == FORMAT_ETWS_PRIMARY; } @@ -300,7 +300,7 @@ public class SmsCbHeader { * Return whether this broadcast is in UMTS format. * @return true if this message is in UMTS format; false otherwise */ - boolean isUmtsFormat() { + public boolean isUmtsFormat() { return mFormat == FORMAT_UMTS; } diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index 28b331b17b91..da32c8c45a73 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -1496,7 +1496,7 @@ public class SmsMessage extends SmsMessageBase { * * @return true if this is a USIM data download message; false otherwise */ - public boolean isUsimDataDownload() { + boolean isUsimDataDownload() { return messageClass == MessageClass.CLASS_2 && (mProtocolIdentifier == 0x7f || mProtocolIdentifier == 0x7c); } diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java index 749f0522846d..3dc2e90652a4 100644 --- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java +++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java @@ -22,6 +22,7 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.telephony.Rlog; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.EncodeException; import com.android.internal.telephony.GsmAlphabet; @@ -29,6 +30,7 @@ import dalvik.annotation.compat.UnsupportedAppUsage; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; +import java.util.List; /** * Various methods, useful for dealing with SIM data. @@ -36,6 +38,11 @@ import java.nio.charset.Charset; public class IccUtils { static final String LOG_TAG="IccUtils"; + // 3GPP specification constants + // Spec reference TS 31.102 section 4.2.16 + @VisibleForTesting + static final int FPLMN_BYTE_SIZE = 3; + // A table mapping from a number to a hex character for fast encoding hex strings. private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' @@ -899,6 +906,30 @@ public class IccUtils { return 0; } + /** + * Encode the Fplmns into byte array to write to EF. + * + * @param fplmns Array of fplmns to be serialized. + * @param dataLength the size of the EF file. + * @return the encoded byte array in the correct format for FPLMN file. + */ + public static byte[] encodeFplmns(List<String> fplmns, int dataLength) { + byte[] serializedFplmns = new byte[dataLength]; + int offset = 0; + for (String fplmn : fplmns) { + if (offset >= dataLength) break; + stringToBcdPlmn(fplmn, serializedFplmns, offset); + offset += FPLMN_BYTE_SIZE; + } + //pads to the length of the EF file. + while (offset < dataLength) { + // required by 3GPP TS 31.102 spec 4.2.16 + serializedFplmns[offset++] = (byte) 0xff; + } + return serializedFplmns; + + } + static byte[] stringToAdnStringField(String alphaTag) { boolean isUcs2 = false; diff --git a/telephony/java/com/google/android/mms/ContentType.java b/telephony/java/com/google/android/mms/ContentType.java deleted file mode 100644 index 12e4b7e26e1e..000000000000 --- a/telephony/java/com/google/android/mms/ContentType.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.util.ArrayList; - -public class ContentType { - public static final String MMS_MESSAGE = "application/vnd.wap.mms-message"; - // The phony content type for generic PDUs (e.g. ReadOrig.ind, - // Notification.ind, Delivery.ind). - public static final String MMS_GENERIC = "application/vnd.wap.mms-generic"; - public static final String MULTIPART_MIXED = "application/vnd.wap.multipart.mixed"; - public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related"; - public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative"; - - public static final String TEXT_PLAIN = "text/plain"; - public static final String TEXT_HTML = "text/html"; - public static final String TEXT_VCALENDAR = "text/x-vCalendar"; - public static final String TEXT_VCARD = "text/x-vCard"; - - public static final String IMAGE_UNSPECIFIED = "image/*"; - public static final String IMAGE_JPEG = "image/jpeg"; - public static final String IMAGE_JPG = "image/jpg"; - public static final String IMAGE_GIF = "image/gif"; - public static final String IMAGE_WBMP = "image/vnd.wap.wbmp"; - public static final String IMAGE_PNG = "image/png"; - public static final String IMAGE_X_MS_BMP = "image/x-ms-bmp"; - - public static final String AUDIO_UNSPECIFIED = "audio/*"; - public static final String AUDIO_AAC = "audio/aac"; - public static final String AUDIO_AMR = "audio/amr"; - public static final String AUDIO_IMELODY = "audio/imelody"; - public static final String AUDIO_MID = "audio/mid"; - public static final String AUDIO_MIDI = "audio/midi"; - public static final String AUDIO_MP3 = "audio/mp3"; - public static final String AUDIO_MPEG3 = "audio/mpeg3"; - public static final String AUDIO_MPEG = "audio/mpeg"; - public static final String AUDIO_MPG = "audio/mpg"; - public static final String AUDIO_MP4 = "audio/mp4"; - public static final String AUDIO_X_MID = "audio/x-mid"; - public static final String AUDIO_X_MIDI = "audio/x-midi"; - public static final String AUDIO_X_MP3 = "audio/x-mp3"; - public static final String AUDIO_X_MPEG3 = "audio/x-mpeg3"; - public static final String AUDIO_X_MPEG = "audio/x-mpeg"; - public static final String AUDIO_X_MPG = "audio/x-mpg"; - public static final String AUDIO_3GPP = "audio/3gpp"; - public static final String AUDIO_X_WAV = "audio/x-wav"; - public static final String AUDIO_OGG = "application/ogg"; - public static final String AUDIO_OGG2 = "audio/ogg"; - - public static final String VIDEO_UNSPECIFIED = "video/*"; - public static final String VIDEO_3GPP = "video/3gpp"; - public static final String VIDEO_3G2 = "video/3gpp2"; - public static final String VIDEO_H263 = "video/h263"; - public static final String VIDEO_MP4 = "video/mp4"; - - public static final String APP_SMIL = "application/smil"; - public static final String APP_WAP_XHTML = "application/vnd.wap.xhtml+xml"; - public static final String APP_XHTML = "application/xhtml+xml"; - - public static final String APP_DRM_CONTENT = "application/vnd.oma.drm.content"; - public static final String APP_DRM_MESSAGE = "application/vnd.oma.drm.message"; - - private static final ArrayList<String> sSupportedContentTypes = new ArrayList<String>(); - private static final ArrayList<String> sSupportedImageTypes = new ArrayList<String>(); - private static final ArrayList<String> sSupportedAudioTypes = new ArrayList<String>(); - private static final ArrayList<String> sSupportedVideoTypes = new ArrayList<String>(); - - static { - sSupportedContentTypes.add(TEXT_PLAIN); - sSupportedContentTypes.add(TEXT_HTML); - sSupportedContentTypes.add(TEXT_VCALENDAR); - sSupportedContentTypes.add(TEXT_VCARD); - - sSupportedContentTypes.add(IMAGE_JPEG); - sSupportedContentTypes.add(IMAGE_GIF); - sSupportedContentTypes.add(IMAGE_WBMP); - sSupportedContentTypes.add(IMAGE_PNG); - sSupportedContentTypes.add(IMAGE_JPG); - sSupportedContentTypes.add(IMAGE_X_MS_BMP); - //supportedContentTypes.add(IMAGE_SVG); not yet supported. - - sSupportedContentTypes.add(AUDIO_AAC); - sSupportedContentTypes.add(AUDIO_AMR); - sSupportedContentTypes.add(AUDIO_IMELODY); - sSupportedContentTypes.add(AUDIO_MID); - sSupportedContentTypes.add(AUDIO_MIDI); - sSupportedContentTypes.add(AUDIO_MP3); - sSupportedContentTypes.add(AUDIO_MP4); - sSupportedContentTypes.add(AUDIO_MPEG3); - sSupportedContentTypes.add(AUDIO_MPEG); - sSupportedContentTypes.add(AUDIO_MPG); - sSupportedContentTypes.add(AUDIO_X_MID); - sSupportedContentTypes.add(AUDIO_X_MIDI); - sSupportedContentTypes.add(AUDIO_X_MP3); - sSupportedContentTypes.add(AUDIO_X_MPEG3); - sSupportedContentTypes.add(AUDIO_X_MPEG); - sSupportedContentTypes.add(AUDIO_X_MPG); - sSupportedContentTypes.add(AUDIO_X_WAV); - sSupportedContentTypes.add(AUDIO_3GPP); - sSupportedContentTypes.add(AUDIO_OGG); - sSupportedContentTypes.add(AUDIO_OGG2); - - sSupportedContentTypes.add(VIDEO_3GPP); - sSupportedContentTypes.add(VIDEO_3G2); - sSupportedContentTypes.add(VIDEO_H263); - sSupportedContentTypes.add(VIDEO_MP4); - - sSupportedContentTypes.add(APP_SMIL); - sSupportedContentTypes.add(APP_WAP_XHTML); - sSupportedContentTypes.add(APP_XHTML); - - sSupportedContentTypes.add(APP_DRM_CONTENT); - sSupportedContentTypes.add(APP_DRM_MESSAGE); - - // add supported image types - sSupportedImageTypes.add(IMAGE_JPEG); - sSupportedImageTypes.add(IMAGE_GIF); - sSupportedImageTypes.add(IMAGE_WBMP); - sSupportedImageTypes.add(IMAGE_PNG); - sSupportedImageTypes.add(IMAGE_JPG); - sSupportedImageTypes.add(IMAGE_X_MS_BMP); - - // add supported audio types - sSupportedAudioTypes.add(AUDIO_AAC); - sSupportedAudioTypes.add(AUDIO_AMR); - sSupportedAudioTypes.add(AUDIO_IMELODY); - sSupportedAudioTypes.add(AUDIO_MID); - sSupportedAudioTypes.add(AUDIO_MIDI); - sSupportedAudioTypes.add(AUDIO_MP3); - sSupportedAudioTypes.add(AUDIO_MPEG3); - sSupportedAudioTypes.add(AUDIO_MPEG); - sSupportedAudioTypes.add(AUDIO_MPG); - sSupportedAudioTypes.add(AUDIO_MP4); - sSupportedAudioTypes.add(AUDIO_X_MID); - sSupportedAudioTypes.add(AUDIO_X_MIDI); - sSupportedAudioTypes.add(AUDIO_X_MP3); - sSupportedAudioTypes.add(AUDIO_X_MPEG3); - sSupportedAudioTypes.add(AUDIO_X_MPEG); - sSupportedAudioTypes.add(AUDIO_X_MPG); - sSupportedAudioTypes.add(AUDIO_X_WAV); - sSupportedAudioTypes.add(AUDIO_3GPP); - sSupportedAudioTypes.add(AUDIO_OGG); - sSupportedAudioTypes.add(AUDIO_OGG2); - - // add supported video types - sSupportedVideoTypes.add(VIDEO_3GPP); - sSupportedVideoTypes.add(VIDEO_3G2); - sSupportedVideoTypes.add(VIDEO_H263); - sSupportedVideoTypes.add(VIDEO_MP4); - } - - // This class should never be instantiated. - private ContentType() { - } - - @UnsupportedAppUsage - public static boolean isSupportedType(String contentType) { - return (null != contentType) && sSupportedContentTypes.contains(contentType); - } - - @UnsupportedAppUsage - public static boolean isSupportedImageType(String contentType) { - return isImageType(contentType) && isSupportedType(contentType); - } - - @UnsupportedAppUsage - public static boolean isSupportedAudioType(String contentType) { - return isAudioType(contentType) && isSupportedType(contentType); - } - - @UnsupportedAppUsage - public static boolean isSupportedVideoType(String contentType) { - return isVideoType(contentType) && isSupportedType(contentType); - } - - @UnsupportedAppUsage - public static boolean isTextType(String contentType) { - return (null != contentType) && contentType.startsWith("text/"); - } - - @UnsupportedAppUsage - public static boolean isImageType(String contentType) { - return (null != contentType) && contentType.startsWith("image/"); - } - - @UnsupportedAppUsage - public static boolean isAudioType(String contentType) { - return (null != contentType) && contentType.startsWith("audio/"); - } - - @UnsupportedAppUsage - public static boolean isVideoType(String contentType) { - return (null != contentType) && contentType.startsWith("video/"); - } - - @UnsupportedAppUsage - public static boolean isDrmType(String contentType) { - return (null != contentType) - && (contentType.equals(APP_DRM_CONTENT) - || contentType.equals(APP_DRM_MESSAGE)); - } - - public static boolean isUnspecified(String contentType) { - return (null != contentType) && contentType.endsWith("*"); - } - - @UnsupportedAppUsage - @SuppressWarnings("unchecked") - public static ArrayList<String> getImageTypes() { - return (ArrayList<String>) sSupportedImageTypes.clone(); - } - - @UnsupportedAppUsage - @SuppressWarnings("unchecked") - public static ArrayList<String> getAudioTypes() { - return (ArrayList<String>) sSupportedAudioTypes.clone(); - } - - @UnsupportedAppUsage - @SuppressWarnings("unchecked") - public static ArrayList<String> getVideoTypes() { - return (ArrayList<String>) sSupportedVideoTypes.clone(); - } - - @SuppressWarnings("unchecked") - public static ArrayList<String> getSupportedTypes() { - return (ArrayList<String>) sSupportedContentTypes.clone(); - } -} diff --git a/telephony/java/com/google/android/mms/InvalidHeaderValueException.java b/telephony/java/com/google/android/mms/InvalidHeaderValueException.java deleted file mode 100644 index 2836c3075b3b..000000000000 --- a/telephony/java/com/google/android/mms/InvalidHeaderValueException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -/** - * Thrown when an invalid header value was set. - */ -public class InvalidHeaderValueException extends MmsException { - private static final long serialVersionUID = -2053384496042052262L; - - /** - * Constructs an InvalidHeaderValueException with no detailed message. - */ - public InvalidHeaderValueException() { - super(); - } - - /** - * Constructs an InvalidHeaderValueException with the specified detailed message. - * - * @param message the detailed message. - */ - @UnsupportedAppUsage - public InvalidHeaderValueException(String message) { - super(message); - } -} diff --git a/telephony/java/com/google/android/mms/MmsException.java b/telephony/java/com/google/android/mms/MmsException.java deleted file mode 100644 index 5be33ed1fac9..000000000000 --- a/telephony/java/com/google/android/mms/MmsException.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -/** - * A generic exception that is thrown by the Mms client. - */ -public class MmsException extends Exception { - private static final long serialVersionUID = -7323249827281485390L; - - /** - * Creates a new MmsException. - */ - @UnsupportedAppUsage - public MmsException() { - super(); - } - - /** - * Creates a new MmsException with the specified detail message. - * - * @param message the detail message. - */ - @UnsupportedAppUsage - public MmsException(String message) { - super(message); - } - - /** - * Creates a new MmsException with the specified cause. - * - * @param cause the cause. - */ - @UnsupportedAppUsage - public MmsException(Throwable cause) { - super(cause); - } - - /** - * Creates a new MmsException with the specified detail message and cause. - * - * @param message the detail message. - * @param cause the cause. - */ - @UnsupportedAppUsage - public MmsException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/telephony/java/com/google/android/mms/package.html b/telephony/java/com/google/android/mms/package.html deleted file mode 100755 index c9f96a66ab3b..000000000000 --- a/telephony/java/com/google/android/mms/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> - -{@hide} - -</body> diff --git a/telephony/java/com/google/android/mms/pdu/AcknowledgeInd.java b/telephony/java/com/google/android/mms/pdu/AcknowledgeInd.java deleted file mode 100644 index ae447d7a7417..000000000000 --- a/telephony/java/com/google/android/mms/pdu/AcknowledgeInd.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Acknowledge.ind PDU. - */ -public class AcknowledgeInd extends GenericPdu { - /** - * Constructor, used when composing a M-Acknowledge.ind pdu. - * - * @param mmsVersion current viersion of mms - * @param transactionId the transaction-id value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if transactionId is null. - */ - @UnsupportedAppUsage - public AcknowledgeInd(int mmsVersion, byte[] transactionId) - throws InvalidHeaderValueException { - super(); - - setMessageType(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - @UnsupportedAppUsage - AcknowledgeInd(PduHeaders headers) { - super(headers); - } - - /** - * Get X-Mms-Report-Allowed field value. - * - * @return the X-Mms-Report-Allowed value - */ - public int getReportAllowed() { - return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Report-Allowed field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - @UnsupportedAppUsage - public void setReportAllowed(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } -} diff --git a/telephony/java/com/google/android/mms/pdu/Base64.java b/telephony/java/com/google/android/mms/pdu/Base64.java deleted file mode 100644 index 483fa7f9842e..000000000000 --- a/telephony/java/com/google/android/mms/pdu/Base64.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -public class Base64 { - /** - * Used to get the number of Quadruples. - */ - static final int FOURBYTE = 4; - - /** - * Byte used to pad output. - */ - static final byte PAD = (byte) '='; - - /** - * The base length. - */ - static final int BASELENGTH = 255; - - // Create arrays to hold the base64 characters - private static byte[] base64Alphabet = new byte[BASELENGTH]; - - // Populating the character arrays - static { - for (int i = 0; i < BASELENGTH; i++) { - base64Alphabet[i] = (byte) -1; - } - for (int i = 'Z'; i >= 'A'; i--) { - base64Alphabet[i] = (byte) (i - 'A'); - } - for (int i = 'z'; i >= 'a'; i--) { - base64Alphabet[i] = (byte) (i - 'a' + 26); - } - for (int i = '9'; i >= '0'; i--) { - base64Alphabet[i] = (byte) (i - '0' + 52); - } - - base64Alphabet['+'] = 62; - base64Alphabet['/'] = 63; - } - - /** - * Decodes Base64 data into octects - * - * @param base64Data Byte array containing Base64 data - * @return Array containing decoded data. - */ - @UnsupportedAppUsage - public static byte[] decodeBase64(byte[] base64Data) { - // RFC 2045 requires that we discard ALL non-Base64 characters - base64Data = discardNonBase64(base64Data); - - // handle the edge case, so we don't have to worry about it later - if (base64Data.length == 0) { - return new byte[0]; - } - - int numberQuadruple = base64Data.length / FOURBYTE; - byte decodedData[] = null; - byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0; - - // Throw away anything not in base64Data - - int encodedIndex = 0; - int dataIndex = 0; - { - // this sizes the output array properly - rlw - int lastData = base64Data.length; - // ignore the '=' padding - while (base64Data[lastData - 1] == PAD) { - if (--lastData == 0) { - return new byte[0]; - } - } - decodedData = new byte[lastData - numberQuadruple]; - } - - for (int i = 0; i < numberQuadruple; i++) { - dataIndex = i * 4; - marker0 = base64Data[dataIndex + 2]; - marker1 = base64Data[dataIndex + 3]; - - b1 = base64Alphabet[base64Data[dataIndex]]; - b2 = base64Alphabet[base64Data[dataIndex + 1]]; - - if (marker0 != PAD && marker1 != PAD) { - //No PAD e.g 3cQl - b3 = base64Alphabet[marker0]; - b4 = base64Alphabet[marker1]; - - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - decodedData[encodedIndex + 1] = - (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4); - } else if (marker0 == PAD) { - //Two PAD e.g. 3c[Pad][Pad] - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - } else if (marker1 == PAD) { - //One PAD e.g. 3cQ[Pad] - b3 = base64Alphabet[marker0]; - - decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); - decodedData[encodedIndex + 1] = - (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); - } - encodedIndex += 3; - } - return decodedData; - } - - /** - * Check octect whether it is a base64 encoding. - * - * @param octect to be checked byte - * @return ture if it is base64 encoding, false otherwise. - */ - private static boolean isBase64(byte octect) { - if (octect == PAD) { - return true; - } else if (base64Alphabet[octect] == -1) { - return false; - } else { - return true; - } - } - - /** - * Discards any characters outside of the base64 alphabet, per - * the requirements on page 25 of RFC 2045 - "Any characters - * outside of the base64 alphabet are to be ignored in base64 - * encoded data." - * - * @param data The base-64 encoded data to groom - * @return The data, less non-base64 characters (see RFC 2045). - */ - static byte[] discardNonBase64(byte[] data) { - byte groomedData[] = new byte[data.length]; - int bytesCopied = 0; - - for (int i = 0; i < data.length; i++) { - if (isBase64(data[i])) { - groomedData[bytesCopied++] = data[i]; - } - } - - byte packedData[] = new byte[bytesCopied]; - - System.arraycopy(groomedData, 0, packedData, 0, bytesCopied); - - return packedData; - } -} diff --git a/telephony/java/com/google/android/mms/pdu/CharacterSets.java b/telephony/java/com/google/android/mms/pdu/CharacterSets.java deleted file mode 100644 index 27da35e2d928..000000000000 --- a/telephony/java/com/google/android/mms/pdu/CharacterSets.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.io.UnsupportedEncodingException; -import java.util.HashMap; - -public class CharacterSets { - /** - * IANA assigned MIB enum numbers. - * - * From wap-230-wsp-20010705-a.pdf - * Any-charset = <Octet 128> - * Equivalent to the special RFC2616 charset value "*" - */ - public static final int ANY_CHARSET = 0x00; - public static final int US_ASCII = 0x03; - public static final int ISO_8859_1 = 0x04; - public static final int ISO_8859_2 = 0x05; - public static final int ISO_8859_3 = 0x06; - public static final int ISO_8859_4 = 0x07; - public static final int ISO_8859_5 = 0x08; - public static final int ISO_8859_6 = 0x09; - public static final int ISO_8859_7 = 0x0A; - public static final int ISO_8859_8 = 0x0B; - public static final int ISO_8859_9 = 0x0C; - public static final int SHIFT_JIS = 0x11; - public static final int UTF_8 = 0x6A; - public static final int BIG5 = 0x07EA; - public static final int UCS2 = 0x03E8; - public static final int UTF_16 = 0x03F7; - - /** - * If the encoding of given data is unsupported, use UTF_8 to decode it. - */ - public static final int DEFAULT_CHARSET = UTF_8; - - /** - * Array of MIB enum numbers. - */ - private static final int[] MIBENUM_NUMBERS = { - ANY_CHARSET, - US_ASCII, - ISO_8859_1, - ISO_8859_2, - ISO_8859_3, - ISO_8859_4, - ISO_8859_5, - ISO_8859_6, - ISO_8859_7, - ISO_8859_8, - ISO_8859_9, - SHIFT_JIS, - UTF_8, - BIG5, - UCS2, - UTF_16, - }; - - /** - * The Well-known-charset Mime name. - */ - public static final String MIMENAME_ANY_CHARSET = "*"; - public static final String MIMENAME_US_ASCII = "us-ascii"; - public static final String MIMENAME_ISO_8859_1 = "iso-8859-1"; - public static final String MIMENAME_ISO_8859_2 = "iso-8859-2"; - public static final String MIMENAME_ISO_8859_3 = "iso-8859-3"; - public static final String MIMENAME_ISO_8859_4 = "iso-8859-4"; - public static final String MIMENAME_ISO_8859_5 = "iso-8859-5"; - public static final String MIMENAME_ISO_8859_6 = "iso-8859-6"; - public static final String MIMENAME_ISO_8859_7 = "iso-8859-7"; - public static final String MIMENAME_ISO_8859_8 = "iso-8859-8"; - public static final String MIMENAME_ISO_8859_9 = "iso-8859-9"; - public static final String MIMENAME_SHIFT_JIS = "shift_JIS"; - public static final String MIMENAME_UTF_8 = "utf-8"; - public static final String MIMENAME_BIG5 = "big5"; - public static final String MIMENAME_UCS2 = "iso-10646-ucs-2"; - public static final String MIMENAME_UTF_16 = "utf-16"; - - public static final String DEFAULT_CHARSET_NAME = MIMENAME_UTF_8; - - /** - * Array of the names of character sets. - */ - private static final String[] MIME_NAMES = { - MIMENAME_ANY_CHARSET, - MIMENAME_US_ASCII, - MIMENAME_ISO_8859_1, - MIMENAME_ISO_8859_2, - MIMENAME_ISO_8859_3, - MIMENAME_ISO_8859_4, - MIMENAME_ISO_8859_5, - MIMENAME_ISO_8859_6, - MIMENAME_ISO_8859_7, - MIMENAME_ISO_8859_8, - MIMENAME_ISO_8859_9, - MIMENAME_SHIFT_JIS, - MIMENAME_UTF_8, - MIMENAME_BIG5, - MIMENAME_UCS2, - MIMENAME_UTF_16, - }; - - private static final HashMap<Integer, String> MIBENUM_TO_NAME_MAP; - private static final HashMap<String, Integer> NAME_TO_MIBENUM_MAP; - - static { - // Create the HashMaps. - MIBENUM_TO_NAME_MAP = new HashMap<Integer, String>(); - NAME_TO_MIBENUM_MAP = new HashMap<String, Integer>(); - assert(MIBENUM_NUMBERS.length == MIME_NAMES.length); - int count = MIBENUM_NUMBERS.length - 1; - for(int i = 0; i <= count; i++) { - MIBENUM_TO_NAME_MAP.put(MIBENUM_NUMBERS[i], MIME_NAMES[i]); - NAME_TO_MIBENUM_MAP.put(MIME_NAMES[i], MIBENUM_NUMBERS[i]); - } - } - - private CharacterSets() {} // Non-instantiatable - - /** - * Map an MIBEnum number to the name of the charset which this number - * is assigned to by IANA. - * - * @param mibEnumValue An IANA assigned MIBEnum number. - * @return The name string of the charset. - * @throws UnsupportedEncodingException - */ - @UnsupportedAppUsage - public static String getMimeName(int mibEnumValue) - throws UnsupportedEncodingException { - String name = MIBENUM_TO_NAME_MAP.get(mibEnumValue); - if (name == null) { - throw new UnsupportedEncodingException(); - } - return name; - } - - /** - * Map a well-known charset name to its assigned MIBEnum number. - * - * @param mimeName The charset name. - * @return The MIBEnum number assigned by IANA for this charset. - * @throws UnsupportedEncodingException - */ - @UnsupportedAppUsage - public static int getMibEnumValue(String mimeName) - throws UnsupportedEncodingException { - if(null == mimeName) { - return -1; - } - - Integer mibEnumValue = NAME_TO_MIBENUM_MAP.get(mimeName); - if (mibEnumValue == null) { - throw new UnsupportedEncodingException(); - } - return mibEnumValue; - } -} diff --git a/telephony/java/com/google/android/mms/pdu/DeliveryInd.java b/telephony/java/com/google/android/mms/pdu/DeliveryInd.java deleted file mode 100644 index 7093ac63338c..000000000000 --- a/telephony/java/com/google/android/mms/pdu/DeliveryInd.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Delivery.Ind Pdu. - */ -public class DeliveryInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public DeliveryInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_DELIVERY_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - @UnsupportedAppUsage - DeliveryInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - @UnsupportedAppUsage - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value, should not be null - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get Status value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getStatus() { - return mPduHeaders.getOctet(PduHeaders.STATUS); - } - - /** - * Set Status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.STATUS); - } - - /** - * Get To value. - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public EncodedStringValue getStatusText() {return null;} - * public void setStatusText(EncodedStringValue value) {} - */ -} diff --git a/telephony/java/com/google/android/mms/pdu/EncodedStringValue.java b/telephony/java/com/google/android/mms/pdu/EncodedStringValue.java deleted file mode 100644 index 41662750842f..000000000000 --- a/telephony/java/com/google/android/mms/pdu/EncodedStringValue.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import android.util.Log; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; - -/** - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ -public class EncodedStringValue implements Cloneable { - private static final String TAG = "EncodedStringValue"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - /** - * The Char-set value. - */ - private int mCharacterSet; - - /** - * The Text-string value. - */ - private byte[] mData; - - /** - * Constructor. - * - * @param charset the Char-set value - * @param data the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - @UnsupportedAppUsage - public EncodedStringValue(int charset, byte[] data) { - // TODO: CharSet needs to be validated against MIBEnum. - if(null == data) { - throw new NullPointerException("EncodedStringValue: Text-string is null."); - } - - mCharacterSet = charset; - mData = new byte[data.length]; - System.arraycopy(data, 0, mData, 0, data.length); - } - - /** - * Constructor. - * - * @param data the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - @UnsupportedAppUsage - public EncodedStringValue(byte[] data) { - this(CharacterSets.DEFAULT_CHARSET, data); - } - - @UnsupportedAppUsage - public EncodedStringValue(String data) { - try { - mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME); - mCharacterSet = CharacterSets.DEFAULT_CHARSET; - } catch (UnsupportedEncodingException e) { - Log.e(TAG, "Default encoding must be supported.", e); - } - } - - /** - * Get Char-set value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getCharacterSet() { - return mCharacterSet; - } - - /** - * Set Char-set value. - * - * @param charset the Char-set value - */ - @UnsupportedAppUsage - public void setCharacterSet(int charset) { - // TODO: CharSet needs to be validated against MIBEnum. - mCharacterSet = charset; - } - - /** - * Get Text-string value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getTextString() { - byte[] byteArray = new byte[mData.length]; - - System.arraycopy(mData, 0, byteArray, 0, mData.length); - return byteArray; - } - - /** - * Set Text-string value. - * - * @param textString the Text-string value - * @throws NullPointerException if Text-string value is null. - */ - @UnsupportedAppUsage - public void setTextString(byte[] textString) { - if(null == textString) { - throw new NullPointerException("EncodedStringValue: Text-string is null."); - } - - mData = new byte[textString.length]; - System.arraycopy(textString, 0, mData, 0, textString.length); - } - - /** - * Convert this object to a {@link java.lang.String}. If the encoding of - * the EncodedStringValue is null or unsupported, it will be - * treated as iso-8859-1 encoding. - * - * @return The decoded String. - */ - @UnsupportedAppUsage - public String getString() { - if (CharacterSets.ANY_CHARSET == mCharacterSet) { - return new String(mData); // system default encoding. - } else { - try { - String name = CharacterSets.getMimeName(mCharacterSet); - return new String(mData, name); - } catch (UnsupportedEncodingException e) { - if (LOCAL_LOGV) { - Log.v(TAG, e.getMessage(), e); - } - try { - return new String(mData, CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException e2) { - return new String(mData); // system default encoding. - } - } - } - } - - /** - * Append to Text-string. - * - * @param textString the textString to append - * @throws NullPointerException if the text String is null - * or an IOException occurred. - */ - @UnsupportedAppUsage - public void appendTextString(byte[] textString) { - if(null == textString) { - throw new NullPointerException("Text-string is null."); - } - - if(null == mData) { - mData = new byte[textString.length]; - System.arraycopy(textString, 0, mData, 0, textString.length); - } else { - ByteArrayOutputStream newTextString = new ByteArrayOutputStream(); - try { - newTextString.write(mData); - newTextString.write(textString); - } catch (IOException e) { - e.printStackTrace(); - throw new NullPointerException( - "appendTextString: failed when write a new Text-string"); - } - - mData = newTextString.toByteArray(); - } - } - - /* - * (non-Javadoc) - * @see java.lang.Object#clone() - */ - @Override - public Object clone() throws CloneNotSupportedException { - super.clone(); - int len = mData.length; - byte[] dstBytes = new byte[len]; - System.arraycopy(mData, 0, dstBytes, 0, len); - - try { - return new EncodedStringValue(mCharacterSet, dstBytes); - } catch (Exception e) { - Log.e(TAG, "failed to clone an EncodedStringValue: " + this); - e.printStackTrace(); - throw new CloneNotSupportedException(e.getMessage()); - } - } - - /** - * Split this encoded string around matches of the given pattern. - * - * @param pattern the delimiting pattern - * @return the array of encoded strings computed by splitting this encoded - * string around matches of the given pattern - */ - public EncodedStringValue[] split(String pattern) { - String[] temp = getString().split(pattern); - EncodedStringValue[] ret = new EncodedStringValue[temp.length]; - for (int i = 0; i < ret.length; ++i) { - try { - ret[i] = new EncodedStringValue(mCharacterSet, - temp[i].getBytes()); - } catch (NullPointerException e) { - // Can't arrive here - return null; - } - } - return ret; - } - - /** - * Extract an EncodedStringValue[] from a given String. - */ - @UnsupportedAppUsage - public static EncodedStringValue[] extract(String src) { - String[] values = src.split(";"); - - ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>(); - for (int i = 0; i < values.length; i++) { - if (values[i].length() > 0) { - list.add(new EncodedStringValue(values[i])); - } - } - - int len = list.size(); - if (len > 0) { - return list.toArray(new EncodedStringValue[len]); - } else { - return null; - } - } - - /** - * Concatenate an EncodedStringValue[] into a single String. - */ - @UnsupportedAppUsage - public static String concat(EncodedStringValue[] addr) { - StringBuilder sb = new StringBuilder(); - int maxIndex = addr.length - 1; - for (int i = 0; i <= maxIndex; i++) { - sb.append(addr[i].getString()); - if (i < maxIndex) { - sb.append(";"); - } - } - - return sb.toString(); - } - - @UnsupportedAppUsage - public static EncodedStringValue copy(EncodedStringValue value) { - if (value == null) { - return null; - } - - return new EncodedStringValue(value.mCharacterSet, value.mData); - } - - @UnsupportedAppUsage - public static EncodedStringValue[] encodeStrings(String[] array) { - int count = array.length; - if (count > 0) { - EncodedStringValue[] encodedArray = new EncodedStringValue[count]; - for (int i = 0; i < count; i++) { - encodedArray[i] = new EncodedStringValue(array[i]); - } - return encodedArray; - } - return null; - } -} diff --git a/telephony/java/com/google/android/mms/pdu/GenericPdu.java b/telephony/java/com/google/android/mms/pdu/GenericPdu.java deleted file mode 100644 index ebf16ac7e632..000000000000 --- a/telephony/java/com/google/android/mms/pdu/GenericPdu.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -public class GenericPdu { - /** - * The headers of pdu. - */ - @UnsupportedAppUsage - PduHeaders mPduHeaders = null; - - /** - * Constructor. - */ - @UnsupportedAppUsage - public GenericPdu() { - mPduHeaders = new PduHeaders(); - } - - /** - * Constructor. - * - * @param headers Headers for this PDU. - */ - GenericPdu(PduHeaders headers) { - mPduHeaders = headers; - } - - /** - * Get the headers of this PDU. - * - * @return A PduHeaders of this PDU. - */ - @UnsupportedAppUsage - PduHeaders getPduHeaders() { - return mPduHeaders; - } - - /** - * Get X-Mms-Message-Type field value. - * - * @return the X-Mms-Report-Allowed value - */ - @UnsupportedAppUsage - public int getMessageType() { - return mPduHeaders.getOctet(PduHeaders.MESSAGE_TYPE); - } - - /** - * Set X-Mms-Message-Type field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if field's value is not Octet. - */ - @UnsupportedAppUsage - public void setMessageType(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.MESSAGE_TYPE); - } - - /** - * Get X-Mms-MMS-Version field value. - * - * @return the X-Mms-MMS-Version value - */ - public int getMmsVersion() { - return mPduHeaders.getOctet(PduHeaders.MMS_VERSION); - } - - /** - * Set X-Mms-MMS-Version field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if field's value is not Octet. - */ - public void setMmsVersion(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.MMS_VERSION); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } -} diff --git a/telephony/java/com/google/android/mms/pdu/MultimediaMessagePdu.java b/telephony/java/com/google/android/mms/pdu/MultimediaMessagePdu.java deleted file mode 100644 index e108f7600baf..000000000000 --- a/telephony/java/com/google/android/mms/pdu/MultimediaMessagePdu.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * Multimedia message PDU. - */ -public class MultimediaMessagePdu extends GenericPdu{ - /** - * The body. - */ - private PduBody mMessageBody; - - /** - * Constructor. - */ - @UnsupportedAppUsage - public MultimediaMessagePdu() { - super(); - } - - /** - * Constructor. - * - * @param header the header of this PDU - * @param body the body of this PDU - */ - @UnsupportedAppUsage - public MultimediaMessagePdu(PduHeaders header, PduBody body) { - super(header); - mMessageBody = body; - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - MultimediaMessagePdu(PduHeaders headers) { - super(headers); - } - - /** - * Get body of the PDU. - * - * @return the body - */ - @UnsupportedAppUsage - public PduBody getBody() { - return mMessageBody; - } - - /** - * Set body of the PDU. - * - * @param body the body - */ - @UnsupportedAppUsage - public void setBody(PduBody body) { - mMessageBody = body; - } - - /** - * Get subject. - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue getSubject() { - return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT); - } - - /** - * Set subject. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setSubject(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT); - } - - /** - * Get To value. - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Add a "To" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void addTo(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.TO); - } - - /** - * Get X-Mms-Priority value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getPriority() { - return mPduHeaders.getOctet(PduHeaders.PRIORITY); - } - - /** - * Set X-Mms-Priority value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - @UnsupportedAppUsage - public void setPriority(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.PRIORITY); - } - - /** - * Get Date value. - * - * @return the value - */ - @UnsupportedAppUsage - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value in seconds. - * - * @param value the value - */ - @UnsupportedAppUsage - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } -} diff --git a/telephony/java/com/google/android/mms/pdu/NotificationInd.java b/telephony/java/com/google/android/mms/pdu/NotificationInd.java deleted file mode 100644 index b561bd4ab3a7..000000000000 --- a/telephony/java/com/google/android/mms/pdu/NotificationInd.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Notification.ind PDU. - */ -public class NotificationInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public NotificationInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - @UnsupportedAppUsage - NotificationInd(PduHeaders headers) { - super(headers); - } - - /** - * Get X-Mms-Content-Class Value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getContentClass() { - return mPduHeaders.getOctet(PduHeaders.CONTENT_CLASS); - } - - /** - * Set X-Mms-Content-Class Value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setContentClass(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.CONTENT_CLASS); - } - - /** - * Get X-Mms-Content-Location value. - * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf: - * Content-location-value = Uri-value - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getContentLocation() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_LOCATION); - } - - /** - * Set X-Mms-Content-Location value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setContentLocation(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_LOCATION); - } - - /** - * Get X-Mms-Expiry value. - * - * Expiry-value = Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) - * - * @return the value - */ - @UnsupportedAppUsage - public long getExpiry() { - return mPduHeaders.getLongInteger(PduHeaders.EXPIRY); - } - - /** - * Set X-Mms-Expiry value. - * - * @param value the value - * @throws RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setExpiry(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get X-Mms-Message-Size value. - * Message-size-value = Long-integer - * - * @return the value - */ - @UnsupportedAppUsage - public long getMessageSize() { - return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE); - } - - /** - * Set X-Mms-Message-Size value. - * - * @param value the value - * @throws RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setMessageSize(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE); - } - - /** - * Get subject. - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue getSubject() { - return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT); - } - - /** - * Set subject. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setSubject(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT); - } - - /** - * Get X-Mms-Transaction-Id. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /** - * Get X-Mms-Delivery-Report Value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report Value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public byte getDistributionIndicator() {return 0x00;} - * public void setDistributionIndicator(byte value) {} - * - * public ElementDescriptorValue getElementDescriptor() {return null;} - * public void getElementDescriptor(ElementDescriptorValue value) {} - * - * public byte getPriority() {return 0x00;} - * public void setPriority(byte value) {} - * - * public byte getRecommendedRetrievalMode() {return 0x00;} - * public void setRecommendedRetrievalMode(byte value) {} - * - * public byte getRecommendedRetrievalModeText() {return 0x00;} - * public void setRecommendedRetrievalModeText(byte value) {} - * - * public byte[] getReplaceId() {return 0x00;} - * public void setReplaceId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - * - * public byte getStored() {return 0x00;} - * public void setStored(byte value) {} - */ -} diff --git a/telephony/java/com/google/android/mms/pdu/NotifyRespInd.java b/telephony/java/com/google/android/mms/pdu/NotifyRespInd.java deleted file mode 100644 index 3c70f86a0890..000000000000 --- a/telephony/java/com/google/android/mms/pdu/NotifyRespInd.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-NofifyResp.ind PDU. - */ -public class NotifyRespInd extends GenericPdu { - /** - * Constructor, used when composing a M-NotifyResp.ind pdu. - * - * @param mmsVersion current version of mms - * @param transactionId the transaction-id value - * @param status the status value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if transactionId is null. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public NotifyRespInd(int mmsVersion, - byte[] transactionId, - int status) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - setStatus(status); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - @UnsupportedAppUsage - NotifyRespInd(PduHeaders headers) { - super(headers); - } - - /** - * Get X-Mms-Report-Allowed field value. - * - * @return the X-Mms-Report-Allowed value - */ - public int getReportAllowed() { - return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Report-Allowed field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setReportAllowed(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED); - } - - /** - * Set X-Mms-Status field value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.STATUS); - } - - /** - * GetX-Mms-Status field value. - * - * @return the X-Mms-Status value - */ - public int getStatus() { - return mPduHeaders.getOctet(PduHeaders.STATUS); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - * RuntimeException if an undeclared error occurs. - */ - @UnsupportedAppUsage - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } -} diff --git a/telephony/java/com/google/android/mms/pdu/PduBody.java b/telephony/java/com/google/android/mms/pdu/PduBody.java deleted file mode 100644 index 51914e4110b0..000000000000 --- a/telephony/java/com/google/android/mms/pdu/PduBody.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.util.HashMap; -import java.util.Map; -import java.util.Vector; - -public class PduBody { - private Vector<PduPart> mParts = null; - - private Map<String, PduPart> mPartMapByContentId = null; - private Map<String, PduPart> mPartMapByContentLocation = null; - private Map<String, PduPart> mPartMapByName = null; - private Map<String, PduPart> mPartMapByFileName = null; - - /** - * Constructor. - */ - @UnsupportedAppUsage - public PduBody() { - mParts = new Vector<PduPart>(); - - mPartMapByContentId = new HashMap<String, PduPart>(); - mPartMapByContentLocation = new HashMap<String, PduPart>(); - mPartMapByName = new HashMap<String, PduPart>(); - mPartMapByFileName = new HashMap<String, PduPart>(); - } - - private void putPartToMaps(PduPart part) { - // Put part to mPartMapByContentId. - byte[] contentId = part.getContentId(); - if(null != contentId) { - mPartMapByContentId.put(new String(contentId), part); - } - - // Put part to mPartMapByContentLocation. - byte[] contentLocation = part.getContentLocation(); - if(null != contentLocation) { - String clc = new String(contentLocation); - mPartMapByContentLocation.put(clc, part); - } - - // Put part to mPartMapByName. - byte[] name = part.getName(); - if(null != name) { - String clc = new String(name); - mPartMapByName.put(clc, part); - } - - // Put part to mPartMapByFileName. - byte[] fileName = part.getFilename(); - if(null != fileName) { - String clc = new String(fileName); - mPartMapByFileName.put(clc, part); - } - } - - /** - * Appends the specified part to the end of this body. - * - * @param part part to be appended - * @return true when success, false when fail - * @throws NullPointerException when part is null - */ - @UnsupportedAppUsage - public boolean addPart(PduPart part) { - if(null == part) { - throw new NullPointerException(); - } - - putPartToMaps(part); - return mParts.add(part); - } - - /** - * Inserts the specified part at the specified position. - * - * @param index index at which the specified part is to be inserted - * @param part part to be inserted - * @throws NullPointerException when part is null - */ - @UnsupportedAppUsage - public void addPart(int index, PduPart part) { - if(null == part) { - throw new NullPointerException(); - } - - putPartToMaps(part); - mParts.add(index, part); - } - - /** - * Removes the part at the specified position. - * - * @param index index of the part to return - * @return part at the specified index - */ - @UnsupportedAppUsage - public PduPart removePart(int index) { - return mParts.remove(index); - } - - /** - * Remove all of the parts. - */ - public void removeAll() { - mParts.clear(); - } - - /** - * Get the part at the specified position. - * - * @param index index of the part to return - * @return part at the specified index - */ - @UnsupportedAppUsage - public PduPart getPart(int index) { - return mParts.get(index); - } - - /** - * Get the index of the specified part. - * - * @param part the part object - * @return index the index of the first occurrence of the part in this body - */ - @UnsupportedAppUsage - public int getPartIndex(PduPart part) { - return mParts.indexOf(part); - } - - /** - * Get the number of parts. - * - * @return the number of parts - */ - @UnsupportedAppUsage - public int getPartsNum() { - return mParts.size(); - } - - /** - * Get pdu part by content id. - * - * @param cid the value of content id. - * @return the pdu part. - */ - @UnsupportedAppUsage - public PduPart getPartByContentId(String cid) { - return mPartMapByContentId.get(cid); - } - - /** - * Get pdu part by Content-Location. Content-Location of part is - * the same as filename and name(param of content-type). - * - * @param fileName the value of filename. - * @return the pdu part. - */ - @UnsupportedAppUsage - public PduPart getPartByContentLocation(String contentLocation) { - return mPartMapByContentLocation.get(contentLocation); - } - - /** - * Get pdu part by name. - * - * @param fileName the value of filename. - * @return the pdu part. - */ - @UnsupportedAppUsage - public PduPart getPartByName(String name) { - return mPartMapByName.get(name); - } - - /** - * Get pdu part by filename. - * - * @param fileName the value of filename. - * @return the pdu part. - */ - @UnsupportedAppUsage - public PduPart getPartByFileName(String filename) { - return mPartMapByFileName.get(filename); - } -} diff --git a/telephony/java/com/google/android/mms/pdu/PduComposer.java b/telephony/java/com/google/android/mms/pdu/PduComposer.java deleted file mode 100644 index e24bf21a11b5..000000000000 --- a/telephony/java/com/google/android/mms/pdu/PduComposer.java +++ /dev/null @@ -1,1229 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import android.content.ContentResolver; -import android.content.Context; -import android.text.TextUtils; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; - -public class PduComposer { - /** - * Address type. - */ - static private final int PDU_PHONE_NUMBER_ADDRESS_TYPE = 1; - static private final int PDU_EMAIL_ADDRESS_TYPE = 2; - static private final int PDU_IPV4_ADDRESS_TYPE = 3; - static private final int PDU_IPV6_ADDRESS_TYPE = 4; - static private final int PDU_UNKNOWN_ADDRESS_TYPE = 5; - - /** - * Address regular expression string. - */ - static final String REGEXP_PHONE_NUMBER_ADDRESS_TYPE = "\\+?[0-9|\\.|\\-]+"; - static final String REGEXP_EMAIL_ADDRESS_TYPE = "[a-zA-Z| ]*\\<{0,1}[a-zA-Z| ]+@{1}" + - "[a-zA-Z| ]+\\.{1}[a-zA-Z| ]+\\>{0,1}"; - static final String REGEXP_IPV6_ADDRESS_TYPE = - "[a-fA-F]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" + - "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" + - "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}"; - static final String REGEXP_IPV4_ADDRESS_TYPE = "[0-9]{1,3}\\.{1}[0-9]{1,3}\\.{1}" + - "[0-9]{1,3}\\.{1}[0-9]{1,3}"; - - /** - * The postfix strings of address. - */ - static final String STRING_PHONE_NUMBER_ADDRESS_TYPE = "/TYPE=PLMN"; - static final String STRING_IPV4_ADDRESS_TYPE = "/TYPE=IPV4"; - static final String STRING_IPV6_ADDRESS_TYPE = "/TYPE=IPV6"; - - /** - * Error values. - */ - static private final int PDU_COMPOSE_SUCCESS = 0; - static private final int PDU_COMPOSE_CONTENT_ERROR = 1; - static private final int PDU_COMPOSE_FIELD_NOT_SET = 2; - static private final int PDU_COMPOSE_FIELD_NOT_SUPPORTED = 3; - - /** - * WAP values defined in WSP spec. - */ - static private final int QUOTED_STRING_FLAG = 34; - static private final int END_STRING_FLAG = 0; - static private final int LENGTH_QUOTE = 31; - static private final int TEXT_MAX = 127; - static private final int SHORT_INTEGER_MAX = 127; - static private final int LONG_INTEGER_LENGTH_MAX = 8; - - /** - * Block size when read data from InputStream. - */ - static private final int PDU_COMPOSER_BLOCK_SIZE = 1024; - - /** - * The output message. - */ - @UnsupportedAppUsage - protected ByteArrayOutputStream mMessage = null; - - /** - * The PDU. - */ - @UnsupportedAppUsage - private GenericPdu mPdu = null; - - /** - * Current visiting position of the mMessage. - */ - @UnsupportedAppUsage - protected int mPosition = 0; - - /** - * Message compose buffer stack. - */ - @UnsupportedAppUsage - private BufferStack mStack = null; - - /** - * Content resolver. - */ - @UnsupportedAppUsage - private final ContentResolver mResolver; - - /** - * Header of this pdu. - */ - @UnsupportedAppUsage - private PduHeaders mPduHeader = null; - - /** - * Map of all content type - */ - @UnsupportedAppUsage - private static HashMap<String, Integer> mContentTypeMap = null; - - static { - mContentTypeMap = new HashMap<String, Integer>(); - - int i; - for (i = 0; i < PduContentTypes.contentTypes.length; i++) { - mContentTypeMap.put(PduContentTypes.contentTypes[i], i); - } - } - - /** - * Constructor. - * - * @param context the context - * @param pdu the pdu to be composed - */ - @UnsupportedAppUsage - public PduComposer(Context context, GenericPdu pdu) { - mPdu = pdu; - mResolver = context.getContentResolver(); - mPduHeader = pdu.getPduHeaders(); - mStack = new BufferStack(); - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - /** - * Make the message. No need to check whether mandatory fields are set, - * because the constructors of outgoing pdus are taking care of this. - * - * @return OutputStream of maked message. Return null if - * the PDU is invalid. - */ - @UnsupportedAppUsage - public byte[] make() { - // Get Message-type. - int type = mPdu.getMessageType(); - - /* make the message */ - switch (type) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - if (makeSendRetrievePdu(type) != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - if (makeNotifyResp() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - if (makeAckInd() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - if (makeReadRecInd() != PDU_COMPOSE_SUCCESS) { - return null; - } - break; - default: - return null; - } - - return mMessage.toByteArray(); - } - - /** - * Copy buf to mMessage. - */ - @UnsupportedAppUsage - protected void arraycopy(byte[] buf, int pos, int length) { - mMessage.write(buf, pos, length); - mPosition = mPosition + length; - } - - /** - * Append a byte to mMessage. - */ - protected void append(int value) { - mMessage.write(value); - mPosition ++; - } - - /** - * Append short integer value to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendShortInteger(int value) { - /* - * From WAP-230-WSP-20010705-a: - * Short-integer = OCTET - * ; Integers in range 0-127 shall be encoded as a one octet value - * ; with the most significant bit set to one (1xxx xxxx) and with - * ; the value in the remaining least significant bits. - * In our implementation, only low 7 bits are stored and otherwise - * bits are ignored. - */ - append((value | 0x80) & 0xff); - } - - /** - * Append an octet number between 128 and 255 into mMessage. - * NOTE: - * A value between 0 and 127 should be appended by using appendShortInteger. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendOctet(int number) { - append(number); - } - - /** - * Append a short length into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendShortLength(int value) { - /* - * From WAP-230-WSP-20010705-a: - * Short-length = <Any octet 0-30> - */ - append(value); - } - - /** - * Append long integer into mMessage. it's used for really long integers. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendLongInteger(long longInt) { - /* - * From WAP-230-WSP-20010705-a: - * Long-integer = Short-length Multi-octet-integer - * ; The Short-length indicates the length of the Multi-octet-integer - * Multi-octet-integer = 1*30 OCTET - * ; The content octets shall be an unsigned integer value with the - * ; most significant octet encoded first (big-endian representation). - * ; The minimum number of octets must be used to encode the value. - */ - int size; - long temp = longInt; - - // Count the length of the long integer. - for(size = 0; (temp != 0) && (size < LONG_INTEGER_LENGTH_MAX); size++) { - temp = (temp >>> 8); - } - - // Set Length. - appendShortLength(size); - - // Count and set the long integer. - int i; - int shift = (size -1) * 8; - - for (i = 0; i < size; i++) { - append((int)((longInt >>> shift) & 0xff)); - shift = shift - 8; - } - } - - /** - * Append text string into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendTextString(byte[] text) { - /* - * From WAP-230-WSP-20010705-a: - * Text-string = [Quote] *TEXT End-of-string - * ; If the first character in the TEXT is in the range of 128-255, - * ; a Quote character must precede it. Otherwise the Quote character - * ;must be omitted. The Quote is not part of the contents. - */ - if (((text[0])&0xff) > TEXT_MAX) { // No need to check for <= 255 - append(TEXT_MAX); - } - - arraycopy(text, 0, text.length); - append(0); - } - - /** - * Append text string into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendTextString(String str) { - /* - * From WAP-230-WSP-20010705-a: - * Text-string = [Quote] *TEXT End-of-string - * ; If the first character in the TEXT is in the range of 128-255, - * ; a Quote character must precede it. Otherwise the Quote character - * ;must be omitted. The Quote is not part of the contents. - */ - appendTextString(str.getBytes()); - } - - /** - * Append encoded string value to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendEncodedString(EncodedStringValue enStr) { - /* - * From OMA-TS-MMS-ENC-V1_3-20050927-C: - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ - assert(enStr != null); - - int charset = enStr.getCharacterSet(); - byte[] textString = enStr.getTextString(); - if (null == textString) { - return; - } - - /* - * In the implementation of EncodedStringValue, the charset field will - * never be 0. It will always be composed as - * Encoded-string-value = Value-length Char-set Text-string - */ - mStack.newbuf(); - PositionMarker start = mStack.mark(); - - appendShortInteger(charset); - appendTextString(textString); - - int len = start.getLength(); - mStack.pop(); - appendValueLength(len); - mStack.copy(); - } - - /** - * Append uintvar integer into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendUintvarInteger(long value) { - /* - * From WAP-230-WSP-20010705-a: - * To encode a large unsigned integer, split it into 7-bit fragments - * and place them in the payloads of multiple octets. The most significant - * bits are placed in the first octets with the least significant bits - * ending up in the last octet. All octets MUST set the Continue bit to 1 - * except the last octet, which MUST set the Continue bit to 0. - */ - int i; - long max = SHORT_INTEGER_MAX; - - for (i = 0; i < 5; i++) { - if (value < max) { - break; - } - - max = (max << 7) | 0x7fl; - } - - while(i > 0) { - long temp = value >>> (i * 7); - temp = temp & 0x7f; - - append((int)((temp | 0x80) & 0xff)); - - i--; - } - - append((int)(value & 0x7f)); - } - - /** - * Append date value into mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - protected void appendDateValue(long date) { - /* - * From OMA-TS-MMS-ENC-V1_3-20050927-C: - * Date-value = Long-integer - */ - appendLongInteger(date); - } - - /** - * Append value length to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendValueLength(long value) { - /* - * From WAP-230-WSP-20010705-a: - * Value-length = Short-length | (Length-quote Length) - * ; Value length is used to indicate the length of the value to follow - * Short-length = <Any octet 0-30> - * Length-quote = <Octet 31> - * Length = Uintvar-integer - */ - if (value < LENGTH_QUOTE) { - appendShortLength((int) value); - return; - } - - append(LENGTH_QUOTE); - appendUintvarInteger(value); - } - - /** - * Append quoted string to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendQuotedString(byte[] text) { - /* - * From WAP-230-WSP-20010705-a: - * Quoted-string = <Octet 34> *TEXT End-of-string - * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing - * ;quotation-marks <"> removed. - */ - append(QUOTED_STRING_FLAG); - arraycopy(text, 0, text.length); - append(END_STRING_FLAG); - } - - /** - * Append quoted string to mMessage. - * This implementation doesn't check the validity of parameter, since it - * assumes that the values are validated in the GenericPdu setter methods. - */ - @UnsupportedAppUsage - protected void appendQuotedString(String str) { - /* - * From WAP-230-WSP-20010705-a: - * Quoted-string = <Octet 34> *TEXT End-of-string - * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing - * ;quotation-marks <"> removed. - */ - appendQuotedString(str.getBytes()); - } - - private EncodedStringValue appendAddressType(EncodedStringValue address) { - EncodedStringValue temp = null; - - try { - int addressType = checkAddressType(address.getString()); - temp = EncodedStringValue.copy(address); - if (PDU_PHONE_NUMBER_ADDRESS_TYPE == addressType) { - // Phone number. - temp.appendTextString(STRING_PHONE_NUMBER_ADDRESS_TYPE.getBytes()); - } else if (PDU_IPV4_ADDRESS_TYPE == addressType) { - // Ipv4 address. - temp.appendTextString(STRING_IPV4_ADDRESS_TYPE.getBytes()); - } else if (PDU_IPV6_ADDRESS_TYPE == addressType) { - // Ipv6 address. - temp.appendTextString(STRING_IPV6_ADDRESS_TYPE.getBytes()); - } - } catch (NullPointerException e) { - return null; - } - - return temp; - } - - /** - * Append header to mMessage. - */ - @UnsupportedAppUsage - private int appendHeader(int field) { - switch (field) { - case PduHeaders.MMS_VERSION: - appendOctet(field); - - int version = mPduHeader.getOctet(field); - if (0 == version) { - appendShortInteger(PduHeaders.CURRENT_MMS_VERSION); - } else { - appendShortInteger(version); - } - - break; - - case PduHeaders.MESSAGE_ID: - case PduHeaders.TRANSACTION_ID: - byte[] textString = mPduHeader.getTextString(field); - if (null == textString) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendTextString(textString); - break; - - case PduHeaders.TO: - case PduHeaders.BCC: - case PduHeaders.CC: - EncodedStringValue[] addr = mPduHeader.getEncodedStringValues(field); - - if (null == addr) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - EncodedStringValue temp; - for (int i = 0; i < addr.length; i++) { - temp = appendAddressType(addr[i]); - if (temp == null) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendOctet(field); - appendEncodedString(temp); - } - break; - - case PduHeaders.FROM: - // Value-length (Address-present-token Encoded-string-value | Insert-address-token) - appendOctet(field); - - EncodedStringValue from = mPduHeader.getEncodedStringValue(field); - if ((from == null) - || TextUtils.isEmpty(from.getString()) - || new String(from.getTextString()).equals( - PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) { - // Length of from = 1 - append(1); - // Insert-address-token = <Octet 129> - append(PduHeaders.FROM_INSERT_ADDRESS_TOKEN); - } else { - mStack.newbuf(); - PositionMarker fstart = mStack.mark(); - - // Address-present-token = <Octet 128> - append(PduHeaders.FROM_ADDRESS_PRESENT_TOKEN); - - temp = appendAddressType(from); - if (temp == null) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendEncodedString(temp); - - int flen = fstart.getLength(); - mStack.pop(); - appendValueLength(flen); - mStack.copy(); - } - break; - - case PduHeaders.READ_STATUS: - case PduHeaders.STATUS: - case PduHeaders.REPORT_ALLOWED: - case PduHeaders.PRIORITY: - case PduHeaders.DELIVERY_REPORT: - case PduHeaders.READ_REPORT: - case PduHeaders.RETRIEVE_STATUS: - int octet = mPduHeader.getOctet(field); - if (0 == octet) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendOctet(octet); - break; - - case PduHeaders.DATE: - long date = mPduHeader.getLongInteger(field); - if (-1 == date) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendDateValue(date); - break; - - case PduHeaders.SUBJECT: - case PduHeaders.RETRIEVE_TEXT: - EncodedStringValue enString = - mPduHeader.getEncodedStringValue(field); - if (null == enString) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - appendEncodedString(enString); - break; - - case PduHeaders.MESSAGE_CLASS: - byte[] messageClass = mPduHeader.getTextString(field); - if (null == messageClass) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_ADVERTISEMENT); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_AUTO); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_PERSONAL); - } else if (Arrays.equals(messageClass, - PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes())) { - appendOctet(PduHeaders.MESSAGE_CLASS_INFORMATIONAL); - } else { - appendTextString(messageClass); - } - break; - - case PduHeaders.EXPIRY: - long expiry = mPduHeader.getLongInteger(field); - if (-1 == expiry) { - return PDU_COMPOSE_FIELD_NOT_SET; - } - - appendOctet(field); - - mStack.newbuf(); - PositionMarker expiryStart = mStack.mark(); - - append(PduHeaders.VALUE_RELATIVE_TOKEN); - appendLongInteger(expiry); - - int expiryLength = expiryStart.getLength(); - mStack.pop(); - appendValueLength(expiryLength); - mStack.copy(); - break; - - default: - return PDU_COMPOSE_FIELD_NOT_SUPPORTED; - } - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make ReadRec.Ind. - */ - private int makeReadRecInd() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_READ_REC_IND); - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Message-ID - if (appendHeader(PduHeaders.MESSAGE_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // To - if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // From - if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Date Optional - appendHeader(PduHeaders.DATE); - - // X-Mms-Read-Status - if (appendHeader(PduHeaders.READ_STATUS) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Applic-ID Optional(not support) - // X-Mms-Reply-Applic-ID Optional(not support) - // X-Mms-Aux-Applic-Info Optional(not support) - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make NotifyResp.Ind. - */ - private int makeNotifyResp() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND); - - // X-Mms-Transaction-ID - if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Status - if (appendHeader(PduHeaders.STATUS) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Report-Allowed Optional (not support) - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make Acknowledge.Ind. - */ - private int makeAckInd() { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND); - - // X-Mms-Transaction-ID - if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // X-Mms-Report-Allowed Optional - appendHeader(PduHeaders.REPORT_ALLOWED); - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Make Send.req. - */ - private int makeSendRetrievePdu(int type) { - if (mMessage == null) { - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - // X-Mms-Message-Type - appendOctet(PduHeaders.MESSAGE_TYPE); - appendOctet(type); - - // X-Mms-Transaction-ID - appendOctet(PduHeaders.TRANSACTION_ID); - - byte[] trid = mPduHeader.getTextString(PduHeaders.TRANSACTION_ID); - if (trid == null) { - // Transaction-ID should be set(by Transaction) before make(). - throw new IllegalArgumentException("Transaction-ID is null."); - } - appendTextString(trid); - - // X-Mms-MMS-Version - if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Date Date-value Optional. - appendHeader(PduHeaders.DATE); - - // From - if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - boolean recipient = false; - - // To - if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Cc - if (appendHeader(PduHeaders.CC) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Bcc - if (appendHeader(PduHeaders.BCC) != PDU_COMPOSE_CONTENT_ERROR) { - recipient = true; - } - - // Need at least one of "cc", "bcc" and "to". - if (false == recipient) { - return PDU_COMPOSE_CONTENT_ERROR; - } - - // Subject Optional - appendHeader(PduHeaders.SUBJECT); - - // X-Mms-Message-Class Optional - // Message-class-value = Class-identifier | Token-text - appendHeader(PduHeaders.MESSAGE_CLASS); - - // X-Mms-Expiry Optional - appendHeader(PduHeaders.EXPIRY); - - // X-Mms-Priority Optional - appendHeader(PduHeaders.PRIORITY); - - // X-Mms-Delivery-Report Optional - appendHeader(PduHeaders.DELIVERY_REPORT); - - // X-Mms-Read-Report Optional - appendHeader(PduHeaders.READ_REPORT); - - if (type == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) { - // X-Mms-Retrieve-Status Optional - appendHeader(PduHeaders.RETRIEVE_STATUS); - // X-Mms-Retrieve-Text Optional - appendHeader(PduHeaders.RETRIEVE_TEXT); - } - - - // Content-Type - appendOctet(PduHeaders.CONTENT_TYPE); - - // Message body - return makeMessageBody(type); - } - - /** - * Make message body. - */ - private int makeMessageBody(int type) { - // 1. add body informations - mStack.newbuf(); // Switching buffer because we need to - - PositionMarker ctStart = mStack.mark(); - - // This contentTypeIdentifier should be used for type of attachment... - String contentType = new String(mPduHeader.getTextString(PduHeaders.CONTENT_TYPE)); - Integer contentTypeIdentifier = mContentTypeMap.get(contentType); - if (contentTypeIdentifier == null) { - // content type is mandatory - return PDU_COMPOSE_CONTENT_ERROR; - } - - appendShortInteger(contentTypeIdentifier.intValue()); - - // content-type parameter: start - PduBody body; - if (type == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) { - body = ((RetrieveConf) mPdu).getBody(); - } else { - body = ((SendReq) mPdu).getBody(); - } - if (null == body || body.getPartsNum() == 0) { - // empty message - appendUintvarInteger(0); - mStack.pop(); - mStack.copy(); - return PDU_COMPOSE_SUCCESS; - } - - PduPart part; - try { - part = body.getPart(0); - - byte[] start = part.getContentId(); - if (start != null) { - appendOctet(PduPart.P_DEP_START); - if (('<' == start[0]) && ('>' == start[start.length - 1])) { - appendTextString(start); - } else { - appendTextString("<" + new String(start) + ">"); - } - } - - // content-type parameter: type - appendOctet(PduPart.P_CT_MR_TYPE); - appendTextString(part.getContentType()); - } - catch (ArrayIndexOutOfBoundsException e){ - e.printStackTrace(); - } - - int ctLength = ctStart.getLength(); - mStack.pop(); - appendValueLength(ctLength); - mStack.copy(); - - // 3. add content - int partNum = body.getPartsNum(); - appendUintvarInteger(partNum); - for (int i = 0; i < partNum; i++) { - part = body.getPart(i); - mStack.newbuf(); // Leaving space for header lengh and data length - PositionMarker attachment = mStack.mark(); - - mStack.newbuf(); // Leaving space for Content-Type length - PositionMarker contentTypeBegin = mStack.mark(); - - byte[] partContentType = part.getContentType(); - - if (partContentType == null) { - // content type is mandatory - return PDU_COMPOSE_CONTENT_ERROR; - } - - // content-type value - Integer partContentTypeIdentifier = - mContentTypeMap.get(new String(partContentType)); - if (partContentTypeIdentifier == null) { - appendTextString(partContentType); - } else { - appendShortInteger(partContentTypeIdentifier.intValue()); - } - - /* Content-type parameter : name. - * The value of name, filename, content-location is the same. - * Just one of them is enough for this PDU. - */ - byte[] name = part.getName(); - - if (null == name) { - name = part.getFilename(); - - if (null == name) { - name = part.getContentLocation(); - - if (null == name) { - /* at lease one of name, filename, Content-location - * should be available. - */ - return PDU_COMPOSE_CONTENT_ERROR; - } - } - } - appendOctet(PduPart.P_DEP_NAME); - appendTextString(name); - - // content-type parameter : charset - int charset = part.getCharset(); - if (charset != 0) { - appendOctet(PduPart.P_CHARSET); - appendShortInteger(charset); - } - - int contentTypeLength = contentTypeBegin.getLength(); - mStack.pop(); - appendValueLength(contentTypeLength); - mStack.copy(); - - // content id - byte[] contentId = part.getContentId(); - - if (null != contentId) { - appendOctet(PduPart.P_CONTENT_ID); - if (('<' == contentId[0]) && ('>' == contentId[contentId.length - 1])) { - appendQuotedString(contentId); - } else { - appendQuotedString("<" + new String(contentId) + ">"); - } - } - - // content-location - byte[] contentLocation = part.getContentLocation(); - if (null != contentLocation) { - appendOctet(PduPart.P_CONTENT_LOCATION); - appendTextString(contentLocation); - } - - // content - int headerLength = attachment.getLength(); - - int dataLength = 0; // Just for safety... - byte[] partData = part.getData(); - - if (partData != null) { - arraycopy(partData, 0, partData.length); - dataLength = partData.length; - } else { - InputStream cr = null; - try { - byte[] buffer = new byte[PDU_COMPOSER_BLOCK_SIZE]; - cr = mResolver.openInputStream(part.getDataUri()); - int len = 0; - while ((len = cr.read(buffer)) != -1) { - mMessage.write(buffer, 0, len); - mPosition += len; - dataLength += len; - } - } catch (FileNotFoundException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } catch (IOException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } catch (RuntimeException e) { - return PDU_COMPOSE_CONTENT_ERROR; - } finally { - if (cr != null) { - try { - cr.close(); - } catch (IOException e) { - } - } - } - } - - if (dataLength != (attachment.getLength() - headerLength)) { - throw new RuntimeException("BUG: Length sanity check failed"); - } - - mStack.pop(); - appendUintvarInteger(headerLength); - appendUintvarInteger(dataLength); - mStack.copy(); - } - - return PDU_COMPOSE_SUCCESS; - } - - /** - * Record current message informations. - */ - static private class LengthRecordNode { - ByteArrayOutputStream currentMessage = null; - public int currentPosition = 0; - - public LengthRecordNode next = null; - } - - /** - * Mark current message position and stact size. - */ - private class PositionMarker { - private int c_pos; // Current position - private int currentStackSize; // Current stack size - - @UnsupportedAppUsage - int getLength() { - // If these assert fails, likely that you are finding the - // size of buffer that is deep in BufferStack you can only - // find the length of the buffer that is on top - if (currentStackSize != mStack.stackSize) { - throw new RuntimeException("BUG: Invalid call to getLength()"); - } - - return mPosition - c_pos; - } - } - - /** - * This implementation can be OPTIMIZED to use only - * 2 buffers. This optimization involves changing BufferStack - * only... Its usage (interface) will not change. - */ - private class BufferStack { - private LengthRecordNode stack = null; - private LengthRecordNode toCopy = null; - - int stackSize = 0; - - /** - * Create a new message buffer and push it into the stack. - */ - @UnsupportedAppUsage - void newbuf() { - // You can't create a new buff when toCopy != null - // That is after calling pop() and before calling copy() - // If you do, it is a bug - if (toCopy != null) { - throw new RuntimeException("BUG: Invalid newbuf() before copy()"); - } - - LengthRecordNode temp = new LengthRecordNode(); - - temp.currentMessage = mMessage; - temp.currentPosition = mPosition; - - temp.next = stack; - stack = temp; - - stackSize = stackSize + 1; - - mMessage = new ByteArrayOutputStream(); - mPosition = 0; - } - - /** - * Pop the message before and record current message in the stack. - */ - @UnsupportedAppUsage - void pop() { - ByteArrayOutputStream currentMessage = mMessage; - int currentPosition = mPosition; - - mMessage = stack.currentMessage; - mPosition = stack.currentPosition; - - toCopy = stack; - // Re using the top element of the stack to avoid memory allocation - - stack = stack.next; - stackSize = stackSize - 1; - - toCopy.currentMessage = currentMessage; - toCopy.currentPosition = currentPosition; - } - - /** - * Append current message to the message before. - */ - @UnsupportedAppUsage - void copy() { - arraycopy(toCopy.currentMessage.toByteArray(), 0, - toCopy.currentPosition); - - toCopy = null; - } - - /** - * Mark current message position - */ - @UnsupportedAppUsage - PositionMarker mark() { - PositionMarker m = new PositionMarker(); - - m.c_pos = mPosition; - m.currentStackSize = stackSize; - - return m; - } - } - - /** - * Check address type. - * - * @param address address string without the postfix stinng type, - * such as "/TYPE=PLMN", "/TYPE=IPv6" and "/TYPE=IPv4" - * @return PDU_PHONE_NUMBER_ADDRESS_TYPE if it is phone number, - * PDU_EMAIL_ADDRESS_TYPE if it is email address, - * PDU_IPV4_ADDRESS_TYPE if it is ipv4 address, - * PDU_IPV6_ADDRESS_TYPE if it is ipv6 address, - * PDU_UNKNOWN_ADDRESS_TYPE if it is unknown. - */ - protected static int checkAddressType(String address) { - /** - * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf, section 8. - * address = ( e-mail / device-address / alphanum-shortcode / num-shortcode) - * e-mail = mailbox; to the definition of mailbox as described in - * section 3.4 of [RFC2822], but excluding the - * obsolete definitions as indicated by the "obs-" prefix. - * device-address = ( global-phone-number "/TYPE=PLMN" ) - * / ( ipv4 "/TYPE=IPv4" ) / ( ipv6 "/TYPE=IPv6" ) - * / ( escaped-value "/TYPE=" address-type ) - * - * global-phone-number = ["+"] 1*( DIGIT / written-sep ) - * written-sep =("-"/".") - * - * ipv4 = 1*3DIGIT 3( "." 1*3DIGIT ) ; IPv4 address value - * - * ipv6 = 4HEXDIG 7( ":" 4HEXDIG ) ; IPv6 address per RFC 2373 - */ - - if (null == address) { - return PDU_UNKNOWN_ADDRESS_TYPE; - } - - if (address.matches(REGEXP_IPV4_ADDRESS_TYPE)) { - // Ipv4 address. - return PDU_IPV4_ADDRESS_TYPE; - }else if (address.matches(REGEXP_PHONE_NUMBER_ADDRESS_TYPE)) { - // Phone number. - return PDU_PHONE_NUMBER_ADDRESS_TYPE; - } else if (address.matches(REGEXP_EMAIL_ADDRESS_TYPE)) { - // Email address. - return PDU_EMAIL_ADDRESS_TYPE; - } else if (address.matches(REGEXP_IPV6_ADDRESS_TYPE)) { - // Ipv6 address. - return PDU_IPV6_ADDRESS_TYPE; - } else { - // Unknown address. - return PDU_UNKNOWN_ADDRESS_TYPE; - } - } -} diff --git a/telephony/java/com/google/android/mms/pdu/PduContentTypes.java b/telephony/java/com/google/android/mms/pdu/PduContentTypes.java deleted file mode 100644 index 8551b2f9b693..000000000000 --- a/telephony/java/com/google/android/mms/pdu/PduContentTypes.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -public class PduContentTypes { - /** - * All content types. From: - * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.htm - */ - @UnsupportedAppUsage - static final String[] contentTypes = { - "*/*", /* 0x00 */ - "text/*", /* 0x01 */ - "text/html", /* 0x02 */ - "text/plain", /* 0x03 */ - "text/x-hdml", /* 0x04 */ - "text/x-ttml", /* 0x05 */ - "text/x-vCalendar", /* 0x06 */ - "text/x-vCard", /* 0x07 */ - "text/vnd.wap.wml", /* 0x08 */ - "text/vnd.wap.wmlscript", /* 0x09 */ - "text/vnd.wap.wta-event", /* 0x0A */ - "multipart/*", /* 0x0B */ - "multipart/mixed", /* 0x0C */ - "multipart/form-data", /* 0x0D */ - "multipart/byterantes", /* 0x0E */ - "multipart/alternative", /* 0x0F */ - "application/*", /* 0x10 */ - "application/java-vm", /* 0x11 */ - "application/x-www-form-urlencoded", /* 0x12 */ - "application/x-hdmlc", /* 0x13 */ - "application/vnd.wap.wmlc", /* 0x14 */ - "application/vnd.wap.wmlscriptc", /* 0x15 */ - "application/vnd.wap.wta-eventc", /* 0x16 */ - "application/vnd.wap.uaprof", /* 0x17 */ - "application/vnd.wap.wtls-ca-certificate", /* 0x18 */ - "application/vnd.wap.wtls-user-certificate", /* 0x19 */ - "application/x-x509-ca-cert", /* 0x1A */ - "application/x-x509-user-cert", /* 0x1B */ - "image/*", /* 0x1C */ - "image/gif", /* 0x1D */ - "image/jpeg", /* 0x1E */ - "image/tiff", /* 0x1F */ - "image/png", /* 0x20 */ - "image/vnd.wap.wbmp", /* 0x21 */ - "application/vnd.wap.multipart.*", /* 0x22 */ - "application/vnd.wap.multipart.mixed", /* 0x23 */ - "application/vnd.wap.multipart.form-data", /* 0x24 */ - "application/vnd.wap.multipart.byteranges", /* 0x25 */ - "application/vnd.wap.multipart.alternative", /* 0x26 */ - "application/xml", /* 0x27 */ - "text/xml", /* 0x28 */ - "application/vnd.wap.wbxml", /* 0x29 */ - "application/x-x968-cross-cert", /* 0x2A */ - "application/x-x968-ca-cert", /* 0x2B */ - "application/x-x968-user-cert", /* 0x2C */ - "text/vnd.wap.si", /* 0x2D */ - "application/vnd.wap.sic", /* 0x2E */ - "text/vnd.wap.sl", /* 0x2F */ - "application/vnd.wap.slc", /* 0x30 */ - "text/vnd.wap.co", /* 0x31 */ - "application/vnd.wap.coc", /* 0x32 */ - "application/vnd.wap.multipart.related", /* 0x33 */ - "application/vnd.wap.sia", /* 0x34 */ - "text/vnd.wap.connectivity-xml", /* 0x35 */ - "application/vnd.wap.connectivity-wbxml", /* 0x36 */ - "application/pkcs7-mime", /* 0x37 */ - "application/vnd.wap.hashed-certificate", /* 0x38 */ - "application/vnd.wap.signed-certificate", /* 0x39 */ - "application/vnd.wap.cert-response", /* 0x3A */ - "application/xhtml+xml", /* 0x3B */ - "application/wml+xml", /* 0x3C */ - "text/css", /* 0x3D */ - "application/vnd.wap.mms-message", /* 0x3E */ - "application/vnd.wap.rollover-certificate", /* 0x3F */ - "application/vnd.wap.locc+wbxml", /* 0x40 */ - "application/vnd.wap.loc+xml", /* 0x41 */ - "application/vnd.syncml.dm+wbxml", /* 0x42 */ - "application/vnd.syncml.dm+xml", /* 0x43 */ - "application/vnd.syncml.notification", /* 0x44 */ - "application/vnd.wap.xhtml+xml", /* 0x45 */ - "application/vnd.wv.csp.cir", /* 0x46 */ - "application/vnd.oma.dd+xml", /* 0x47 */ - "application/vnd.oma.drm.message", /* 0x48 */ - "application/vnd.oma.drm.content", /* 0x49 */ - "application/vnd.oma.drm.rights+xml", /* 0x4A */ - "application/vnd.oma.drm.rights+wbxml", /* 0x4B */ - "application/vnd.wv.csp+xml", /* 0x4C */ - "application/vnd.wv.csp+wbxml", /* 0x4D */ - "application/vnd.syncml.ds.notification", /* 0x4E */ - "audio/*", /* 0x4F */ - "video/*", /* 0x50 */ - "application/vnd.oma.dd2+xml", /* 0x51 */ - "application/mikey" /* 0x52 */ - }; -} diff --git a/telephony/java/com/google/android/mms/pdu/PduHeaders.java b/telephony/java/com/google/android/mms/pdu/PduHeaders.java deleted file mode 100644 index b5244645fda1..000000000000 --- a/telephony/java/com/google/android/mms/pdu/PduHeaders.java +++ /dev/null @@ -1,733 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -import java.util.ArrayList; -import java.util.HashMap; - -public class PduHeaders { - /** - * All pdu header fields. - */ - public static final int BCC = 0x81; - public static final int CC = 0x82; - public static final int CONTENT_LOCATION = 0x83; - public static final int CONTENT_TYPE = 0x84; - public static final int DATE = 0x85; - public static final int DELIVERY_REPORT = 0x86; - public static final int DELIVERY_TIME = 0x87; - public static final int EXPIRY = 0x88; - public static final int FROM = 0x89; - public static final int MESSAGE_CLASS = 0x8A; - public static final int MESSAGE_ID = 0x8B; - public static final int MESSAGE_TYPE = 0x8C; - public static final int MMS_VERSION = 0x8D; - public static final int MESSAGE_SIZE = 0x8E; - public static final int PRIORITY = 0x8F; - - public static final int READ_REPLY = 0x90; - public static final int READ_REPORT = 0x90; - public static final int REPORT_ALLOWED = 0x91; - public static final int RESPONSE_STATUS = 0x92; - public static final int RESPONSE_TEXT = 0x93; - public static final int SENDER_VISIBILITY = 0x94; - public static final int STATUS = 0x95; - public static final int SUBJECT = 0x96; - public static final int TO = 0x97; - public static final int TRANSACTION_ID = 0x98; - public static final int RETRIEVE_STATUS = 0x99; - public static final int RETRIEVE_TEXT = 0x9A; - public static final int READ_STATUS = 0x9B; - public static final int REPLY_CHARGING = 0x9C; - public static final int REPLY_CHARGING_DEADLINE = 0x9D; - public static final int REPLY_CHARGING_ID = 0x9E; - public static final int REPLY_CHARGING_SIZE = 0x9F; - - public static final int PREVIOUSLY_SENT_BY = 0xA0; - public static final int PREVIOUSLY_SENT_DATE = 0xA1; - public static final int STORE = 0xA2; - public static final int MM_STATE = 0xA3; - public static final int MM_FLAGS = 0xA4; - public static final int STORE_STATUS = 0xA5; - public static final int STORE_STATUS_TEXT = 0xA6; - public static final int STORED = 0xA7; - public static final int ATTRIBUTES = 0xA8; - public static final int TOTALS = 0xA9; - public static final int MBOX_TOTALS = 0xAA; - public static final int QUOTAS = 0xAB; - public static final int MBOX_QUOTAS = 0xAC; - public static final int MESSAGE_COUNT = 0xAD; - public static final int CONTENT = 0xAE; - public static final int START = 0xAF; - - public static final int ADDITIONAL_HEADERS = 0xB0; - public static final int DISTRIBUTION_INDICATOR = 0xB1; - public static final int ELEMENT_DESCRIPTOR = 0xB2; - public static final int LIMIT = 0xB3; - public static final int RECOMMENDED_RETRIEVAL_MODE = 0xB4; - public static final int RECOMMENDED_RETRIEVAL_MODE_TEXT = 0xB5; - public static final int STATUS_TEXT = 0xB6; - public static final int APPLIC_ID = 0xB7; - public static final int REPLY_APPLIC_ID = 0xB8; - public static final int AUX_APPLIC_ID = 0xB9; - public static final int CONTENT_CLASS = 0xBA; - public static final int DRM_CONTENT = 0xBB; - public static final int ADAPTATION_ALLOWED = 0xBC; - public static final int REPLACE_ID = 0xBD; - public static final int CANCEL_ID = 0xBE; - public static final int CANCEL_STATUS = 0xBF; - - /** - * X-Mms-Message-Type field types. - */ - public static final int MESSAGE_TYPE_SEND_REQ = 0x80; - public static final int MESSAGE_TYPE_SEND_CONF = 0x81; - public static final int MESSAGE_TYPE_NOTIFICATION_IND = 0x82; - public static final int MESSAGE_TYPE_NOTIFYRESP_IND = 0x83; - public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84; - public static final int MESSAGE_TYPE_ACKNOWLEDGE_IND = 0x85; - public static final int MESSAGE_TYPE_DELIVERY_IND = 0x86; - public static final int MESSAGE_TYPE_READ_REC_IND = 0x87; - public static final int MESSAGE_TYPE_READ_ORIG_IND = 0x88; - public static final int MESSAGE_TYPE_FORWARD_REQ = 0x89; - public static final int MESSAGE_TYPE_FORWARD_CONF = 0x8A; - public static final int MESSAGE_TYPE_MBOX_STORE_REQ = 0x8B; - public static final int MESSAGE_TYPE_MBOX_STORE_CONF = 0x8C; - public static final int MESSAGE_TYPE_MBOX_VIEW_REQ = 0x8D; - public static final int MESSAGE_TYPE_MBOX_VIEW_CONF = 0x8E; - public static final int MESSAGE_TYPE_MBOX_UPLOAD_REQ = 0x8F; - public static final int MESSAGE_TYPE_MBOX_UPLOAD_CONF = 0x90; - public static final int MESSAGE_TYPE_MBOX_DELETE_REQ = 0x91; - public static final int MESSAGE_TYPE_MBOX_DELETE_CONF = 0x92; - public static final int MESSAGE_TYPE_MBOX_DESCR = 0x93; - public static final int MESSAGE_TYPE_DELETE_REQ = 0x94; - public static final int MESSAGE_TYPE_DELETE_CONF = 0x95; - public static final int MESSAGE_TYPE_CANCEL_REQ = 0x96; - public static final int MESSAGE_TYPE_CANCEL_CONF = 0x97; - - /** - * X-Mms-Delivery-Report | - * X-Mms-Read-Report | - * X-Mms-Report-Allowed | - * X-Mms-Sender-Visibility | - * X-Mms-Store | - * X-Mms-Stored | - * X-Mms-Totals | - * X-Mms-Quotas | - * X-Mms-Distribution-Indicator | - * X-Mms-DRM-Content | - * X-Mms-Adaptation-Allowed | - * field types. - */ - public static final int VALUE_YES = 0x80; - public static final int VALUE_NO = 0x81; - - /** - * Delivery-Time | - * Expiry and Reply-Charging-Deadline | - * field type components. - */ - public static final int VALUE_ABSOLUTE_TOKEN = 0x80; - public static final int VALUE_RELATIVE_TOKEN = 0x81; - - /** - * X-Mms-MMS-Version field types. - */ - public static final int MMS_VERSION_1_3 = ((1 << 4) | 3); - public static final int MMS_VERSION_1_2 = ((1 << 4) | 2); - public static final int MMS_VERSION_1_1 = ((1 << 4) | 1); - public static final int MMS_VERSION_1_0 = ((1 << 4) | 0); - - // Current version is 1.2. - public static final int CURRENT_MMS_VERSION = MMS_VERSION_1_2; - - /** - * From field type components. - */ - public static final int FROM_ADDRESS_PRESENT_TOKEN = 0x80; - public static final int FROM_INSERT_ADDRESS_TOKEN = 0x81; - - public static final String FROM_ADDRESS_PRESENT_TOKEN_STR = "address-present-token"; - public static final String FROM_INSERT_ADDRESS_TOKEN_STR = "insert-address-token"; - - /** - * X-Mms-Status Field. - */ - public static final int STATUS_EXPIRED = 0x80; - public static final int STATUS_RETRIEVED = 0x81; - public static final int STATUS_REJECTED = 0x82; - public static final int STATUS_DEFERRED = 0x83; - public static final int STATUS_UNRECOGNIZED = 0x84; - public static final int STATUS_INDETERMINATE = 0x85; - public static final int STATUS_FORWARDED = 0x86; - public static final int STATUS_UNREACHABLE = 0x87; - - /** - * MM-Flags field type components. - */ - public static final int MM_FLAGS_ADD_TOKEN = 0x80; - public static final int MM_FLAGS_REMOVE_TOKEN = 0x81; - public static final int MM_FLAGS_FILTER_TOKEN = 0x82; - - /** - * X-Mms-Message-Class field types. - */ - public static final int MESSAGE_CLASS_PERSONAL = 0x80; - public static final int MESSAGE_CLASS_ADVERTISEMENT = 0x81; - public static final int MESSAGE_CLASS_INFORMATIONAL = 0x82; - public static final int MESSAGE_CLASS_AUTO = 0x83; - - public static final String MESSAGE_CLASS_PERSONAL_STR = "personal"; - public static final String MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement"; - public static final String MESSAGE_CLASS_INFORMATIONAL_STR = "informational"; - public static final String MESSAGE_CLASS_AUTO_STR = "auto"; - - /** - * X-Mms-Priority field types. - */ - public static final int PRIORITY_LOW = 0x80; - public static final int PRIORITY_NORMAL = 0x81; - public static final int PRIORITY_HIGH = 0x82; - - /** - * X-Mms-Response-Status field types. - */ - public static final int RESPONSE_STATUS_OK = 0x80; - public static final int RESPONSE_STATUS_ERROR_UNSPECIFIED = 0x81; - public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82; - - public static final int RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT = 0x83; - public static final int RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED = 0x84; - - public static final int RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND = 0x85; - public static final int RESPONSE_STATUS_ERROR_NETWORK_PROBLEM = 0x86; - public static final int RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED = 0x87; - public static final int RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE = 0x88; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_SENDNG_ADDRESS_UNRESOLVED = 0xC1; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC2; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC3; - public static final int RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS = 0xC4; - - public static final int RESPONSE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED = 0xE3; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE4; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED = 0xE5; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET = 0xE6; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED = 0xE6; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED = 0xE8; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED = 0xE9; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED = 0xEA; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID = 0xEB; - public static final int RESPONSE_STATUS_ERROR_PERMANENT_END = 0xFF; - - /** - * X-Mms-Retrieve-Status field types. - */ - public static final int RETRIEVE_STATUS_OK = 0x80; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC1; - public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC2; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE2; - public static final int RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 0xE3; - public static final int RETRIEVE_STATUS_ERROR_END = 0xFF; - - /** - * X-Mms-Sender-Visibility field types. - */ - public static final int SENDER_VISIBILITY_HIDE = 0x80; - public static final int SENDER_VISIBILITY_SHOW = 0x81; - - /** - * X-Mms-Read-Status field types. - */ - public static final int READ_STATUS_READ = 0x80; - public static final int READ_STATUS__DELETED_WITHOUT_BEING_READ = 0x81; - - /** - * X-Mms-Cancel-Status field types. - */ - public static final int CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED = 0x80; - public static final int CANCEL_STATUS_REQUEST_CORRUPTED = 0x81; - - /** - * X-Mms-Reply-Charging field types. - */ - public static final int REPLY_CHARGING_REQUESTED = 0x80; - public static final int REPLY_CHARGING_REQUESTED_TEXT_ONLY = 0x81; - public static final int REPLY_CHARGING_ACCEPTED = 0x82; - public static final int REPLY_CHARGING_ACCEPTED_TEXT_ONLY = 0x83; - - /** - * X-Mms-MM-State field types. - */ - public static final int MM_STATE_DRAFT = 0x80; - public static final int MM_STATE_SENT = 0x81; - public static final int MM_STATE_NEW = 0x82; - public static final int MM_STATE_RETRIEVED = 0x83; - public static final int MM_STATE_FORWARDED = 0x84; - - /** - * X-Mms-Recommended-Retrieval-Mode field types. - */ - public static final int RECOMMENDED_RETRIEVAL_MODE_MANUAL = 0x80; - - /** - * X-Mms-Content-Class field types. - */ - public static final int CONTENT_CLASS_TEXT = 0x80; - public static final int CONTENT_CLASS_IMAGE_BASIC = 0x81; - public static final int CONTENT_CLASS_IMAGE_RICH = 0x82; - public static final int CONTENT_CLASS_VIDEO_BASIC = 0x83; - public static final int CONTENT_CLASS_VIDEO_RICH = 0x84; - public static final int CONTENT_CLASS_MEGAPIXEL = 0x85; - public static final int CONTENT_CLASS_CONTENT_BASIC = 0x86; - public static final int CONTENT_CLASS_CONTENT_RICH = 0x87; - - /** - * X-Mms-Store-Status field types. - */ - public static final int STORE_STATUS_SUCCESS = 0x80; - public static final int STORE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0; - public static final int STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC1; - public static final int STORE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0; - public static final int STORE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1; - public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2; - public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE3; - public static final int STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL = 0xE4; - public static final int STORE_STATUS_ERROR_END = 0xFF; - - /** - * The map contains the value of all headers. - */ - private HashMap<Integer, Object> mHeaderMap = null; - - /** - * Constructor of PduHeaders. - */ - @UnsupportedAppUsage - public PduHeaders() { - mHeaderMap = new HashMap<Integer, Object>(); - } - - /** - * Get octet value by header field. - * - * @param field the field - * @return the octet value of the pdu header - * with specified header field. Return 0 if - * the value is not set. - */ - @UnsupportedAppUsage - protected int getOctet(int field) { - Integer octet = (Integer) mHeaderMap.get(field); - if (null == octet) { - return 0; - } - - return octet; - } - - /** - * Set octet value to pdu header by header field. - * - * @param value the value - * @param field the field - * @throws InvalidHeaderValueException if the value is invalid. - */ - @UnsupportedAppUsage - protected void setOctet(int value, int field) - throws InvalidHeaderValueException{ - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - switch (field) { - case REPORT_ALLOWED: - case ADAPTATION_ALLOWED: - case DELIVERY_REPORT: - case DRM_CONTENT: - case DISTRIBUTION_INDICATOR: - case QUOTAS: - case READ_REPORT: - case STORE: - case STORED: - case TOTALS: - case SENDER_VISIBILITY: - if ((VALUE_YES != value) && (VALUE_NO != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case READ_STATUS: - if ((READ_STATUS_READ != value) && - (READ_STATUS__DELETED_WITHOUT_BEING_READ != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case CANCEL_STATUS: - if ((CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED != value) && - (CANCEL_STATUS_REQUEST_CORRUPTED != value)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case PRIORITY: - if ((value < PRIORITY_LOW) || (value > PRIORITY_HIGH)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case STATUS: - if ((value < STATUS_EXPIRED) || (value > STATUS_UNREACHABLE)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case REPLY_CHARGING: - if ((value < REPLY_CHARGING_REQUESTED) - || (value > REPLY_CHARGING_ACCEPTED_TEXT_ONLY)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case MM_STATE: - if ((value < MM_STATE_DRAFT) || (value > MM_STATE_FORWARDED)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case RECOMMENDED_RETRIEVAL_MODE: - if (RECOMMENDED_RETRIEVAL_MODE_MANUAL != value) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case CONTENT_CLASS: - if ((value < CONTENT_CLASS_TEXT) - || (value > CONTENT_CLASS_CONTENT_RICH)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - case RETRIEVE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.50, we modify the invalid value. - if ((value > RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) && - (value < RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if ((value > RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED) && - (value <= RETRIEVE_STATUS_ERROR_END)) { - value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE; - } else if ((value < RETRIEVE_STATUS_OK) || - ((value > RETRIEVE_STATUS_OK) && - (value < RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > RETRIEVE_STATUS_ERROR_END)) { - value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case STORE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.58, we modify the invalid value. - if ((value > STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) && - (value < STORE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = STORE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if ((value > STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL) && - (value <= STORE_STATUS_ERROR_END)) { - value = STORE_STATUS_ERROR_PERMANENT_FAILURE; - } else if ((value < STORE_STATUS_SUCCESS) || - ((value > STORE_STATUS_SUCCESS) && - (value < STORE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > STORE_STATUS_ERROR_END)) { - value = STORE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case RESPONSE_STATUS: - // According to oma-ts-mms-enc-v1_3, section 7.3.48, we modify the invalid value. - if ((value > RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS) && - (value < RESPONSE_STATUS_ERROR_PERMANENT_FAILURE)) { - value = RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE; - } else if (((value > RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID) && - (value <= RESPONSE_STATUS_ERROR_PERMANENT_END)) || - (value < RESPONSE_STATUS_OK) || - ((value > RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE) && - (value < RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE)) || - (value > RESPONSE_STATUS_ERROR_PERMANENT_END)) { - value = RESPONSE_STATUS_ERROR_PERMANENT_FAILURE; - } - break; - case MMS_VERSION: - if ((value < MMS_VERSION_1_0)|| (value > MMS_VERSION_1_3)) { - value = CURRENT_MMS_VERSION; // Current version is the default value. - } - break; - case MESSAGE_TYPE: - if ((value < MESSAGE_TYPE_SEND_REQ) || (value > MESSAGE_TYPE_CANCEL_CONF)) { - // Invalid value. - throw new InvalidHeaderValueException("Invalid Octet value!"); - } - break; - default: - // This header value should not be Octect. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } - - /** - * Get TextString value by header field. - * - * @param field the field - * @return the TextString value of the pdu header - * with specified header field - */ - @UnsupportedAppUsage - protected byte[] getTextString(int field) { - return (byte[]) mHeaderMap.get(field); - } - - /** - * Set TextString value to pdu header by header field. - * - * @param value the value - * @param field the field - * @return the TextString value of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - protected void setTextString(byte[] value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case TRANSACTION_ID: - case REPLY_CHARGING_ID: - case AUX_APPLIC_ID: - case APPLIC_ID: - case REPLY_APPLIC_ID: - case MESSAGE_ID: - case REPLACE_ID: - case CANCEL_ID: - case CONTENT_LOCATION: - case MESSAGE_CLASS: - case CONTENT_TYPE: - break; - default: - // This header value should not be Text-String. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } - - /** - * Get EncodedStringValue value by header field. - * - * @param field the field - * @return the EncodedStringValue value of the pdu header - * with specified header field - */ - @UnsupportedAppUsage - protected EncodedStringValue getEncodedStringValue(int field) { - return (EncodedStringValue) mHeaderMap.get(field); - } - - /** - * Get TO, CC or BCC header value. - * - * @param field the field - * @return the EncodeStringValue array of the pdu header - * with specified header field - */ - @UnsupportedAppUsage - protected EncodedStringValue[] getEncodedStringValues(int field) { - ArrayList<EncodedStringValue> list = - (ArrayList<EncodedStringValue>) mHeaderMap.get(field); - if (null == list) { - return null; - } - EncodedStringValue[] values = new EncodedStringValue[list.size()]; - return list.toArray(values); - } - - /** - * Set EncodedStringValue value to pdu header by header field. - * - * @param value the value - * @param field the field - * @return the EncodedStringValue value of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - protected void setEncodedStringValue(EncodedStringValue value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case SUBJECT: - case RECOMMENDED_RETRIEVAL_MODE_TEXT: - case RETRIEVE_TEXT: - case STATUS_TEXT: - case STORE_STATUS_TEXT: - case RESPONSE_TEXT: - case FROM: - case PREVIOUSLY_SENT_BY: - case MM_FLAGS: - break; - default: - // This header value should not be Encoded-String-Value. - throw new RuntimeException("Invalid header field!"); - } - - mHeaderMap.put(field, value); - } - - /** - * Set TO, CC or BCC header value. - * - * @param value the value - * @param field the field - * @return the EncodedStringValue value array of the pdu header - * with specified header field - * @throws NullPointerException if the value is null. - */ - protected void setEncodedStringValues(EncodedStringValue[] value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case BCC: - case CC: - case TO: - break; - default: - // This header value should not be Encoded-String-Value. - throw new RuntimeException("Invalid header field!"); - } - - ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>(); - for (int i = 0; i < value.length; i++) { - list.add(value[i]); - } - mHeaderMap.put(field, list); - } - - /** - * Append one EncodedStringValue to another. - * - * @param value the EncodedStringValue to append - * @param field the field - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - protected void appendEncodedStringValue(EncodedStringValue value, - int field) { - if (null == value) { - throw new NullPointerException(); - } - - switch (field) { - case BCC: - case CC: - case TO: - break; - default: - throw new RuntimeException("Invalid header field!"); - } - - ArrayList<EncodedStringValue> list = - (ArrayList<EncodedStringValue>) mHeaderMap.get(field); - if (null == list) { - list = new ArrayList<EncodedStringValue>(); - } - list.add(value); - mHeaderMap.put(field, list); - } - - /** - * Get LongInteger value by header field. - * - * @param field the field - * @return the LongInteger value of the pdu header - * with specified header field. if return -1, the - * field is not existed in pdu header. - */ - @UnsupportedAppUsage - protected long getLongInteger(int field) { - Long longInteger = (Long) mHeaderMap.get(field); - if (null == longInteger) { - return -1; - } - - return longInteger.longValue(); - } - - /** - * Set LongInteger value to pdu header by header field. - * - * @param value the value - * @param field the field - */ - @UnsupportedAppUsage - protected void setLongInteger(long value, int field) { - /** - * Check whether this field can be set for specific - * header and check validity of the field. - */ - switch (field) { - case DATE: - case REPLY_CHARGING_SIZE: - case MESSAGE_SIZE: - case MESSAGE_COUNT: - case START: - case LIMIT: - case DELIVERY_TIME: - case EXPIRY: - case REPLY_CHARGING_DEADLINE: - case PREVIOUSLY_SENT_DATE: - break; - default: - // This header value should not be LongInteger. - throw new RuntimeException("Invalid header field!"); - } - mHeaderMap.put(field, value); - } -} diff --git a/telephony/java/com/google/android/mms/pdu/PduParser.java b/telephony/java/com/google/android/mms/pdu/PduParser.java deleted file mode 100755 index f48399410723..000000000000 --- a/telephony/java/com/google/android/mms/pdu/PduParser.java +++ /dev/null @@ -1,2023 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import android.util.Log; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.ContentType; -import com.google.android.mms.InvalidHeaderValueException; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; -import java.util.HashMap; - -public class PduParser { - /** - * The next are WAP values defined in WSP specification. - */ - private static final int QUOTE = 127; - private static final int LENGTH_QUOTE = 31; - private static final int TEXT_MIN = 32; - private static final int TEXT_MAX = 127; - private static final int SHORT_INTEGER_MAX = 127; - private static final int SHORT_LENGTH_MAX = 30; - private static final int LONG_INTEGER_LENGTH_MAX = 8; - private static final int QUOTED_STRING_FLAG = 34; - private static final int END_STRING_FLAG = 0x00; - //The next two are used by the interface "parseWapString" to - //distinguish Text-String and Quoted-String. - private static final int TYPE_TEXT_STRING = 0; - private static final int TYPE_QUOTED_STRING = 1; - private static final int TYPE_TOKEN_STRING = 2; - - /** - * Specify the part position. - */ - private static final int THE_FIRST_PART = 0; - private static final int THE_LAST_PART = 1; - - /** - * The pdu data. - */ - private ByteArrayInputStream mPduDataStream = null; - - /** - * Store pdu headers - */ - private PduHeaders mHeaders = null; - - /** - * Store pdu parts. - */ - private PduBody mBody = null; - - /** - * Store the "type" parameter in "Content-Type" header field. - */ - private static byte[] mTypeParam = null; - - /** - * Store the "start" parameter in "Content-Type" header field. - */ - private static byte[] mStartParam = null; - - /** - * The log tag. - */ - private static final String LOG_TAG = "PduParser"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - /** - * Whether to parse content-disposition part header - */ - private final boolean mParseContentDisposition; - - /** - * Constructor. - * - * @param pduDataStream pdu data to be parsed - * @param parseContentDisposition whether to parse the Content-Disposition part header - */ - @UnsupportedAppUsage - public PduParser(byte[] pduDataStream, boolean parseContentDisposition) { - mPduDataStream = new ByteArrayInputStream(pduDataStream); - mParseContentDisposition = parseContentDisposition; - } - - /** - * Parse the pdu. - * - * @return the pdu structure if parsing successfully. - * null if parsing error happened or mandatory fields are not set. - */ - @UnsupportedAppUsage - public GenericPdu parse(){ - if (mPduDataStream == null) { - return null; - } - - /* parse headers */ - mHeaders = parseHeaders(mPduDataStream); - if (null == mHeaders) { - // Parse headers failed. - return null; - } - - /* get the message type */ - int messageType = mHeaders.getOctet(PduHeaders.MESSAGE_TYPE); - - /* check mandatory header fields */ - if (false == checkMandatoryHeader(mHeaders)) { - log("check mandatory headers failed!"); - return null; - } - - if ((PduHeaders.MESSAGE_TYPE_SEND_REQ == messageType) || - (PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF == messageType)) { - /* need to parse the parts */ - mBody = parseParts(mPduDataStream); - if (null == mBody) { - // Parse parts failed. - return null; - } - } - - switch (messageType) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_REQ"); - } - SendReq sendReq = new SendReq(mHeaders, mBody); - return sendReq; - case PduHeaders.MESSAGE_TYPE_SEND_CONF: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_CONF"); - } - SendConf sendConf = new SendConf(mHeaders); - return sendConf; - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFICATION_IND"); - } - NotificationInd notificationInd = - new NotificationInd(mHeaders); - return notificationInd; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFYRESP_IND"); - } - NotifyRespInd notifyRespInd = - new NotifyRespInd(mHeaders); - return notifyRespInd; - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_RETRIEVE_CONF"); - } - RetrieveConf retrieveConf = - new RetrieveConf(mHeaders, mBody); - - byte[] contentType = retrieveConf.getContentType(); - if (null == contentType) { - return null; - } - String ctTypeStr = new String(contentType); - if (ctTypeStr.equals(ContentType.MULTIPART_MIXED) - || ctTypeStr.equals(ContentType.MULTIPART_RELATED) - || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { - // The MMS content type must be "application/vnd.wap.multipart.mixed" - // or "application/vnd.wap.multipart.related" - // or "application/vnd.wap.multipart.alternative" - return retrieveConf; - } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) { - // "application/vnd.wap.multipart.alternative" - // should take only the first part. - PduPart firstPart = mBody.getPart(0); - mBody.removeAll(); - mBody.addPart(0, firstPart); - return retrieveConf; - } - return null; - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_DELIVERY_IND"); - } - DeliveryInd deliveryInd = - new DeliveryInd(mHeaders); - return deliveryInd; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_ACKNOWLEDGE_IND"); - } - AcknowledgeInd acknowledgeInd = - new AcknowledgeInd(mHeaders); - return acknowledgeInd; - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_ORIG_IND"); - } - ReadOrigInd readOrigInd = - new ReadOrigInd(mHeaders); - return readOrigInd; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_REC_IND"); - } - ReadRecInd readRecInd = - new ReadRecInd(mHeaders); - return readRecInd; - default: - log("Parser doesn't support this message type in this version!"); - return null; - } - } - - /** - * Parse pdu headers. - * - * @param pduDataStream pdu data input stream - * @return headers in PduHeaders structure, null when parse fail - */ - protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream){ - if (pduDataStream == null) { - return null; - } - boolean keepParsing = true; - PduHeaders headers = new PduHeaders(); - - while (keepParsing && (pduDataStream.available() > 0)) { - pduDataStream.mark(1); - int headerField = extractByteValue(pduDataStream); - /* parse custom text header */ - if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) { - pduDataStream.reset(); - byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "TextHeader: " + new String(bVal)); - } - /* we should ignore it at the moment */ - continue; - } - switch (headerField) { - case PduHeaders.MESSAGE_TYPE: - { - int messageType = extractByteValue(pduDataStream); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: messageType: " + messageType); - } - switch (messageType) { - // We don't support these kind of messages now. - case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: - case PduHeaders.MESSAGE_TYPE_FORWARD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DESCR: - case PduHeaders.MESSAGE_TYPE_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_CANCEL_REQ: - case PduHeaders.MESSAGE_TYPE_CANCEL_CONF: - return null; - } - try { - headers.setOctet(messageType, headerField); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + messageType + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - /* Octect value */ - case PduHeaders.REPORT_ALLOWED: - case PduHeaders.ADAPTATION_ALLOWED: - case PduHeaders.DELIVERY_REPORT: - case PduHeaders.DRM_CONTENT: - case PduHeaders.DISTRIBUTION_INDICATOR: - case PduHeaders.QUOTAS: - case PduHeaders.READ_REPORT: - case PduHeaders.STORE: - case PduHeaders.STORED: - case PduHeaders.TOTALS: - case PduHeaders.SENDER_VISIBILITY: - case PduHeaders.READ_STATUS: - case PduHeaders.CANCEL_STATUS: - case PduHeaders.PRIORITY: - case PduHeaders.STATUS: - case PduHeaders.REPLY_CHARGING: - case PduHeaders.MM_STATE: - case PduHeaders.RECOMMENDED_RETRIEVAL_MODE: - case PduHeaders.CONTENT_CLASS: - case PduHeaders.RETRIEVE_STATUS: - case PduHeaders.STORE_STATUS: - /** - * The following field has a different value when - * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. - * For now we ignore this fact, since we do not support these PDUs - */ - case PduHeaders.RESPONSE_STATUS: - { - int value = extractByteValue(pduDataStream); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: byte: " + headerField + " value: " + - value); - } - - try { - headers.setOctet(value, headerField); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + value + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - - /* Long-Integer */ - case PduHeaders.DATE: - case PduHeaders.REPLY_CHARGING_SIZE: - case PduHeaders.MESSAGE_SIZE: - { - try { - long value = parseLongInteger(pduDataStream); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: longint: " + headerField + " value: " + - value); - } - headers.setLongInteger(value, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - /* Integer-Value */ - case PduHeaders.MESSAGE_COUNT: - case PduHeaders.START: - case PduHeaders.LIMIT: - { - try { - long value = parseIntegerValue(pduDataStream); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: int: " + headerField + " value: " + - value); - } - headers.setLongInteger(value, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - /* Text-String */ - case PduHeaders.TRANSACTION_ID: - case PduHeaders.REPLY_CHARGING_ID: - case PduHeaders.AUX_APPLIC_ID: - case PduHeaders.APPLIC_ID: - case PduHeaders.REPLY_APPLIC_ID: - /** - * The next three header fields are email addresses - * as defined in RFC2822, - * not including the characters "<" and ">" - */ - case PduHeaders.MESSAGE_ID: - case PduHeaders.REPLACE_ID: - case PduHeaders.CANCEL_ID: - /** - * The following field has a different value when - * used in the M-Mbox-Delete.conf and M-Delete.conf PDU. - * For now we ignore this fact, since we do not support these PDUs - */ - case PduHeaders.CONTENT_LOCATION: - { - byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != value) { - try { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: string: " + headerField + " value: " + - new String(value)); - } - headers.setTextString(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - break; - } - - /* Encoded-string-value */ - case PduHeaders.SUBJECT: - case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT: - case PduHeaders.RETRIEVE_TEXT: - case PduHeaders.STATUS_TEXT: - case PduHeaders.STORE_STATUS_TEXT: - /* the next one is not support - * M-Mbox-Delete.conf and M-Delete.conf now */ - case PduHeaders.RESPONSE_TEXT: - { - EncodedStringValue value = - parseEncodedStringValue(pduDataStream); - if (null != value) { - try { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: encoded string: " + headerField - + " value: " + value.getString()); - } - headers.setEncodedStringValue(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch (RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - /* Addressing model */ - case PduHeaders.BCC: - case PduHeaders.CC: - case PduHeaders.TO: - { - EncodedStringValue value = - parseEncodedStringValue(pduDataStream); - if (null != value) { - byte[] address = value.getTextString(); - if (null != address) { - String str = new String(address); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: (to/cc/bcc) address: " + headerField - + " value: " + str); - } - int endIndex = str.indexOf("/"); - if (endIndex > 0) { - str = str.substring(0, endIndex); - } - try { - value.setTextString(str.getBytes()); - } catch(NullPointerException e) { - log("null pointer error!"); - return null; - } - } - - try { - headers.appendEncodedStringValue(value, headerField); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - /* Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) */ - case PduHeaders.DELIVERY_TIME: - case PduHeaders.EXPIRY: - case PduHeaders.REPLY_CHARGING_DEADLINE: - { - /* parse Value-length */ - parseValueLength(pduDataStream); - - /* Absolute-token or Relative-token */ - int token = extractByteValue(pduDataStream); - - /* Date-value or Delta-seconds-value */ - long timeValue; - try { - timeValue = parseLongInteger(pduDataStream); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - if (PduHeaders.VALUE_RELATIVE_TOKEN == token) { - /* need to convert the Delta-seconds-value - * into Date-value */ - timeValue = System.currentTimeMillis()/1000 + timeValue; - } - - try { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: time value: " + headerField - + " value: " + timeValue); - } - headers.setLongInteger(timeValue, headerField); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - case PduHeaders.FROM: { - /* From-value = - * Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - */ - EncodedStringValue from = null; - parseValueLength(pduDataStream); /* parse value-length */ - - /* Address-present-token or Insert-address-token */ - int fromToken = extractByteValue(pduDataStream); - - /* Address-present-token or Insert-address-token */ - if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) { - /* Encoded-string-value */ - from = parseEncodedStringValue(pduDataStream); - if (null != from) { - byte[] address = from.getTextString(); - if (null != address) { - String str = new String(address); - int endIndex = str.indexOf("/"); - if (endIndex > 0) { - str = str.substring(0, endIndex); - } - try { - from.setTextString(str.getBytes()); - } catch(NullPointerException e) { - log("null pointer error!"); - return null; - } - } - } - } else { - try { - from = new EncodedStringValue( - PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()); - } catch(NullPointerException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - - try { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: from address: " + headerField - + " value: " + from.getString()); - } - headers.setEncodedStringValue(from, PduHeaders.FROM); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - break; - } - - case PduHeaders.MESSAGE_CLASS: { - /* Message-class-value = Class-identifier | Token-text */ - pduDataStream.mark(1); - int messageClass = extractByteValue(pduDataStream); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: MESSAGE_CLASS: " + headerField - + " value: " + messageClass); - } - - if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) { - /* Class-identifier */ - try { - if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) { - headers.setTextString( - PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(), - PduHeaders.MESSAGE_CLASS); - } - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } else { - /* Token-text */ - pduDataStream.reset(); - byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != messageClassString) { - try { - headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - } - break; - } - - case PduHeaders.MMS_VERSION: { - int version = parseShortInteger(pduDataStream); - - try { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: MMS_VERSION: " + headerField - + " value: " + version); - } - headers.setOctet(version, PduHeaders.MMS_VERSION); - } catch(InvalidHeaderValueException e) { - log("Set invalid Octet value: " + version + - " into the header filed: " + headerField); - return null; - } catch(RuntimeException e) { - log(headerField + "is not Octet header field!"); - return null; - } - break; - } - - case PduHeaders.PREVIOUSLY_SENT_BY: { - /* Previously-sent-by-value = - * Value-length Forwarded-count-value Encoded-string-value */ - /* parse value-length */ - parseValueLength(pduDataStream); - - /* parse Forwarded-count-value */ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* parse Encoded-string-value */ - EncodedStringValue previouslySentBy = - parseEncodedStringValue(pduDataStream); - if (null != previouslySentBy) { - try { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_BY: " + headerField - + " value: " + previouslySentBy.getString()); - } - headers.setEncodedStringValue(previouslySentBy, - PduHeaders.PREVIOUSLY_SENT_BY); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Encoded-String-Value header field!"); - return null; - } - } - break; - } - - case PduHeaders.PREVIOUSLY_SENT_DATE: { - /* Previously-sent-date-value = - * Value-length Forwarded-count-value Date-value */ - /* parse value-length */ - parseValueLength(pduDataStream); - - /* parse Forwarded-count-value */ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* Date-value */ - try { - long perviouslySentDate = parseLongInteger(pduDataStream); - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_DATE: " + headerField - + " value: " + perviouslySentDate); - } - headers.setLongInteger(perviouslySentDate, - PduHeaders.PREVIOUSLY_SENT_DATE); - } catch(RuntimeException e) { - log(headerField + "is not Long-Integer header field!"); - return null; - } - break; - } - - case PduHeaders.MM_FLAGS: { - /* MM-flags-value = - * Value-length - * ( Add-token | Remove-token | Filter-token ) - * Encoded-string-value - */ - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: MM_FLAGS: " + headerField - + " NOT REALLY SUPPORTED"); - } - - /* parse Value-length */ - parseValueLength(pduDataStream); - - /* Add-token | Remove-token | Filter-token */ - extractByteValue(pduDataStream); - - /* Encoded-string-value */ - parseEncodedStringValue(pduDataStream); - - /* not store this header filed in "headers", - * because now PduHeaders doesn't support it */ - break; - } - - /* Value-length - * (Message-total-token | Size-total-token) Integer-Value */ - case PduHeaders.MBOX_TOTALS: - case PduHeaders.MBOX_QUOTAS: - { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: MBOX_TOTALS: " + headerField); - } - /* Value-length */ - parseValueLength(pduDataStream); - - /* Message-total-token | Size-total-token */ - extractByteValue(pduDataStream); - - /*Integer-Value*/ - try { - parseIntegerValue(pduDataStream); - } catch(RuntimeException e) { - log(headerField + " is not Integer-Value"); - return null; - } - - /* not store these headers filed in "headers", - because now PduHeaders doesn't support them */ - break; - } - - case PduHeaders.ELEMENT_DESCRIPTOR: { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: ELEMENT_DESCRIPTOR: " + headerField); - } - parseContentType(pduDataStream, null); - - /* not store this header filed in "headers", - because now PduHeaders doesn't support it */ - break; - } - - case PduHeaders.CONTENT_TYPE: { - HashMap<Integer, Object> map = - new HashMap<Integer, Object>(); - byte[] contentType = - parseContentType(pduDataStream, map); - - if (null != contentType) { - try { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: CONTENT_TYPE: " + headerField + - contentType.toString()); - } - headers.setTextString(contentType, PduHeaders.CONTENT_TYPE); - } catch(NullPointerException e) { - log("null pointer error!"); - } catch(RuntimeException e) { - log(headerField + "is not Text-String header field!"); - return null; - } - } - - /* get start parameter */ - mStartParam = (byte[]) map.get(PduPart.P_START); - - /* get charset parameter */ - mTypeParam= (byte[]) map.get(PduPart.P_TYPE); - - keepParsing = false; - break; - } - - case PduHeaders.CONTENT: - case PduHeaders.ADDITIONAL_HEADERS: - case PduHeaders.ATTRIBUTES: - default: { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "parseHeaders: Unknown header: " + headerField); - } - log("Unknown header"); - } - } - } - - return headers; - } - - /** - * Parse pdu parts. - * - * @param pduDataStream pdu data input stream - * @return parts in PduBody structure - */ - protected PduBody parseParts(ByteArrayInputStream pduDataStream) { - if (pduDataStream == null) { - return null; - } - - int count = parseUnsignedInt(pduDataStream); // get the number of parts - PduBody body = new PduBody(); - - for (int i = 0 ; i < count ; i++) { - int headerLength = parseUnsignedInt(pduDataStream); - int dataLength = parseUnsignedInt(pduDataStream); - PduPart part = new PduPart(); - int startPos = pduDataStream.available(); - if (startPos <= 0) { - // Invalid part. - return null; - } - - /* parse part's content-type */ - HashMap<Integer, Object> map = new HashMap<Integer, Object>(); - byte[] contentType = parseContentType(pduDataStream, map); - if (null != contentType) { - part.setContentType(contentType); - } else { - part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*" - } - - /* get name parameter */ - byte[] name = (byte[]) map.get(PduPart.P_NAME); - if (null != name) { - part.setName(name); - } - - /* get charset parameter */ - Integer charset = (Integer) map.get(PduPart.P_CHARSET); - if (null != charset) { - part.setCharset(charset); - } - - /* parse part's headers */ - int endPos = pduDataStream.available(); - int partHeaderLen = headerLength - (startPos - endPos); - if (partHeaderLen > 0) { - if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) { - // Parse part header faild. - return null; - } - } else if (partHeaderLen < 0) { - // Invalid length of content-type. - return null; - } - - /* FIXME: check content-id, name, filename and content location, - * if not set anyone of them, generate a default content-location - */ - if ((null == part.getContentLocation()) - && (null == part.getName()) - && (null == part.getFilename()) - && (null == part.getContentId())) { - part.setContentLocation(Long.toOctalString( - System.currentTimeMillis()).getBytes()); - } - - /* get part's data */ - if (dataLength > 0) { - byte[] partData = new byte[dataLength]; - String partContentType = new String(part.getContentType()); - pduDataStream.read(partData, 0, dataLength); - if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) { - // parse "multipart/vnd.wap.multipart.alternative". - PduBody childBody = parseParts(new ByteArrayInputStream(partData)); - // take the first part of children. - part = childBody.getPart(0); - } else { - // Check Content-Transfer-Encoding. - byte[] partDataEncoding = part.getContentTransferEncoding(); - if (null != partDataEncoding) { - String encoding = new String(partDataEncoding); - if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { - // Decode "base64" into "binary". - partData = Base64.decodeBase64(partData); - } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { - // Decode "quoted-printable" into "binary". - partData = QuotedPrintable.decodeQuotedPrintable(partData); - } else { - // "binary" is the default encoding. - } - } - if (null == partData) { - log("Decode part data error!"); - return null; - } - part.setData(partData); - } - } - - /* add this part to body */ - if (THE_FIRST_PART == checkPartPosition(part)) { - /* this is the first part */ - body.addPart(0, part); - } else { - /* add the part to the end */ - body.addPart(part); - } - } - - return body; - } - - /** - * Log status. - * - * @param text log information - */ - @UnsupportedAppUsage - private static void log(String text) { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, text); - } - } - - /** - * Parse unsigned integer. - * - * @param pduDataStream pdu data input stream - * @return the integer, -1 when failed - */ - @UnsupportedAppUsage - protected static int parseUnsignedInt(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * The maximum size of a uintvar is 32 bits. - * So it will be encoded in no more than 5 octets. - */ - assert(null != pduDataStream); - int result = 0; - int temp = pduDataStream.read(); - if (temp == -1) { - return temp; - } - - while((temp & 0x80) != 0) { - result = result << 7; - result |= temp & 0x7F; - temp = pduDataStream.read(); - if (temp == -1) { - return temp; - } - } - - result = result << 7; - result |= temp & 0x7F; - - return result; - } - - /** - * Parse value length. - * - * @param pduDataStream pdu data input stream - * @return the integer - */ - @UnsupportedAppUsage - protected static int parseValueLength(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Value-length = Short-length | (Length-quote Length) - * Short-length = <Any octet 0-30> - * Length-quote = <Octet 31> - * Length = Uintvar-integer - * Uintvar-integer = 1*5 OCTET - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - int first = temp & 0xFF; - - if (first <= SHORT_LENGTH_MAX) { - return first; - } else if (first == LENGTH_QUOTE) { - return parseUnsignedInt(pduDataStream); - } - - throw new RuntimeException ("Value length > LENGTH_QUOTE!"); - } - - /** - * Parse encoded string value. - * - * @param pduDataStream pdu data input stream - * @return the EncodedStringValue - */ - protected static EncodedStringValue parseEncodedStringValue(ByteArrayInputStream pduDataStream){ - /** - * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf - * Encoded-string-value = Text-string | Value-length Char-set Text-string - */ - assert(null != pduDataStream); - pduDataStream.mark(1); - EncodedStringValue returnValue = null; - int charset = 0; - int temp = pduDataStream.read(); - assert(-1 != temp); - int first = temp & 0xFF; - if (first == 0) { - return new EncodedStringValue(""); - } - - pduDataStream.reset(); - if (first < TEXT_MIN) { - parseValueLength(pduDataStream); - - charset = parseShortInteger(pduDataStream); //get the "Charset" - } - - byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING); - - try { - if (0 != charset) { - returnValue = new EncodedStringValue(charset, textString); - } else { - returnValue = new EncodedStringValue(textString); - } - } catch(Exception e) { - return null; - } - - return returnValue; - } - - /** - * Parse Text-String or Quoted-String. - * - * @param pduDataStream pdu data input stream - * @param stringType TYPE_TEXT_STRING or TYPE_QUOTED_STRING - * @return the string without End-of-string in byte array - */ - @UnsupportedAppUsage - protected static byte[] parseWapString(ByteArrayInputStream pduDataStream, - int stringType) { - assert(null != pduDataStream); - /** - * From wap-230-wsp-20010705-a.pdf - * Text-string = [Quote] *TEXT End-of-string - * If the first character in the TEXT is in the range of 128-255, - * a Quote character must precede it. - * Otherwise the Quote character must be omitted. - * The Quote is not part of the contents. - * Quote = <Octet 127> - * End-of-string = <Octet 0> - * - * Quoted-string = <Octet 34> *TEXT End-of-string - * - * Token-text = Token End-of-string - */ - - // Mark supposed beginning of Text-string - // We will have to mark again if first char is QUOTE or QUOTED_STRING_FLAG - pduDataStream.mark(1); - - // Check first char - int temp = pduDataStream.read(); - assert(-1 != temp); - if ((TYPE_QUOTED_STRING == stringType) && - (QUOTED_STRING_FLAG == temp)) { - // Mark again if QUOTED_STRING_FLAG and ignore it - pduDataStream.mark(1); - } else if ((TYPE_TEXT_STRING == stringType) && - (QUOTE == temp)) { - // Mark again if QUOTE and ignore it - pduDataStream.mark(1); - } else { - // Otherwise go back to origin - pduDataStream.reset(); - } - - // We are now definitely at the beginning of string - /** - * Return *TOKEN or *TEXT (Text-String without QUOTE, - * Quoted-String without QUOTED_STRING_FLAG and without End-of-string) - */ - return getWapString(pduDataStream, stringType); - } - - /** - * Check TOKEN data defined in RFC2616. - * @param ch checking data - * @return true when ch is TOKEN, false when ch is not TOKEN - */ - protected static boolean isTokenCharacter(int ch) { - /** - * Token = 1*<any CHAR except CTLs or separators> - * separators = "("(40) | ")"(41) | "<"(60) | ">"(62) | "@"(64) - * | ","(44) | ";"(59) | ":"(58) | "\"(92) | <">(34) - * | "/"(47) | "["(91) | "]"(93) | "?"(63) | "="(61) - * | "{"(123) | "}"(125) | SP(32) | HT(9) - * CHAR = <any US-ASCII character (octets 0 - 127)> - * CTL = <any US-ASCII control character - * (octets 0 - 31) and DEL (127)> - * SP = <US-ASCII SP, space (32)> - * HT = <US-ASCII HT, horizontal-tab (9)> - */ - if((ch < 33) || (ch > 126)) { - return false; - } - - switch(ch) { - case '"': /* '"' */ - case '(': /* '(' */ - case ')': /* ')' */ - case ',': /* ',' */ - case '/': /* '/' */ - case ':': /* ':' */ - case ';': /* ';' */ - case '<': /* '<' */ - case '=': /* '=' */ - case '>': /* '>' */ - case '?': /* '?' */ - case '@': /* '@' */ - case '[': /* '[' */ - case '\\': /* '\' */ - case ']': /* ']' */ - case '{': /* '{' */ - case '}': /* '}' */ - return false; - } - - return true; - } - - /** - * Check TEXT data defined in RFC2616. - * @param ch checking data - * @return true when ch is TEXT, false when ch is not TEXT - */ - protected static boolean isText(int ch) { - /** - * TEXT = <any OCTET except CTLs, - * but including LWS> - * CTL = <any US-ASCII control character - * (octets 0 - 31) and DEL (127)> - * LWS = [CRLF] 1*( SP | HT ) - * CRLF = CR LF - * CR = <US-ASCII CR, carriage return (13)> - * LF = <US-ASCII LF, linefeed (10)> - */ - if(((ch >= 32) && (ch <= 126)) || ((ch >= 128) && (ch <= 255))) { - return true; - } - - switch(ch) { - case '\t': /* '\t' */ - case '\n': /* '\n' */ - case '\r': /* '\r' */ - return true; - } - - return false; - } - - protected static byte[] getWapString(ByteArrayInputStream pduDataStream, - int stringType) { - assert(null != pduDataStream); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int temp = pduDataStream.read(); - assert(-1 != temp); - while((-1 != temp) && ('\0' != temp)) { - // check each of the character - if (stringType == TYPE_TOKEN_STRING) { - if (isTokenCharacter(temp)) { - out.write(temp); - } - } else { - if (isText(temp)) { - out.write(temp); - } - } - - temp = pduDataStream.read(); - assert(-1 != temp); - } - - if (out.size() > 0) { - return out.toByteArray(); - } - - return null; - } - - /** - * Extract a byte value from the input stream. - * - * @param pduDataStream pdu data input stream - * @return the byte - */ - protected static int extractByteValue(ByteArrayInputStream pduDataStream) { - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - return temp & 0xFF; - } - - /** - * Parse Short-Integer. - * - * @param pduDataStream pdu data input stream - * @return the byte - */ - @UnsupportedAppUsage - protected static int parseShortInteger(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Short-integer = OCTET - * Integers in range 0-127 shall be encoded as a one - * octet value with the most significant bit set to one (1xxx xxxx) - * and with the value in the remaining least significant bits. - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - return temp & 0x7F; - } - - /** - * Parse Long-Integer. - * - * @param pduDataStream pdu data input stream - * @return long integer - */ - protected static long parseLongInteger(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Long-integer = Short-length Multi-octet-integer - * The Short-length indicates the length of the Multi-octet-integer - * Multi-octet-integer = 1*30 OCTET - * The content octets shall be an unsigned integer value - * with the most significant octet encoded first (big-endian representation). - * The minimum number of octets must be used to encode the value. - * Short-length = <Any octet 0-30> - */ - assert(null != pduDataStream); - int temp = pduDataStream.read(); - assert(-1 != temp); - int count = temp & 0xFF; - - if (count > LONG_INTEGER_LENGTH_MAX) { - throw new RuntimeException("Octet count greater than 8 and I can't represent that!"); - } - - long result = 0; - - for (int i = 0 ; i < count ; i++) { - temp = pduDataStream.read(); - assert(-1 != temp); - result <<= 8; - result += (temp & 0xFF); - } - - return result; - } - - /** - * Parse Integer-Value. - * - * @param pduDataStream pdu data input stream - * @return long integer - */ - protected static long parseIntegerValue(ByteArrayInputStream pduDataStream) { - /** - * From wap-230-wsp-20010705-a.pdf - * Integer-Value = Short-integer | Long-integer - */ - assert(null != pduDataStream); - pduDataStream.mark(1); - int temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - if (temp > SHORT_INTEGER_MAX) { - return parseShortInteger(pduDataStream); - } else { - return parseLongInteger(pduDataStream); - } - } - - /** - * To skip length of the wap value. - * - * @param pduDataStream pdu data input stream - * @param length area size - * @return the values in this area - */ - protected static int skipWapValue(ByteArrayInputStream pduDataStream, int length) { - assert(null != pduDataStream); - byte[] area = new byte[length]; - int readLen = pduDataStream.read(area, 0, length); - if (readLen < length) { //The actually read length is lower than the length - return -1; - } else { - return readLen; - } - } - - /** - * Parse content type parameters. For now we just support - * four parameters used in mms: "type", "start", "name", "charset". - * - * @param pduDataStream pdu data input stream - * @param map to store parameters of Content-Type field - * @param length length of all the parameters - */ - protected static void parseContentTypeParams(ByteArrayInputStream pduDataStream, - HashMap<Integer, Object> map, Integer length) { - /** - * From wap-230-wsp-20010705-a.pdf - * Parameter = Typed-parameter | Untyped-parameter - * Typed-parameter = Well-known-parameter-token Typed-value - * the actual expected type of the value is implied by the well-known parameter - * Well-known-parameter-token = Integer-value - * the code values used for parameters are specified in the Assigned Numbers appendix - * Typed-value = Compact-value | Text-value - * In addition to the expected type, there may be no value. - * If the value cannot be encoded using the expected type, it shall be encoded as text. - * Compact-value = Integer-value | - * Date-value | Delta-seconds-value | Q-value | Version-value | - * Uri-value - * Untyped-parameter = Token-text Untyped-value - * the type of the value is unknown, but it shall be encoded as an integer, - * if that is possible. - * Untyped-value = Integer-value | Text-value - */ - assert(null != pduDataStream); - assert(length > 0); - - int startPos = pduDataStream.available(); - int tempPos = 0; - int lastLen = length; - while(0 < lastLen) { - int param = pduDataStream.read(); - assert(-1 != param); - lastLen--; - - switch (param) { - /** - * From rfc2387, chapter 3.1 - * The type parameter must be specified and its value is the MIME media - * type of the "root" body part. It permits a MIME user agent to - * determine the content-type without reference to the enclosed body - * part. If the value of the type parameter and the root body part's - * content-type differ then the User Agent's behavior is undefined. - * - * From wap-230-wsp-20010705-a.pdf - * type = Constrained-encoding - * Constrained-encoding = Extension-Media | Short-integer - * Extension-media = *TEXT End-of-string - */ - case PduPart.P_TYPE: - case PduPart.P_CT_MR_TYPE: - pduDataStream.mark(1); - int first = extractByteValue(pduDataStream); - pduDataStream.reset(); - if (first > TEXT_MAX) { - // Short-integer (well-known type) - int index = parseShortInteger(pduDataStream); - - if (index < PduContentTypes.contentTypes.length) { - byte[] type = (PduContentTypes.contentTypes[index]).getBytes(); - map.put(PduPart.P_TYPE, type); - } else { - //not support this type, ignore it. - } - } else { - // Text-String (extension-media) - byte[] type = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != type) && (null != map)) { - map.put(PduPart.P_TYPE, type); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.3. - * Start Parameter Referring to Presentation - * - * From rfc2387, chapter 3.2 - * The start parameter, if given, is the content-ID of the compound - * object's "root". If not present the "root" is the first body part in - * the Multipart/Related entity. The "root" is the element the - * applications processes first. - * - * From wap-230-wsp-20010705-a.pdf - * start = Text-String - */ - case PduPart.P_START: - case PduPart.P_DEP_START: - byte[] start = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != start) && (null != map)) { - map.put(PduPart.P_START, start); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf - * In creation, the character set SHALL be either us-ascii - * (IANA MIBenum 3) or utf-8 (IANA MIBenum 106)[Unicode]. - * In retrieval, both us-ascii and utf-8 SHALL be supported. - * - * From wap-230-wsp-20010705-a.pdf - * charset = Well-known-charset|Text-String - * Well-known-charset = Any-charset | Integer-value - * Both are encoded using values from Character Set - * Assignments table in Assigned Numbers - * Any-charset = <Octet 128> - * Equivalent to the special RFC2616 charset value "*" - */ - case PduPart.P_CHARSET: - pduDataStream.mark(1); - int firstValue = extractByteValue(pduDataStream); - pduDataStream.reset(); - //Check first char - if (((firstValue > TEXT_MIN) && (firstValue < TEXT_MAX)) || - (END_STRING_FLAG == firstValue)) { - //Text-String (extension-charset) - byte[] charsetStr = parseWapString(pduDataStream, TYPE_TEXT_STRING); - try { - int charsetInt = CharacterSets.getMibEnumValue( - new String(charsetStr)); - map.put(PduPart.P_CHARSET, charsetInt); - } catch (UnsupportedEncodingException e) { - // Not a well-known charset, use "*". - Log.e(LOG_TAG, Arrays.toString(charsetStr), e); - map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET); - } - } else { - //Well-known-charset - int charset = (int) parseIntegerValue(pduDataStream); - if (map != null) { - map.put(PduPart.P_CHARSET, charset); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - - /** - * From oma-ts-mms-conf-v1_3.pdf - * A name for multipart object SHALL be encoded using name-parameter - * for Content-Type header in WSP multipart headers. - * - * From wap-230-wsp-20010705-a.pdf - * name = Text-String - */ - case PduPart.P_DEP_NAME: - case PduPart.P_NAME: - byte[] name = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if ((null != name) && (null != map)) { - map.put(PduPart.P_NAME, name); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - default: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Content-Type parameter"); - } - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Content-Type"); - } else { - lastLen = 0; - } - break; - } - } - - if (0 != lastLen) { - Log.e(LOG_TAG, "Corrupt Content-Type"); - } - } - - /** - * Parse content type. - * - * @param pduDataStream pdu data input stream - * @param map to store parameters in Content-Type header field - * @return Content-Type value - */ - @UnsupportedAppUsage - protected static byte[] parseContentType(ByteArrayInputStream pduDataStream, - HashMap<Integer, Object> map) { - /** - * From wap-230-wsp-20010705-a.pdf - * Content-type-value = Constrained-media | Content-general-form - * Content-general-form = Value-length Media-type - * Media-type = (Well-known-media | Extension-Media) *(Parameter) - */ - assert(null != pduDataStream); - - byte[] contentType = null; - pduDataStream.mark(1); - int temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - - int cur = (temp & 0xFF); - - if (cur < TEXT_MIN) { - int length = parseValueLength(pduDataStream); - int startPos = pduDataStream.available(); - pduDataStream.mark(1); - temp = pduDataStream.read(); - assert(-1 != temp); - pduDataStream.reset(); - int first = (temp & 0xFF); - - if ((first >= TEXT_MIN) && (first <= TEXT_MAX)) { - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } else if (first > TEXT_MAX) { - int index = parseShortInteger(pduDataStream); - - if (index < PduContentTypes.contentTypes.length) { //well-known type - contentType = (PduContentTypes.contentTypes[index]).getBytes(); - } else { - pduDataStream.reset(); - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } - } else { - Log.e(LOG_TAG, "Corrupt content-type"); - return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" - } - - int endPos = pduDataStream.available(); - int parameterLen = length - (startPos - endPos); - if (parameterLen > 0) {//have parameters - parseContentTypeParams(pduDataStream, map, parameterLen); - } - - if (parameterLen < 0) { - Log.e(LOG_TAG, "Corrupt MMS message"); - return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*" - } - } else if (cur <= TEXT_MAX) { - contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING); - } else { - contentType = - (PduContentTypes.contentTypes[parseShortInteger(pduDataStream)]).getBytes(); - } - - return contentType; - } - - /** - * Parse part's headers. - * - * @param pduDataStream pdu data input stream - * @param part to store the header informations of the part - * @param length length of the headers - * @return true if parse successfully, false otherwise - */ - @UnsupportedAppUsage - protected boolean parsePartHeaders(ByteArrayInputStream pduDataStream, - PduPart part, int length) { - assert(null != pduDataStream); - assert(null != part); - assert(length > 0); - - /** - * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2. - * A name for multipart object SHALL be encoded using name-parameter - * for Content-Type header in WSP multipart headers. - * In decoding, name-parameter of Content-Type SHALL be used if available. - * If name-parameter of Content-Type is not available, - * filename parameter of Content-Disposition header SHALL be used if available. - * If neither name-parameter of Content-Type header nor filename parameter - * of Content-Disposition header is available, - * Content-Location header SHALL be used if available. - * - * Within SMIL part the reference to the media object parts SHALL use - * either Content-ID or Content-Location mechanism [RFC2557] - * and the corresponding WSP part headers in media object parts - * contain the corresponding definitions. - */ - int startPos = pduDataStream.available(); - int tempPos = 0; - int lastLen = length; - while(0 < lastLen) { - int header = pduDataStream.read(); - assert(-1 != header); - lastLen--; - - if (header > TEXT_MAX) { - // Number assigned headers. - switch (header) { - case PduPart.P_CONTENT_LOCATION: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-location-value = Uri-value - */ - byte[] contentLocation = parseWapString(pduDataStream, TYPE_TEXT_STRING); - if (null != contentLocation) { - part.setContentLocation(contentLocation); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - case PduPart.P_CONTENT_ID: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-ID-value = Quoted-string - */ - byte[] contentId = parseWapString(pduDataStream, TYPE_QUOTED_STRING); - if (null != contentId) { - part.setContentId(contentId); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - break; - case PduPart.P_DEP_CONTENT_DISPOSITION: - case PduPart.P_CONTENT_DISPOSITION: - /** - * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21 - * Content-disposition-value = Value-length Disposition *(Parameter) - * Disposition = Form-data | Attachment | Inline | Token-text - * Form-data = <Octet 128> - * Attachment = <Octet 129> - * Inline = <Octet 130> - */ - - /* - * some carrier mmsc servers do not support content_disposition - * field correctly - */ - if (mParseContentDisposition) { - int len = parseValueLength(pduDataStream); - pduDataStream.mark(1); - int thisStartPos = pduDataStream.available(); - int thisEndPos = 0; - int value = pduDataStream.read(); - - if (value == PduPart.P_DISPOSITION_FROM_DATA ) { - part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA); - } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) { - part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT); - } else if (value == PduPart.P_DISPOSITION_INLINE) { - part.setContentDisposition(PduPart.DISPOSITION_INLINE); - } else { - pduDataStream.reset(); - /* Token-text */ - part.setContentDisposition(parseWapString(pduDataStream - , TYPE_TEXT_STRING)); - } - - /* get filename parameter and skip other parameters */ - thisEndPos = pduDataStream.available(); - if (thisStartPos - thisEndPos < len) { - value = pduDataStream.read(); - if (value == PduPart.P_FILENAME) { //filename is text-string - part.setFilename(parseWapString(pduDataStream - , TYPE_TEXT_STRING)); - } - - /* skip other parameters */ - thisEndPos = pduDataStream.available(); - if (thisStartPos - thisEndPos < len) { - int last = len - (thisStartPos - thisEndPos); - byte[] temp = new byte[last]; - pduDataStream.read(temp, 0, last); - } - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - } - break; - default: - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Part headers: " + header); - } - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - lastLen = 0; - break; - } - } else if ((header >= TEXT_MIN) && (header <= TEXT_MAX)) { - // Not assigned header. - byte[] tempHeader = parseWapString(pduDataStream, TYPE_TEXT_STRING); - byte[] tempValue = parseWapString(pduDataStream, TYPE_TEXT_STRING); - - // Check the header whether it is "Content-Transfer-Encoding". - if (true == - PduPart.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(new String(tempHeader))) { - part.setContentTransferEncoding(tempValue); - } - - tempPos = pduDataStream.available(); - lastLen = length - (startPos - tempPos); - } else { - if (LOCAL_LOGV) { - Log.v(LOG_TAG, "Not supported Part headers: " + header); - } - // Skip all headers of this part. - if (-1 == skipWapValue(pduDataStream, lastLen)) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - lastLen = 0; - } - } - - if (0 != lastLen) { - Log.e(LOG_TAG, "Corrupt Part headers"); - return false; - } - - return true; - } - - /** - * Check the position of a specified part. - * - * @param part the part to be checked - * @return part position, THE_FIRST_PART when it's the - * first one, THE_LAST_PART when it's the last one. - */ - @UnsupportedAppUsage - private static int checkPartPosition(PduPart part) { - assert(null != part); - if ((null == mTypeParam) && - (null == mStartParam)) { - return THE_LAST_PART; - } - - /* check part's content-id */ - if (null != mStartParam) { - byte[] contentId = part.getContentId(); - if (null != contentId) { - if (true == Arrays.equals(mStartParam, contentId)) { - return THE_FIRST_PART; - } - } - // This is not the first part, so append to end (keeping the original order) - // Check b/19607294 for details of this change - return THE_LAST_PART; - } - - /* check part's content-type */ - if (null != mTypeParam) { - byte[] contentType = part.getContentType(); - if (null != contentType) { - if (true == Arrays.equals(mTypeParam, contentType)) { - return THE_FIRST_PART; - } - } - } - - return THE_LAST_PART; - } - - /** - * Check mandatory headers of a pdu. - * - * @param headers pdu headers - * @return true if the pdu has all of the mandatory headers, false otherwise. - */ - protected static boolean checkMandatoryHeader(PduHeaders headers) { - if (null == headers) { - return false; - } - - /* get message type */ - int messageType = headers.getOctet(PduHeaders.MESSAGE_TYPE); - - /* check Mms-Version field */ - int mmsVersion = headers.getOctet(PduHeaders.MMS_VERSION); - if (0 == mmsVersion) { - // Every message should have Mms-Version field. - return false; - } - - /* check mandatory header fields */ - switch (messageType) { - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - // Content-Type field. - byte[] srContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); - if (null == srContentType) { - return false; - } - - // From field. - EncodedStringValue srFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == srFrom) { - return false; - } - - // Transaction-Id field. - byte[] srTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == srTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_SEND_CONF: - // Response-Status field. - int scResponseStatus = headers.getOctet(PduHeaders.RESPONSE_STATUS); - if (0 == scResponseStatus) { - return false; - } - - // Transaction-Id field. - byte[] scTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == scTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - // Content-Location field. - byte[] niContentLocation = headers.getTextString(PduHeaders.CONTENT_LOCATION); - if (null == niContentLocation) { - return false; - } - - // Expiry field. - long niExpiry = headers.getLongInteger(PduHeaders.EXPIRY); - if (-1 == niExpiry) { - return false; - } - - // Message-Class field. - byte[] niMessageClass = headers.getTextString(PduHeaders.MESSAGE_CLASS); - if (null == niMessageClass) { - return false; - } - - // Message-Size field. - long niMessageSize = headers.getLongInteger(PduHeaders.MESSAGE_SIZE); - if (-1 == niMessageSize) { - return false; - } - - // Transaction-Id field. - byte[] niTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == niTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - // Status field. - int nriStatus = headers.getOctet(PduHeaders.STATUS); - if (0 == nriStatus) { - return false; - } - - // Transaction-Id field. - byte[] nriTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == nriTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - // Content-Type field. - byte[] rcContentType = headers.getTextString(PduHeaders.CONTENT_TYPE); - if (null == rcContentType) { - return false; - } - - // Date field. - long rcDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == rcDate) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: - // Date field. - long diDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == diDate) { - return false; - } - - // Message-Id field. - byte[] diMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == diMessageId) { - return false; - } - - // Status field. - int diStatus = headers.getOctet(PduHeaders.STATUS); - if (0 == diStatus) { - return false; - } - - // To field. - EncodedStringValue[] diTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == diTo) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - // Transaction-Id field. - byte[] aiTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID); - if (null == aiTransactionId) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: - // Date field. - long roDate = headers.getLongInteger(PduHeaders.DATE); - if (-1 == roDate) { - return false; - } - - // From field. - EncodedStringValue roFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == roFrom) { - return false; - } - - // Message-Id field. - byte[] roMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == roMessageId) { - return false; - } - - // Read-Status field. - int roReadStatus = headers.getOctet(PduHeaders.READ_STATUS); - if (0 == roReadStatus) { - return false; - } - - // To field. - EncodedStringValue[] roTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == roTo) { - return false; - } - - break; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - // From field. - EncodedStringValue rrFrom = headers.getEncodedStringValue(PduHeaders.FROM); - if (null == rrFrom) { - return false; - } - - // Message-Id field. - byte[] rrMessageId = headers.getTextString(PduHeaders.MESSAGE_ID); - if (null == rrMessageId) { - return false; - } - - // Read-Status field. - int rrReadStatus = headers.getOctet(PduHeaders.READ_STATUS); - if (0 == rrReadStatus) { - return false; - } - - // To field. - EncodedStringValue[] rrTo = headers.getEncodedStringValues(PduHeaders.TO); - if (null == rrTo) { - return false; - } - - break; - default: - // Parser doesn't support this message type in this version. - return false; - } - - return true; - } -} diff --git a/telephony/java/com/google/android/mms/pdu/PduPart.java b/telephony/java/com/google/android/mms/pdu/PduPart.java deleted file mode 100644 index 09b775118dc3..000000000000 --- a/telephony/java/com/google/android/mms/pdu/PduPart.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import android.net.Uri; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.util.HashMap; -import java.util.Map; - -/** - * The pdu part. - */ -public class PduPart { - /** - * Well-Known Parameters. - */ - public static final int P_Q = 0x80; - public static final int P_CHARSET = 0x81; - public static final int P_LEVEL = 0x82; - public static final int P_TYPE = 0x83; - public static final int P_DEP_NAME = 0x85; - public static final int P_DEP_FILENAME = 0x86; - public static final int P_DIFFERENCES = 0x87; - public static final int P_PADDING = 0x88; - // This value of "TYPE" s used with Content-Type: multipart/related - public static final int P_CT_MR_TYPE = 0x89; - public static final int P_DEP_START = 0x8A; - public static final int P_DEP_START_INFO = 0x8B; - public static final int P_DEP_COMMENT = 0x8C; - public static final int P_DEP_DOMAIN = 0x8D; - public static final int P_MAX_AGE = 0x8E; - public static final int P_DEP_PATH = 0x8F; - public static final int P_SECURE = 0x90; - public static final int P_SEC = 0x91; - public static final int P_MAC = 0x92; - public static final int P_CREATION_DATE = 0x93; - public static final int P_MODIFICATION_DATE = 0x94; - public static final int P_READ_DATE = 0x95; - public static final int P_SIZE = 0x96; - public static final int P_NAME = 0x97; - public static final int P_FILENAME = 0x98; - public static final int P_START = 0x99; - public static final int P_START_INFO = 0x9A; - public static final int P_COMMENT = 0x9B; - public static final int P_DOMAIN = 0x9C; - public static final int P_PATH = 0x9D; - - /** - * Header field names. - */ - public static final int P_CONTENT_TYPE = 0x91; - public static final int P_CONTENT_LOCATION = 0x8E; - public static final int P_CONTENT_ID = 0xC0; - public static final int P_DEP_CONTENT_DISPOSITION = 0xAE; - public static final int P_CONTENT_DISPOSITION = 0xC5; - // The next header is unassigned header, use reserved header(0x48) value. - public static final int P_CONTENT_TRANSFER_ENCODING = 0xC8; - - /** - * Content=Transfer-Encoding string. - */ - public static final String CONTENT_TRANSFER_ENCODING = - "Content-Transfer-Encoding"; - - /** - * Value of Content-Transfer-Encoding. - */ - public static final String P_BINARY = "binary"; - public static final String P_7BIT = "7bit"; - public static final String P_8BIT = "8bit"; - public static final String P_BASE64 = "base64"; - public static final String P_QUOTED_PRINTABLE = "quoted-printable"; - - /** - * Value of disposition can be set to PduPart when the value is octet in - * the PDU. - * "from-data" instead of Form-data<Octet 128>. - * "attachment" instead of Attachment<Octet 129>. - * "inline" instead of Inline<Octet 130>. - */ - static final byte[] DISPOSITION_FROM_DATA = "from-data".getBytes(); - static final byte[] DISPOSITION_ATTACHMENT = "attachment".getBytes(); - static final byte[] DISPOSITION_INLINE = "inline".getBytes(); - - /** - * Content-Disposition value. - */ - public static final int P_DISPOSITION_FROM_DATA = 0x80; - public static final int P_DISPOSITION_ATTACHMENT = 0x81; - public static final int P_DISPOSITION_INLINE = 0x82; - - /** - * Header of part. - */ - private Map<Integer, Object> mPartHeader = null; - - /** - * Data uri. - */ - private Uri mUri = null; - - /** - * Part data. - */ - private byte[] mPartData = null; - - private static final String TAG = "PduPart"; - - /** - * Empty Constructor. - */ - @UnsupportedAppUsage - public PduPart() { - mPartHeader = new HashMap<Integer, Object>(); - } - - /** - * Set part data. The data are stored as byte array. - * - * @param data the data - */ - @UnsupportedAppUsage - public void setData(byte[] data) { - if(data == null) { - return; - } - - mPartData = new byte[data.length]; - System.arraycopy(data, 0, mPartData, 0, data.length); - } - - /** - * @return A copy of the part data or null if the data wasn't set or - * the data is stored as Uri. - * @see #getDataUri - */ - @UnsupportedAppUsage - public byte[] getData() { - if(mPartData == null) { - return null; - } - - byte[] byteArray = new byte[mPartData.length]; - System.arraycopy(mPartData, 0, byteArray, 0, mPartData.length); - return byteArray; - } - - /** - * @return The length of the data, if this object have data, else 0. - */ - @UnsupportedAppUsage - public int getDataLength() { - if(mPartData != null){ - return mPartData.length; - } else { - return 0; - } - } - - - /** - * Set data uri. The data are stored as Uri. - * - * @param uri the uri - */ - @UnsupportedAppUsage - public void setDataUri(Uri uri) { - mUri = uri; - } - - /** - * @return The Uri of the part data or null if the data wasn't set or - * the data is stored as byte array. - * @see #getData - */ - @UnsupportedAppUsage - public Uri getDataUri() { - return mUri; - } - - /** - * Set Content-id value - * - * @param contentId the content-id value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setContentId(byte[] contentId) { - if((contentId == null) || (contentId.length == 0)) { - throw new IllegalArgumentException( - "Content-Id may not be null or empty."); - } - - if ((contentId.length > 1) - && ((char) contentId[0] == '<') - && ((char) contentId[contentId.length - 1] == '>')) { - mPartHeader.put(P_CONTENT_ID, contentId); - return; - } - - // Insert beginning '<' and trailing '>' for Content-Id. - byte[] buffer = new byte[contentId.length + 2]; - buffer[0] = (byte) (0xff & '<'); - buffer[buffer.length - 1] = (byte) (0xff & '>'); - System.arraycopy(contentId, 0, buffer, 1, contentId.length); - mPartHeader.put(P_CONTENT_ID, buffer); - } - - /** - * Get Content-id value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getContentId() { - return (byte[]) mPartHeader.get(P_CONTENT_ID); - } - - /** - * Set Char-set value. - * - * @param charset the value - */ - @UnsupportedAppUsage - public void setCharset(int charset) { - mPartHeader.put(P_CHARSET, charset); - } - - /** - * Get Char-set value - * - * @return the charset value. Return 0 if charset was not set. - */ - @UnsupportedAppUsage - public int getCharset() { - Integer charset = (Integer) mPartHeader.get(P_CHARSET); - if(charset == null) { - return 0; - } else { - return charset.intValue(); - } - } - - /** - * Set Content-Location value. - * - * @param contentLocation the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setContentLocation(byte[] contentLocation) { - if(contentLocation == null) { - throw new NullPointerException("null content-location"); - } - - mPartHeader.put(P_CONTENT_LOCATION, contentLocation); - } - - /** - * Get Content-Location value. - * - * @return the value - * return PduPart.disposition[0] instead of <Octet 128> (Form-data). - * return PduPart.disposition[1] instead of <Octet 129> (Attachment). - * return PduPart.disposition[2] instead of <Octet 130> (Inline). - */ - @UnsupportedAppUsage - public byte[] getContentLocation() { - return (byte[]) mPartHeader.get(P_CONTENT_LOCATION); - } - - /** - * Set Content-Disposition value. - * Use PduPart.disposition[0] instead of <Octet 128> (Form-data). - * Use PduPart.disposition[1] instead of <Octet 129> (Attachment). - * Use PduPart.disposition[2] instead of <Octet 130> (Inline). - * - * @param contentDisposition the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setContentDisposition(byte[] contentDisposition) { - if(contentDisposition == null) { - throw new NullPointerException("null content-disposition"); - } - - mPartHeader.put(P_CONTENT_DISPOSITION, contentDisposition); - } - - /** - * Get Content-Disposition value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getContentDisposition() { - return (byte[]) mPartHeader.get(P_CONTENT_DISPOSITION); - } - - /** - * Set Content-Type value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setContentType(byte[] contentType) { - if(contentType == null) { - throw new NullPointerException("null content-type"); - } - - mPartHeader.put(P_CONTENT_TYPE, contentType); - } - - /** - * Get Content-Type value of part. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getContentType() { - return (byte[]) mPartHeader.get(P_CONTENT_TYPE); - } - - /** - * Set Content-Transfer-Encoding value - * - * @param contentId the content-id value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setContentTransferEncoding(byte[] contentTransferEncoding) { - if(contentTransferEncoding == null) { - throw new NullPointerException("null content-transfer-encoding"); - } - - mPartHeader.put(P_CONTENT_TRANSFER_ENCODING, contentTransferEncoding); - } - - /** - * Get Content-Transfer-Encoding value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getContentTransferEncoding() { - return (byte[]) mPartHeader.get(P_CONTENT_TRANSFER_ENCODING); - } - - /** - * Set Content-type parameter: name. - * - * @param name the name value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setName(byte[] name) { - if(null == name) { - throw new NullPointerException("null content-id"); - } - - mPartHeader.put(P_NAME, name); - } - - /** - * Get content-type parameter: name. - * - * @return the name - */ - @UnsupportedAppUsage - public byte[] getName() { - return (byte[]) mPartHeader.get(P_NAME); - } - - /** - * Get Content-disposition parameter: filename - * - * @param fileName the filename value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setFilename(byte[] fileName) { - if(null == fileName) { - throw new NullPointerException("null content-id"); - } - - mPartHeader.put(P_FILENAME, fileName); - } - - /** - * Set Content-disposition parameter: filename - * - * @return the filename - */ - @UnsupportedAppUsage - public byte[] getFilename() { - return (byte[]) mPartHeader.get(P_FILENAME); - } - - @UnsupportedAppUsage - public String generateLocation() { - // Assumption: At least one of the content-location / name / filename - // or content-id should be set. This is guaranteed by the PduParser - // for incoming messages and by MM composer for outgoing messages. - byte[] location = (byte[]) mPartHeader.get(P_NAME); - if(null == location) { - location = (byte[]) mPartHeader.get(P_FILENAME); - - if (null == location) { - location = (byte[]) mPartHeader.get(P_CONTENT_LOCATION); - } - } - - if (null == location) { - byte[] contentId = (byte[]) mPartHeader.get(P_CONTENT_ID); - return "cid:" + new String(contentId); - } else { - return new String(location); - } - } -} - diff --git a/telephony/java/com/google/android/mms/pdu/PduPersister.java b/telephony/java/com/google/android/mms/pdu/PduPersister.java deleted file mode 100755 index 93f30657bf1b..000000000000 --- a/telephony/java/com/google/android/mms/pdu/PduPersister.java +++ /dev/null @@ -1,1573 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.DatabaseUtils; -import android.drm.DrmManagerClient; -import android.net.Uri; -import android.os.ParcelFileDescriptor; -import android.provider.Telephony; -import android.provider.Telephony.Mms; -import android.provider.Telephony.Mms.Addr; -import android.provider.Telephony.Mms.Part; -import android.provider.Telephony.MmsSms; -import android.provider.Telephony.MmsSms.PendingMessages; -import android.provider.Telephony.Threads; -import android.telephony.PhoneNumberUtils; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.Log; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.ContentType; -import com.google.android.mms.InvalidHeaderValueException; -import com.google.android.mms.MmsException; -import com.google.android.mms.util.DownloadDrmHelper; -import com.google.android.mms.util.DrmConvertSession; -import com.google.android.mms.util.PduCache; -import com.google.android.mms.util.PduCacheEntry; -import com.google.android.mms.util.SqliteWrapper; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * This class is the high-level manager of PDU storage. - */ -public class PduPersister { - private static final String TAG = "PduPersister"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - private static final long DUMMY_THREAD_ID = Long.MAX_VALUE; - - /** - * The uri of temporary drm objects. - */ - public static final String TEMPORARY_DRM_OBJECT_URI = - "content://mms/" + Long.MAX_VALUE + "/part"; - /** - * Indicate that we transiently failed to process a MM. - */ - public static final int PROC_STATUS_TRANSIENT_FAILURE = 1; - /** - * Indicate that we permanently failed to process a MM. - */ - public static final int PROC_STATUS_PERMANENTLY_FAILURE = 2; - /** - * Indicate that we have successfully processed a MM. - */ - public static final int PROC_STATUS_COMPLETED = 3; - - private static PduPersister sPersister; - @UnsupportedAppUsage - private static final PduCache PDU_CACHE_INSTANCE; - - @UnsupportedAppUsage - private static final int[] ADDRESS_FIELDS = new int[] { - PduHeaders.BCC, - PduHeaders.CC, - PduHeaders.FROM, - PduHeaders.TO - }; - - private static final String[] PDU_PROJECTION = new String[] { - Mms._ID, - Mms.MESSAGE_BOX, - Mms.THREAD_ID, - Mms.RETRIEVE_TEXT, - Mms.SUBJECT, - Mms.CONTENT_LOCATION, - Mms.CONTENT_TYPE, - Mms.MESSAGE_CLASS, - Mms.MESSAGE_ID, - Mms.RESPONSE_TEXT, - Mms.TRANSACTION_ID, - Mms.CONTENT_CLASS, - Mms.DELIVERY_REPORT, - Mms.MESSAGE_TYPE, - Mms.MMS_VERSION, - Mms.PRIORITY, - Mms.READ_REPORT, - Mms.READ_STATUS, - Mms.REPORT_ALLOWED, - Mms.RETRIEVE_STATUS, - Mms.STATUS, - Mms.DATE, - Mms.DELIVERY_TIME, - Mms.EXPIRY, - Mms.MESSAGE_SIZE, - Mms.SUBJECT_CHARSET, - Mms.RETRIEVE_TEXT_CHARSET, - }; - - private static final int PDU_COLUMN_ID = 0; - private static final int PDU_COLUMN_MESSAGE_BOX = 1; - private static final int PDU_COLUMN_THREAD_ID = 2; - private static final int PDU_COLUMN_RETRIEVE_TEXT = 3; - private static final int PDU_COLUMN_SUBJECT = 4; - private static final int PDU_COLUMN_CONTENT_LOCATION = 5; - private static final int PDU_COLUMN_CONTENT_TYPE = 6; - private static final int PDU_COLUMN_MESSAGE_CLASS = 7; - private static final int PDU_COLUMN_MESSAGE_ID = 8; - private static final int PDU_COLUMN_RESPONSE_TEXT = 9; - private static final int PDU_COLUMN_TRANSACTION_ID = 10; - private static final int PDU_COLUMN_CONTENT_CLASS = 11; - private static final int PDU_COLUMN_DELIVERY_REPORT = 12; - private static final int PDU_COLUMN_MESSAGE_TYPE = 13; - private static final int PDU_COLUMN_MMS_VERSION = 14; - private static final int PDU_COLUMN_PRIORITY = 15; - private static final int PDU_COLUMN_READ_REPORT = 16; - private static final int PDU_COLUMN_READ_STATUS = 17; - private static final int PDU_COLUMN_REPORT_ALLOWED = 18; - private static final int PDU_COLUMN_RETRIEVE_STATUS = 19; - private static final int PDU_COLUMN_STATUS = 20; - private static final int PDU_COLUMN_DATE = 21; - private static final int PDU_COLUMN_DELIVERY_TIME = 22; - private static final int PDU_COLUMN_EXPIRY = 23; - private static final int PDU_COLUMN_MESSAGE_SIZE = 24; - private static final int PDU_COLUMN_SUBJECT_CHARSET = 25; - private static final int PDU_COLUMN_RETRIEVE_TEXT_CHARSET = 26; - - @UnsupportedAppUsage - private static final String[] PART_PROJECTION = new String[] { - Part._ID, - Part.CHARSET, - Part.CONTENT_DISPOSITION, - Part.CONTENT_ID, - Part.CONTENT_LOCATION, - Part.CONTENT_TYPE, - Part.FILENAME, - Part.NAME, - Part.TEXT - }; - - private static final int PART_COLUMN_ID = 0; - private static final int PART_COLUMN_CHARSET = 1; - private static final int PART_COLUMN_CONTENT_DISPOSITION = 2; - private static final int PART_COLUMN_CONTENT_ID = 3; - private static final int PART_COLUMN_CONTENT_LOCATION = 4; - private static final int PART_COLUMN_CONTENT_TYPE = 5; - private static final int PART_COLUMN_FILENAME = 6; - private static final int PART_COLUMN_NAME = 7; - private static final int PART_COLUMN_TEXT = 8; - - @UnsupportedAppUsage - private static final HashMap<Uri, Integer> MESSAGE_BOX_MAP; - // These map are used for convenience in persist() and load(). - private static final HashMap<Integer, Integer> CHARSET_COLUMN_INDEX_MAP; - private static final HashMap<Integer, Integer> ENCODED_STRING_COLUMN_INDEX_MAP; - private static final HashMap<Integer, Integer> TEXT_STRING_COLUMN_INDEX_MAP; - private static final HashMap<Integer, Integer> OCTET_COLUMN_INDEX_MAP; - private static final HashMap<Integer, Integer> LONG_COLUMN_INDEX_MAP; - @UnsupportedAppUsage - private static final HashMap<Integer, String> CHARSET_COLUMN_NAME_MAP; - @UnsupportedAppUsage - private static final HashMap<Integer, String> ENCODED_STRING_COLUMN_NAME_MAP; - @UnsupportedAppUsage - private static final HashMap<Integer, String> TEXT_STRING_COLUMN_NAME_MAP; - @UnsupportedAppUsage - private static final HashMap<Integer, String> OCTET_COLUMN_NAME_MAP; - @UnsupportedAppUsage - private static final HashMap<Integer, String> LONG_COLUMN_NAME_MAP; - - static { - MESSAGE_BOX_MAP = new HashMap<Uri, Integer>(); - MESSAGE_BOX_MAP.put(Mms.Inbox.CONTENT_URI, Mms.MESSAGE_BOX_INBOX); - MESSAGE_BOX_MAP.put(Mms.Sent.CONTENT_URI, Mms.MESSAGE_BOX_SENT); - MESSAGE_BOX_MAP.put(Mms.Draft.CONTENT_URI, Mms.MESSAGE_BOX_DRAFTS); - MESSAGE_BOX_MAP.put(Mms.Outbox.CONTENT_URI, Mms.MESSAGE_BOX_OUTBOX); - - CHARSET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); - CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT_CHARSET); - CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT_CHARSET); - - CHARSET_COLUMN_NAME_MAP = new HashMap<Integer, String>(); - CHARSET_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT_CHARSET); - CHARSET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT_CHARSET); - - // Encoded string field code -> column index/name map. - ENCODED_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); - ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT); - ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT); - - ENCODED_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>(); - ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT); - ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT); - - // Text string field code -> column index/name map. - TEXT_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_LOCATION, PDU_COLUMN_CONTENT_LOCATION); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_TYPE, PDU_COLUMN_CONTENT_TYPE); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_CLASS, PDU_COLUMN_MESSAGE_CLASS); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_ID, PDU_COLUMN_MESSAGE_ID); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RESPONSE_TEXT, PDU_COLUMN_RESPONSE_TEXT); - TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.TRANSACTION_ID, PDU_COLUMN_TRANSACTION_ID); - - TEXT_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>(); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_LOCATION, Mms.CONTENT_LOCATION); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_TYPE, Mms.CONTENT_TYPE); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_CLASS, Mms.MESSAGE_CLASS); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_ID, Mms.MESSAGE_ID); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.RESPONSE_TEXT, Mms.RESPONSE_TEXT); - TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.TRANSACTION_ID, Mms.TRANSACTION_ID); - - // Octet field code -> column index/name map. - OCTET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_CLASS, PDU_COLUMN_CONTENT_CLASS); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_REPORT, PDU_COLUMN_DELIVERY_REPORT); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_TYPE, PDU_COLUMN_MESSAGE_TYPE); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MMS_VERSION, PDU_COLUMN_MMS_VERSION); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.PRIORITY, PDU_COLUMN_PRIORITY); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_REPORT, PDU_COLUMN_READ_REPORT); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_STATUS, PDU_COLUMN_READ_STATUS); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.REPORT_ALLOWED, PDU_COLUMN_REPORT_ALLOWED); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_STATUS, PDU_COLUMN_RETRIEVE_STATUS); - OCTET_COLUMN_INDEX_MAP.put(PduHeaders.STATUS, PDU_COLUMN_STATUS); - - OCTET_COLUMN_NAME_MAP = new HashMap<Integer, String>(); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_CLASS, Mms.CONTENT_CLASS); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_REPORT, Mms.DELIVERY_REPORT); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_TYPE, Mms.MESSAGE_TYPE); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.MMS_VERSION, Mms.MMS_VERSION); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.PRIORITY, Mms.PRIORITY); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_REPORT, Mms.READ_REPORT); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_STATUS, Mms.READ_STATUS); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.REPORT_ALLOWED, Mms.REPORT_ALLOWED); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_STATUS, Mms.RETRIEVE_STATUS); - OCTET_COLUMN_NAME_MAP.put(PduHeaders.STATUS, Mms.STATUS); - - // Long field code -> column index/name map. - LONG_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); - LONG_COLUMN_INDEX_MAP.put(PduHeaders.DATE, PDU_COLUMN_DATE); - LONG_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_TIME, PDU_COLUMN_DELIVERY_TIME); - LONG_COLUMN_INDEX_MAP.put(PduHeaders.EXPIRY, PDU_COLUMN_EXPIRY); - LONG_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_SIZE, PDU_COLUMN_MESSAGE_SIZE); - - LONG_COLUMN_NAME_MAP = new HashMap<Integer, String>(); - LONG_COLUMN_NAME_MAP.put(PduHeaders.DATE, Mms.DATE); - LONG_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_TIME, Mms.DELIVERY_TIME); - LONG_COLUMN_NAME_MAP.put(PduHeaders.EXPIRY, Mms.EXPIRY); - LONG_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_SIZE, Mms.MESSAGE_SIZE); - - PDU_CACHE_INSTANCE = PduCache.getInstance(); - } - - @UnsupportedAppUsage - private final Context mContext; - @UnsupportedAppUsage - private final ContentResolver mContentResolver; - private final DrmManagerClient mDrmManagerClient; - @UnsupportedAppUsage - private final TelephonyManager mTelephonyManager; - - private PduPersister(Context context) { - mContext = context; - mContentResolver = context.getContentResolver(); - mDrmManagerClient = new DrmManagerClient(context); - mTelephonyManager = (TelephonyManager)context - .getSystemService(Context.TELEPHONY_SERVICE); - } - - /** Get(or create if not exist) an instance of PduPersister */ - @UnsupportedAppUsage - public static PduPersister getPduPersister(Context context) { - if ((sPersister == null)) { - sPersister = new PduPersister(context); - } else if (!context.equals(sPersister.mContext)) { - sPersister.release(); - sPersister = new PduPersister(context); - } - - return sPersister; - } - - private void setEncodedStringValueToHeaders( - Cursor c, int columnIndex, - PduHeaders headers, int mapColumn) { - String s = c.getString(columnIndex); - if ((s != null) && (s.length() > 0)) { - int charsetColumnIndex = CHARSET_COLUMN_INDEX_MAP.get(mapColumn); - int charset = c.getInt(charsetColumnIndex); - EncodedStringValue value = new EncodedStringValue( - charset, getBytes(s)); - headers.setEncodedStringValue(value, mapColumn); - } - } - - private void setTextStringToHeaders( - Cursor c, int columnIndex, - PduHeaders headers, int mapColumn) { - String s = c.getString(columnIndex); - if (s != null) { - headers.setTextString(getBytes(s), mapColumn); - } - } - - private void setOctetToHeaders( - Cursor c, int columnIndex, - PduHeaders headers, int mapColumn) throws InvalidHeaderValueException { - if (!c.isNull(columnIndex)) { - int b = c.getInt(columnIndex); - headers.setOctet(b, mapColumn); - } - } - - private void setLongToHeaders( - Cursor c, int columnIndex, - PduHeaders headers, int mapColumn) { - if (!c.isNull(columnIndex)) { - long l = c.getLong(columnIndex); - headers.setLongInteger(l, mapColumn); - } - } - - @UnsupportedAppUsage - private Integer getIntegerFromPartColumn(Cursor c, int columnIndex) { - if (!c.isNull(columnIndex)) { - return c.getInt(columnIndex); - } - return null; - } - - @UnsupportedAppUsage - private byte[] getByteArrayFromPartColumn(Cursor c, int columnIndex) { - if (!c.isNull(columnIndex)) { - return getBytes(c.getString(columnIndex)); - } - return null; - } - - private PduPart[] loadParts(long msgId) throws MmsException { - Cursor c = SqliteWrapper.query(mContext, mContentResolver, - Uri.parse("content://mms/" + msgId + "/part"), - PART_PROJECTION, null, null, null); - - PduPart[] parts = null; - - try { - if ((c == null) || (c.getCount() == 0)) { - if (LOCAL_LOGV) { - Log.v(TAG, "loadParts(" + msgId + "): no part to load."); - } - return null; - } - - int partCount = c.getCount(); - int partIdx = 0; - parts = new PduPart[partCount]; - while (c.moveToNext()) { - PduPart part = new PduPart(); - Integer charset = getIntegerFromPartColumn( - c, PART_COLUMN_CHARSET); - if (charset != null) { - part.setCharset(charset); - } - - byte[] contentDisposition = getByteArrayFromPartColumn( - c, PART_COLUMN_CONTENT_DISPOSITION); - if (contentDisposition != null) { - part.setContentDisposition(contentDisposition); - } - - byte[] contentId = getByteArrayFromPartColumn( - c, PART_COLUMN_CONTENT_ID); - if (contentId != null) { - part.setContentId(contentId); - } - - byte[] contentLocation = getByteArrayFromPartColumn( - c, PART_COLUMN_CONTENT_LOCATION); - if (contentLocation != null) { - part.setContentLocation(contentLocation); - } - - byte[] contentType = getByteArrayFromPartColumn( - c, PART_COLUMN_CONTENT_TYPE); - if (contentType != null) { - part.setContentType(contentType); - } else { - throw new MmsException("Content-Type must be set."); - } - - byte[] fileName = getByteArrayFromPartColumn( - c, PART_COLUMN_FILENAME); - if (fileName != null) { - part.setFilename(fileName); - } - - byte[] name = getByteArrayFromPartColumn( - c, PART_COLUMN_NAME); - if (name != null) { - part.setName(name); - } - - // Construct a Uri for this part. - long partId = c.getLong(PART_COLUMN_ID); - Uri partURI = Uri.parse("content://mms/part/" + partId); - part.setDataUri(partURI); - - // For images/audio/video, we won't keep their data in Part - // because their renderer accept Uri as source. - String type = toIsoString(contentType); - if (!ContentType.isImageType(type) - && !ContentType.isAudioType(type) - && !ContentType.isVideoType(type)) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - InputStream is = null; - - // Store simple string values directly in the database instead of an - // external file. This makes the text searchable and retrieval slightly - // faster. - if (ContentType.TEXT_PLAIN.equals(type) || ContentType.APP_SMIL.equals(type) - || ContentType.TEXT_HTML.equals(type)) { - String text = c.getString(PART_COLUMN_TEXT); - byte [] blob = new EncodedStringValue(text != null ? text : "") - .getTextString(); - baos.write(blob, 0, blob.length); - } else { - - try { - is = mContentResolver.openInputStream(partURI); - - byte[] buffer = new byte[256]; - int len = is.read(buffer); - while (len >= 0) { - baos.write(buffer, 0, len); - len = is.read(buffer); - } - } catch (IOException e) { - Log.e(TAG, "Failed to load part data", e); - c.close(); - throw new MmsException(e); - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException e) { - Log.e(TAG, "Failed to close stream", e); - } // Ignore - } - } - } - part.setData(baos.toByteArray()); - } - parts[partIdx++] = part; - } - } finally { - if (c != null) { - c.close(); - } - } - - return parts; - } - - private void loadAddress(long msgId, PduHeaders headers) { - Cursor c = SqliteWrapper.query(mContext, mContentResolver, - Uri.parse("content://mms/" + msgId + "/addr"), - new String[] { Addr.ADDRESS, Addr.CHARSET, Addr.TYPE }, - null, null, null); - - if (c != null) { - try { - while (c.moveToNext()) { - String addr = c.getString(0); - if (!TextUtils.isEmpty(addr)) { - int addrType = c.getInt(2); - switch (addrType) { - case PduHeaders.FROM: - headers.setEncodedStringValue( - new EncodedStringValue(c.getInt(1), getBytes(addr)), - addrType); - break; - case PduHeaders.TO: - case PduHeaders.CC: - case PduHeaders.BCC: - headers.appendEncodedStringValue( - new EncodedStringValue(c.getInt(1), getBytes(addr)), - addrType); - break; - default: - Log.e(TAG, "Unknown address type: " + addrType); - break; - } - } - } - } finally { - c.close(); - } - } - } - - /** - * Load a PDU from storage by given Uri. - * - * @param uri The Uri of the PDU to be loaded. - * @return A generic PDU object, it may be cast to dedicated PDU. - * @throws MmsException Failed to load some fields of a PDU. - */ - @UnsupportedAppUsage - public GenericPdu load(Uri uri) throws MmsException { - GenericPdu pdu = null; - PduCacheEntry cacheEntry = null; - int msgBox = 0; - long threadId = -1; - try { - synchronized(PDU_CACHE_INSTANCE) { - if (PDU_CACHE_INSTANCE.isUpdating(uri)) { - if (LOCAL_LOGV) { - Log.v(TAG, "load: " + uri + " blocked by isUpdating()"); - } - try { - PDU_CACHE_INSTANCE.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "load: ", e); - } - cacheEntry = PDU_CACHE_INSTANCE.get(uri); - if (cacheEntry != null) { - return cacheEntry.getPdu(); - } - } - // Tell the cache to indicate to other callers that this item - // is currently being updated. - PDU_CACHE_INSTANCE.setUpdating(uri, true); - } - - Cursor c = SqliteWrapper.query(mContext, mContentResolver, uri, - PDU_PROJECTION, null, null, null); - PduHeaders headers = new PduHeaders(); - Set<Entry<Integer, Integer>> set; - long msgId = ContentUris.parseId(uri); - - try { - if ((c == null) || (c.getCount() != 1) || !c.moveToFirst()) { - throw new MmsException("Bad uri: " + uri); - } - - msgBox = c.getInt(PDU_COLUMN_MESSAGE_BOX); - threadId = c.getLong(PDU_COLUMN_THREAD_ID); - - set = ENCODED_STRING_COLUMN_INDEX_MAP.entrySet(); - for (Entry<Integer, Integer> e : set) { - setEncodedStringValueToHeaders( - c, e.getValue(), headers, e.getKey()); - } - - set = TEXT_STRING_COLUMN_INDEX_MAP.entrySet(); - for (Entry<Integer, Integer> e : set) { - setTextStringToHeaders( - c, e.getValue(), headers, e.getKey()); - } - - set = OCTET_COLUMN_INDEX_MAP.entrySet(); - for (Entry<Integer, Integer> e : set) { - setOctetToHeaders( - c, e.getValue(), headers, e.getKey()); - } - - set = LONG_COLUMN_INDEX_MAP.entrySet(); - for (Entry<Integer, Integer> e : set) { - setLongToHeaders( - c, e.getValue(), headers, e.getKey()); - } - } finally { - if (c != null) { - c.close(); - } - } - - // Check whether 'msgId' has been assigned a valid value. - if (msgId == -1L) { - throw new MmsException("Error! ID of the message: -1."); - } - - // Load address information of the MM. - loadAddress(msgId, headers); - - int msgType = headers.getOctet(PduHeaders.MESSAGE_TYPE); - PduBody body = new PduBody(); - - // For PDU which type is M_retrieve.conf or Send.req, we should - // load multiparts and put them into the body of the PDU. - if ((msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) - || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) { - PduPart[] parts = loadParts(msgId); - if (parts != null) { - int partsNum = parts.length; - for (int i = 0; i < partsNum; i++) { - body.addPart(parts[i]); - } - } - } - - switch (msgType) { - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - pdu = new NotificationInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: - pdu = new DeliveryInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: - pdu = new ReadOrigInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - pdu = new RetrieveConf(headers, body); - break; - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - pdu = new SendReq(headers, body); - break; - case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: - pdu = new AcknowledgeInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: - pdu = new NotifyRespInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_READ_REC_IND: - pdu = new ReadRecInd(headers); - break; - case PduHeaders.MESSAGE_TYPE_SEND_CONF: - case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: - case PduHeaders.MESSAGE_TYPE_FORWARD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_MBOX_DESCR: - case PduHeaders.MESSAGE_TYPE_DELETE_REQ: - case PduHeaders.MESSAGE_TYPE_DELETE_CONF: - case PduHeaders.MESSAGE_TYPE_CANCEL_REQ: - case PduHeaders.MESSAGE_TYPE_CANCEL_CONF: - throw new MmsException( - "Unsupported PDU type: " + Integer.toHexString(msgType)); - - default: - throw new MmsException( - "Unrecognized PDU type: " + Integer.toHexString(msgType)); - } - } finally { - synchronized(PDU_CACHE_INSTANCE) { - if (pdu != null) { - assert(PDU_CACHE_INSTANCE.get(uri) == null); - // Update the cache entry with the real info - cacheEntry = new PduCacheEntry(pdu, msgBox, threadId); - PDU_CACHE_INSTANCE.put(uri, cacheEntry); - } - PDU_CACHE_INSTANCE.setUpdating(uri, false); - PDU_CACHE_INSTANCE.notifyAll(); // tell anybody waiting on this entry to go ahead - } - } - return pdu; - } - - @UnsupportedAppUsage - private void persistAddress( - long msgId, int type, EncodedStringValue[] array) { - ContentValues values = new ContentValues(3); - - for (EncodedStringValue addr : array) { - values.clear(); // Clear all values first. - values.put(Addr.ADDRESS, toIsoString(addr.getTextString())); - values.put(Addr.CHARSET, addr.getCharacterSet()); - values.put(Addr.TYPE, type); - - Uri uri = Uri.parse("content://mms/" + msgId + "/addr"); - SqliteWrapper.insert(mContext, mContentResolver, uri, values); - } - } - - @UnsupportedAppUsage - private static String getPartContentType(PduPart part) { - return part.getContentType() == null ? null : toIsoString(part.getContentType()); - } - - @UnsupportedAppUsage - public Uri persistPart(PduPart part, long msgId, HashMap<Uri, InputStream> preOpenedFiles) - throws MmsException { - Uri uri = Uri.parse("content://mms/" + msgId + "/part"); - ContentValues values = new ContentValues(8); - - int charset = part.getCharset(); - if (charset != 0 ) { - values.put(Part.CHARSET, charset); - } - - String contentType = getPartContentType(part); - if (contentType != null) { - // There is no "image/jpg" in Android (and it's an invalid mimetype). - // Change it to "image/jpeg" - if (ContentType.IMAGE_JPG.equals(contentType)) { - contentType = ContentType.IMAGE_JPEG; - } - - values.put(Part.CONTENT_TYPE, contentType); - // To ensure the SMIL part is always the first part. - if (ContentType.APP_SMIL.equals(contentType)) { - values.put(Part.SEQ, -1); - } - } else { - throw new MmsException("MIME type of the part must be set."); - } - - if (part.getFilename() != null) { - String fileName = new String(part.getFilename()); - values.put(Part.FILENAME, fileName); - } - - if (part.getName() != null) { - String name = new String(part.getName()); - values.put(Part.NAME, name); - } - - Object value = null; - if (part.getContentDisposition() != null) { - value = toIsoString(part.getContentDisposition()); - values.put(Part.CONTENT_DISPOSITION, (String) value); - } - - if (part.getContentId() != null) { - value = toIsoString(part.getContentId()); - values.put(Part.CONTENT_ID, (String) value); - } - - if (part.getContentLocation() != null) { - value = toIsoString(part.getContentLocation()); - values.put(Part.CONTENT_LOCATION, (String) value); - } - - Uri res = SqliteWrapper.insert(mContext, mContentResolver, uri, values); - if (res == null) { - throw new MmsException("Failed to persist part, return null."); - } - - persistData(part, res, contentType, preOpenedFiles); - // After successfully store the data, we should update - // the dataUri of the part. - part.setDataUri(res); - - return res; - } - - /** - * Save data of the part into storage. The source data may be given - * by a byte[] or a Uri. If it's a byte[], directly save it - * into storage, otherwise load source data from the dataUri and then - * save it. If the data is an image, we may scale down it according - * to user preference. - * - * @param part The PDU part which contains data to be saved. - * @param uri The URI of the part. - * @param contentType The MIME type of the part. - * @param preOpenedFiles if not null, a map of preopened InputStreams for the parts. - * @throws MmsException Cannot find source data or error occurred - * while saving the data. - */ - private void persistData(PduPart part, Uri uri, - String contentType, HashMap<Uri, InputStream> preOpenedFiles) - throws MmsException { - OutputStream os = null; - InputStream is = null; - DrmConvertSession drmConvertSession = null; - Uri dataUri = null; - String path = null; - - try { - byte[] data = part.getData(); - if (ContentType.TEXT_PLAIN.equals(contentType) - || ContentType.APP_SMIL.equals(contentType) - || ContentType.TEXT_HTML.equals(contentType)) { - ContentValues cv = new ContentValues(); - if (data == null) { - data = new String("").getBytes(CharacterSets.DEFAULT_CHARSET_NAME); - } - cv.put(Telephony.Mms.Part.TEXT, new EncodedStringValue(data).getString()); - if (mContentResolver.update(uri, cv, null, null) != 1) { - throw new MmsException("unable to update " + uri.toString()); - } - } else { - boolean isDrm = DownloadDrmHelper.isDrmConvertNeeded(contentType); - if (isDrm) { - if (uri != null) { - try (ParcelFileDescriptor pfd = - mContentResolver.openFileDescriptor(uri, "r")) { - if (pfd.getStatSize() > 0) { - // we're not going to re-persist and re-encrypt an already - // converted drm file - return; - } - } catch (Exception e) { - Log.e(TAG, "Can't get file info for: " + part.getDataUri(), e); - } - } - // We haven't converted the file yet, start the conversion - drmConvertSession = DrmConvertSession.open(mContext, contentType); - if (drmConvertSession == null) { - throw new MmsException("Mimetype " + contentType + - " can not be converted."); - } - } - // uri can look like: - // content://mms/part/98 - os = mContentResolver.openOutputStream(uri); - if (data == null) { - dataUri = part.getDataUri(); - if ((dataUri == null) || (dataUri.equals(uri))) { - Log.w(TAG, "Can't find data for this part."); - return; - } - // dataUri can look like: - // content://com.google.android.gallery3d.provider/picasa/item/5720646660183715586 - if (preOpenedFiles != null && preOpenedFiles.containsKey(dataUri)) { - is = preOpenedFiles.get(dataUri); - } - if (is == null) { - is = mContentResolver.openInputStream(dataUri); - } - - if (LOCAL_LOGV) { - Log.v(TAG, "Saving data to: " + uri); - } - - byte[] buffer = new byte[8192]; - for (int len = 0; (len = is.read(buffer)) != -1; ) { - if (!isDrm) { - os.write(buffer, 0, len); - } else { - byte[] convertedData = drmConvertSession.convert(buffer, len); - if (convertedData != null) { - os.write(convertedData, 0, convertedData.length); - } else { - throw new MmsException("Error converting drm data."); - } - } - } - } else { - if (LOCAL_LOGV) { - Log.v(TAG, "Saving data to: " + uri); - } - if (!isDrm) { - os.write(data); - } else { - dataUri = uri; - byte[] convertedData = drmConvertSession.convert(data, data.length); - if (convertedData != null) { - os.write(convertedData, 0, convertedData.length); - } else { - throw new MmsException("Error converting drm data."); - } - } - } - } - } catch (FileNotFoundException e) { - Log.e(TAG, "Failed to open Input/Output stream.", e); - throw new MmsException(e); - } catch (IOException e) { - Log.e(TAG, "Failed to read/write data.", e); - throw new MmsException(e); - } finally { - if (os != null) { - try { - os.close(); - } catch (IOException e) { - Log.e(TAG, "IOException while closing: " + os, e); - } // Ignore - } - if (is != null) { - try { - is.close(); - } catch (IOException e) { - Log.e(TAG, "IOException while closing: " + is, e); - } // Ignore - } - if (drmConvertSession != null) { - drmConvertSession.close(path); - - // Reset the permissions on the encrypted part file so everyone has only read - // permission. - File f = new File(path); - ContentValues values = new ContentValues(0); - SqliteWrapper.update(mContext, mContentResolver, - Uri.parse("content://mms/resetFilePerm/" + f.getName()), - values, null, null); - } - } - } - - @UnsupportedAppUsage - private void updateAddress( - long msgId, int type, EncodedStringValue[] array) { - // Delete old address information and then insert new ones. - SqliteWrapper.delete(mContext, mContentResolver, - Uri.parse("content://mms/" + msgId + "/addr"), - Addr.TYPE + "=" + type, null); - - persistAddress(msgId, type, array); - } - - /** - * Update headers of a SendReq. - * - * @param uri The PDU which need to be updated. - * @param pdu New headers. - * @throws MmsException Bad URI or updating failed. - */ - @UnsupportedAppUsage - public void updateHeaders(Uri uri, SendReq sendReq) { - synchronized(PDU_CACHE_INSTANCE) { - // If the cache item is getting updated, wait until it's done updating before - // purging it. - if (PDU_CACHE_INSTANCE.isUpdating(uri)) { - if (LOCAL_LOGV) { - Log.v(TAG, "updateHeaders: " + uri + " blocked by isUpdating()"); - } - try { - PDU_CACHE_INSTANCE.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "updateHeaders: ", e); - } - } - } - PDU_CACHE_INSTANCE.purge(uri); - - ContentValues values = new ContentValues(10); - byte[] contentType = sendReq.getContentType(); - if (contentType != null) { - values.put(Mms.CONTENT_TYPE, toIsoString(contentType)); - } - - long date = sendReq.getDate(); - if (date != -1) { - values.put(Mms.DATE, date); - } - - int deliveryReport = sendReq.getDeliveryReport(); - if (deliveryReport != 0) { - values.put(Mms.DELIVERY_REPORT, deliveryReport); - } - - long expiry = sendReq.getExpiry(); - if (expiry != -1) { - values.put(Mms.EXPIRY, expiry); - } - - byte[] msgClass = sendReq.getMessageClass(); - if (msgClass != null) { - values.put(Mms.MESSAGE_CLASS, toIsoString(msgClass)); - } - - int priority = sendReq.getPriority(); - if (priority != 0) { - values.put(Mms.PRIORITY, priority); - } - - int readReport = sendReq.getReadReport(); - if (readReport != 0) { - values.put(Mms.READ_REPORT, readReport); - } - - byte[] transId = sendReq.getTransactionId(); - if (transId != null) { - values.put(Mms.TRANSACTION_ID, toIsoString(transId)); - } - - EncodedStringValue subject = sendReq.getSubject(); - if (subject != null) { - values.put(Mms.SUBJECT, toIsoString(subject.getTextString())); - values.put(Mms.SUBJECT_CHARSET, subject.getCharacterSet()); - } else { - values.put(Mms.SUBJECT, ""); - } - - long messageSize = sendReq.getMessageSize(); - if (messageSize > 0) { - values.put(Mms.MESSAGE_SIZE, messageSize); - } - - PduHeaders headers = sendReq.getPduHeaders(); - HashSet<String> recipients = new HashSet<String>(); - for (int addrType : ADDRESS_FIELDS) { - EncodedStringValue[] array = null; - if (addrType == PduHeaders.FROM) { - EncodedStringValue v = headers.getEncodedStringValue(addrType); - if (v != null) { - array = new EncodedStringValue[1]; - array[0] = v; - } - } else { - array = headers.getEncodedStringValues(addrType); - } - - if (array != null) { - long msgId = ContentUris.parseId(uri); - updateAddress(msgId, addrType, array); - if (addrType == PduHeaders.TO) { - for (EncodedStringValue v : array) { - if (v != null) { - recipients.add(v.getString()); - } - } - } - } - } - if (!recipients.isEmpty()) { - long threadId = Threads.getOrCreateThreadId(mContext, recipients); - values.put(Mms.THREAD_ID, threadId); - } - - SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null); - } - - private void updatePart(Uri uri, PduPart part, HashMap<Uri, InputStream> preOpenedFiles) - throws MmsException { - ContentValues values = new ContentValues(7); - - int charset = part.getCharset(); - if (charset != 0 ) { - values.put(Part.CHARSET, charset); - } - - String contentType = null; - if (part.getContentType() != null) { - contentType = toIsoString(part.getContentType()); - values.put(Part.CONTENT_TYPE, contentType); - } else { - throw new MmsException("MIME type of the part must be set."); - } - - if (part.getFilename() != null) { - String fileName = new String(part.getFilename()); - values.put(Part.FILENAME, fileName); - } - - if (part.getName() != null) { - String name = new String(part.getName()); - values.put(Part.NAME, name); - } - - Object value = null; - if (part.getContentDisposition() != null) { - value = toIsoString(part.getContentDisposition()); - values.put(Part.CONTENT_DISPOSITION, (String) value); - } - - if (part.getContentId() != null) { - value = toIsoString(part.getContentId()); - values.put(Part.CONTENT_ID, (String) value); - } - - if (part.getContentLocation() != null) { - value = toIsoString(part.getContentLocation()); - values.put(Part.CONTENT_LOCATION, (String) value); - } - - SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null); - - // Only update the data when: - // 1. New binary data supplied or - // 2. The Uri of the part is different from the current one. - if ((part.getData() != null) - || (!uri.equals(part.getDataUri()))) { - persistData(part, uri, contentType, preOpenedFiles); - } - } - - /** - * Update all parts of a PDU. - * - * @param uri The PDU which need to be updated. - * @param body New message body of the PDU. - * @param preOpenedFiles if not null, a map of preopened InputStreams for the parts. - * @throws MmsException Bad URI or updating failed. - */ - @UnsupportedAppUsage - public void updateParts(Uri uri, PduBody body, HashMap<Uri, InputStream> preOpenedFiles) - throws MmsException { - try { - PduCacheEntry cacheEntry; - synchronized(PDU_CACHE_INSTANCE) { - if (PDU_CACHE_INSTANCE.isUpdating(uri)) { - if (LOCAL_LOGV) { - Log.v(TAG, "updateParts: " + uri + " blocked by isUpdating()"); - } - try { - PDU_CACHE_INSTANCE.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "updateParts: ", e); - } - cacheEntry = PDU_CACHE_INSTANCE.get(uri); - if (cacheEntry != null) { - ((MultimediaMessagePdu) cacheEntry.getPdu()).setBody(body); - } - } - // Tell the cache to indicate to other callers that this item - // is currently being updated. - PDU_CACHE_INSTANCE.setUpdating(uri, true); - } - - ArrayList<PduPart> toBeCreated = new ArrayList<PduPart>(); - HashMap<Uri, PduPart> toBeUpdated = new HashMap<Uri, PduPart>(); - - int partsNum = body.getPartsNum(); - StringBuilder filter = new StringBuilder().append('('); - for (int i = 0; i < partsNum; i++) { - PduPart part = body.getPart(i); - Uri partUri = part.getDataUri(); - if ((partUri == null) || TextUtils.isEmpty(partUri.getAuthority()) - || !partUri.getAuthority().startsWith("mms")) { - toBeCreated.add(part); - } else { - toBeUpdated.put(partUri, part); - - // Don't use 'i > 0' to determine whether we should append - // 'AND' since 'i = 0' may be skipped in another branch. - if (filter.length() > 1) { - filter.append(" AND "); - } - - filter.append(Part._ID); - filter.append("!="); - DatabaseUtils.appendEscapedSQLString(filter, partUri.getLastPathSegment()); - } - } - filter.append(')'); - - long msgId = ContentUris.parseId(uri); - - // Remove the parts which doesn't exist anymore. - SqliteWrapper.delete(mContext, mContentResolver, - Uri.parse(Mms.CONTENT_URI + "/" + msgId + "/part"), - filter.length() > 2 ? filter.toString() : null, null); - - // Create new parts which didn't exist before. - for (PduPart part : toBeCreated) { - persistPart(part, msgId, preOpenedFiles); - } - - // Update the modified parts. - for (Map.Entry<Uri, PduPart> e : toBeUpdated.entrySet()) { - updatePart(e.getKey(), e.getValue(), preOpenedFiles); - } - } finally { - synchronized(PDU_CACHE_INSTANCE) { - PDU_CACHE_INSTANCE.setUpdating(uri, false); - PDU_CACHE_INSTANCE.notifyAll(); - } - } - } - - /** - * Persist a PDU object to specific location in the storage. - * - * @param pdu The PDU object to be stored. - * @param uri Where to store the given PDU object. - * @param createThreadId if true, this function may create a thread id for the recipients - * @param groupMmsEnabled if true, all of the recipients addressed in the PDU will be used - * to create the associated thread. When false, only the sender will be used in finding or - * creating the appropriate thread or conversation. - * @param preOpenedFiles if not null, a map of preopened InputStreams for the parts. - * @return A Uri which can be used to access the stored PDU. - */ - - @UnsupportedAppUsage - public Uri persist(GenericPdu pdu, Uri uri, boolean createThreadId, boolean groupMmsEnabled, - HashMap<Uri, InputStream> preOpenedFiles) - throws MmsException { - if (uri == null) { - throw new MmsException("Uri may not be null."); - } - long msgId = -1; - try { - msgId = ContentUris.parseId(uri); - } catch (NumberFormatException e) { - // the uri ends with "inbox" or something else like that - } - boolean existingUri = msgId != -1; - - if (!existingUri && MESSAGE_BOX_MAP.get(uri) == null) { - throw new MmsException( - "Bad destination, must be one of " - + "content://mms/inbox, content://mms/sent, " - + "content://mms/drafts, content://mms/outbox, " - + "content://mms/temp."); - } - synchronized(PDU_CACHE_INSTANCE) { - // If the cache item is getting updated, wait until it's done updating before - // purging it. - if (PDU_CACHE_INSTANCE.isUpdating(uri)) { - if (LOCAL_LOGV) { - Log.v(TAG, "persist: " + uri + " blocked by isUpdating()"); - } - try { - PDU_CACHE_INSTANCE.wait(); - } catch (InterruptedException e) { - Log.e(TAG, "persist1: ", e); - } - } - } - PDU_CACHE_INSTANCE.purge(uri); - - PduHeaders header = pdu.getPduHeaders(); - PduBody body = null; - ContentValues values = new ContentValues(); - Set<Entry<Integer, String>> set; - - set = ENCODED_STRING_COLUMN_NAME_MAP.entrySet(); - for (Entry<Integer, String> e : set) { - int field = e.getKey(); - EncodedStringValue encodedString = header.getEncodedStringValue(field); - if (encodedString != null) { - String charsetColumn = CHARSET_COLUMN_NAME_MAP.get(field); - values.put(e.getValue(), toIsoString(encodedString.getTextString())); - values.put(charsetColumn, encodedString.getCharacterSet()); - } - } - - set = TEXT_STRING_COLUMN_NAME_MAP.entrySet(); - for (Entry<Integer, String> e : set){ - byte[] text = header.getTextString(e.getKey()); - if (text != null) { - values.put(e.getValue(), toIsoString(text)); - } - } - - set = OCTET_COLUMN_NAME_MAP.entrySet(); - for (Entry<Integer, String> e : set){ - int b = header.getOctet(e.getKey()); - if (b != 0) { - values.put(e.getValue(), b); - } - } - - set = LONG_COLUMN_NAME_MAP.entrySet(); - for (Entry<Integer, String> e : set){ - long l = header.getLongInteger(e.getKey()); - if (l != -1L) { - values.put(e.getValue(), l); - } - } - - HashMap<Integer, EncodedStringValue[]> addressMap = - new HashMap<Integer, EncodedStringValue[]>(ADDRESS_FIELDS.length); - // Save address information. - for (int addrType : ADDRESS_FIELDS) { - EncodedStringValue[] array = null; - if (addrType == PduHeaders.FROM) { - EncodedStringValue v = header.getEncodedStringValue(addrType); - if (v != null) { - array = new EncodedStringValue[1]; - array[0] = v; - } - } else { - array = header.getEncodedStringValues(addrType); - } - addressMap.put(addrType, array); - } - - HashSet<String> recipients = new HashSet<String>(); - int msgType = pdu.getMessageType(); - // Here we only allocate thread ID for M-Notification.ind, - // M-Retrieve.conf and M-Send.req. - // Some of other PDU types may be allocated a thread ID outside - // this scope. - if ((msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) - || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) - || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) { - switch (msgType) { - case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: - case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - loadRecipients(PduHeaders.FROM, recipients, addressMap, false); - - // For received messages when group MMS is enabled, we want to associate this - // message with the thread composed of all the recipients -- all but our own - // number, that is. This includes the person who sent the - // message or the FROM field (above) in addition to the other people the message - // was addressed to or the TO field. Our own number is in that TO field and - // we have to ignore it in loadRecipients. - if (groupMmsEnabled) { - loadRecipients(PduHeaders.TO, recipients, addressMap, true); - - // Also load any numbers in the CC field to address group messaging - // compatibility issues with devices that place numbers in this field - // for group messages. - loadRecipients(PduHeaders.CC, recipients, addressMap, true); - } - break; - case PduHeaders.MESSAGE_TYPE_SEND_REQ: - loadRecipients(PduHeaders.TO, recipients, addressMap, false); - break; - } - long threadId = 0; - if (createThreadId && !recipients.isEmpty()) { - // Given all the recipients associated with this message, find (or create) the - // correct thread. - threadId = Threads.getOrCreateThreadId(mContext, recipients); - } - values.put(Mms.THREAD_ID, threadId); - } - - // Save parts first to avoid inconsistent message is loaded - // while saving the parts. - long dummyId = System.currentTimeMillis(); // Dummy ID of the msg. - - // Figure out if this PDU is a text-only message - boolean textOnly = true; - - // Sum up the total message size - int messageSize = 0; - - // Get body if the PDU is a RetrieveConf or SendReq. - if (pdu instanceof MultimediaMessagePdu) { - body = ((MultimediaMessagePdu) pdu).getBody(); - // Start saving parts if necessary. - if (body != null) { - int partsNum = body.getPartsNum(); - if (partsNum > 2) { - // For a text-only message there will be two parts: 1-the SMIL, 2-the text. - // Down a few lines below we're checking to make sure we've only got SMIL or - // text. We also have to check then we don't have more than two parts. - // Otherwise, a slideshow with two text slides would be marked as textOnly. - textOnly = false; - } - for (int i = 0; i < partsNum; i++) { - PduPart part = body.getPart(i); - messageSize += part.getDataLength(); - persistPart(part, dummyId, preOpenedFiles); - - // If we've got anything besides text/plain or SMIL part, then we've got - // an mms message with some other type of attachment. - String contentType = getPartContentType(part); - if (contentType != null && !ContentType.APP_SMIL.equals(contentType) - && !ContentType.TEXT_PLAIN.equals(contentType)) { - textOnly = false; - } - } - } - } - // Record whether this mms message is a simple plain text or not. This is a hint for the - // UI. - values.put(Mms.TEXT_ONLY, textOnly ? 1 : 0); - // The message-size might already have been inserted when parsing the - // PDU header. If not, then we insert the message size as well. - if (values.getAsInteger(Mms.MESSAGE_SIZE) == null) { - values.put(Mms.MESSAGE_SIZE, messageSize); - } - - Uri res = null; - if (existingUri) { - res = uri; - SqliteWrapper.update(mContext, mContentResolver, res, values, null, null); - } else { - res = SqliteWrapper.insert(mContext, mContentResolver, uri, values); - if (res == null) { - throw new MmsException("persist() failed: return null."); - } - // Get the real ID of the PDU and update all parts which were - // saved with the dummy ID. - msgId = ContentUris.parseId(res); - } - - values = new ContentValues(1); - values.put(Part.MSG_ID, msgId); - SqliteWrapper.update(mContext, mContentResolver, - Uri.parse("content://mms/" + dummyId + "/part"), - values, null, null); - // We should return the longest URI of the persisted PDU, for - // example, if input URI is "content://mms/inbox" and the _ID of - // persisted PDU is '8', we should return "content://mms/inbox/8" - // instead of "content://mms/8". - // FIXME: Should the MmsProvider be responsible for this??? - if (!existingUri) { - res = Uri.parse(uri + "/" + msgId); - } - - // Save address information. - for (int addrType : ADDRESS_FIELDS) { - EncodedStringValue[] array = addressMap.get(addrType); - if (array != null) { - persistAddress(msgId, addrType, array); - } - } - - return res; - } - - /** - * For a given address type, extract the recipients from the headers. - * - * @param addressType can be PduHeaders.FROM, PduHeaders.TO or PduHeaders.CC - * @param recipients a HashSet that is loaded with the recipients from the FROM, TO or CC headers - * @param addressMap a HashMap of the addresses from the ADDRESS_FIELDS header - * @param excludeMyNumber if true, the number of this phone will be excluded from recipients - */ - @UnsupportedAppUsage - private void loadRecipients(int addressType, HashSet<String> recipients, - HashMap<Integer, EncodedStringValue[]> addressMap, boolean excludeMyNumber) { - EncodedStringValue[] array = addressMap.get(addressType); - if (array == null) { - return; - } - // If the TO recipients is only a single address, then we can skip loadRecipients when - // we're excluding our own number because we know that address is our own. - if (excludeMyNumber && array.length == 1) { - return; - } - final SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext); - final Set<String> myPhoneNumbers = new HashSet<String>(); - if (excludeMyNumber) { - // Build a list of my phone numbers from the various sims. - for (int subid : subscriptionManager.getActiveSubscriptionIdList()) { - final String myNumber = mTelephonyManager.getLine1Number(subid); - if (myNumber != null) { - myPhoneNumbers.add(myNumber); - } - } - } - - for (EncodedStringValue v : array) { - if (v != null) { - final String number = v.getString(); - if (excludeMyNumber) { - for (final String myNumber : myPhoneNumbers) { - if (!PhoneNumberUtils.compare(number, myNumber) - && !recipients.contains(number)) { - // Only add numbers which aren't my own number. - recipients.add(number); - break; - } - } - } else if (!recipients.contains(number)){ - recipients.add(number); - } - } - } - } - - /** - * Move a PDU object from one location to another. - * - * @param from Specify the PDU object to be moved. - * @param to The destination location, should be one of the following: - * "content://mms/inbox", "content://mms/sent", - * "content://mms/drafts", "content://mms/outbox", - * "content://mms/trash". - * @return New Uri of the moved PDU. - * @throws MmsException Error occurred while moving the message. - */ - @UnsupportedAppUsage - public Uri move(Uri from, Uri to) throws MmsException { - // Check whether the 'msgId' has been assigned a valid value. - long msgId = ContentUris.parseId(from); - if (msgId == -1L) { - throw new MmsException("Error! ID of the message: -1."); - } - - // Get corresponding int value of destination box. - Integer msgBox = MESSAGE_BOX_MAP.get(to); - if (msgBox == null) { - throw new MmsException( - "Bad destination, must be one of " - + "content://mms/inbox, content://mms/sent, " - + "content://mms/drafts, content://mms/outbox, " - + "content://mms/temp."); - } - - ContentValues values = new ContentValues(1); - values.put(Mms.MESSAGE_BOX, msgBox); - SqliteWrapper.update(mContext, mContentResolver, from, values, null, null); - return ContentUris.withAppendedId(to, msgId); - } - - /** - * Wrap a byte[] into a String. - */ - @UnsupportedAppUsage - public static String toIsoString(byte[] bytes) { - try { - return new String(bytes, CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException e) { - // Impossible to reach here! - Log.e(TAG, "ISO_8859_1 must be supported!", e); - return ""; - } - } - - /** - * Unpack a given String into a byte[]. - */ - @UnsupportedAppUsage - public static byte[] getBytes(String data) { - try { - return data.getBytes(CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException e) { - // Impossible to reach here! - Log.e(TAG, "ISO_8859_1 must be supported!", e); - return new byte[0]; - } - } - - /** - * Remove all objects in the temporary path. - */ - public void release() { - Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI); - SqliteWrapper.delete(mContext, mContentResolver, uri, null, null); - } - - /** - * Find all messages to be sent or downloaded before certain time. - */ - @UnsupportedAppUsage - public Cursor getPendingMessages(long dueTime) { - Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon(); - uriBuilder.appendQueryParameter("protocol", "mms"); - - String selection = PendingMessages.ERROR_TYPE + " < ?" - + " AND " + PendingMessages.DUE_TIME + " <= ?"; - - String[] selectionArgs = new String[] { - String.valueOf(MmsSms.ERR_TYPE_GENERIC_PERMANENT), - String.valueOf(dueTime) - }; - - return SqliteWrapper.query(mContext, mContentResolver, - uriBuilder.build(), null, selection, selectionArgs, - PendingMessages.DUE_TIME); - } -} diff --git a/telephony/java/com/google/android/mms/pdu/QuotedPrintable.java b/telephony/java/com/google/android/mms/pdu/QuotedPrintable.java deleted file mode 100644 index 9d6535c72e90..000000000000 --- a/telephony/java/com/google/android/mms/pdu/QuotedPrintable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.io.ByteArrayOutputStream; - -public class QuotedPrintable { - private static byte ESCAPE_CHAR = '='; - - /** - * Decodes an array quoted-printable characters into an array of original bytes. - * Escaped characters are converted back to their original representation. - * - * <p> - * This function implements a subset of - * quoted-printable encoding specification (rule #1 and rule #2) - * as defined in RFC 1521. - * </p> - * - * @param bytes array of quoted-printable characters - * @return array of original bytes, - * null if quoted-printable decoding is unsuccessful. - */ - @UnsupportedAppUsage - public static final byte[] decodeQuotedPrintable(byte[] bytes) { - if (bytes == null) { - return null; - } - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - for (int i = 0; i < bytes.length; i++) { - int b = bytes[i]; - if (b == ESCAPE_CHAR) { - try { - if('\r' == (char)bytes[i + 1] && - '\n' == (char)bytes[i + 2]) { - i += 2; - continue; - } - int u = Character.digit((char) bytes[++i], 16); - int l = Character.digit((char) bytes[++i], 16); - if (u == -1 || l == -1) { - return null; - } - buffer.write((char) ((u << 4) + l)); - } catch (ArrayIndexOutOfBoundsException e) { - return null; - } - } else { - buffer.write(b); - } - } - return buffer.toByteArray(); - } -} diff --git a/telephony/java/com/google/android/mms/pdu/ReadOrigInd.java b/telephony/java/com/google/android/mms/pdu/ReadOrigInd.java deleted file mode 100644 index e38c62dde622..000000000000 --- a/telephony/java/com/google/android/mms/pdu/ReadOrigInd.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -public class ReadOrigInd extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - public ReadOrigInd() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_READ_ORIG_IND); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - @UnsupportedAppUsage - ReadOrigInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-MMS-Read-status value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getReadStatus() { - return mPduHeaders.getOctet(PduHeaders.READ_STATUS); - } - - /** - * Set X-MMS-Read-status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_STATUS); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - */ -} diff --git a/telephony/java/com/google/android/mms/pdu/ReadRecInd.java b/telephony/java/com/google/android/mms/pdu/ReadRecInd.java deleted file mode 100644 index 9696bc259d00..000000000000 --- a/telephony/java/com/google/android/mms/pdu/ReadRecInd.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -public class ReadRecInd extends GenericPdu { - /** - * Constructor, used when composing a M-ReadRec.ind pdu. - * - * @param from the from value - * @param messageId the message ID value - * @param mmsVersion current viersion of mms - * @param readStatus the read status value - * @param to the to value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if messageId or to is null. - */ - @UnsupportedAppUsage - public ReadRecInd(EncodedStringValue from, - byte[] messageId, - int mmsVersion, - int readStatus, - EncodedStringValue[] to) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_READ_REC_IND); - setFrom(from); - setMessageId(messageId); - setMmsVersion(mmsVersion); - setTo(to); - setReadStatus(readStatus); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - @UnsupportedAppUsage - ReadRecInd(PduHeaders headers) { - super(headers); - } - - /** - * Get Date value. - * - * @return the value - */ - public long getDate() { - return mPduHeaders.getLongInteger(PduHeaders.DATE); - } - - /** - * Set Date value. - * - * @param value the value - */ - @UnsupportedAppUsage - public void setDate(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.DATE); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get To value. - * - * @return the value - */ - public EncodedStringValue[] getTo() { - return mPduHeaders.getEncodedStringValues(PduHeaders.TO); - } - - /** - * Set To value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /** - * Get X-MMS-Read-status value. - * - * @return the value - */ - public int getReadStatus() { - return mPduHeaders.getOctet(PduHeaders.READ_STATUS); - } - - /** - * Set X-MMS-Read-status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setReadStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_STATUS); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - */ -} diff --git a/telephony/java/com/google/android/mms/pdu/RetrieveConf.java b/telephony/java/com/google/android/mms/pdu/RetrieveConf.java deleted file mode 100644 index 03755af4189c..000000000000 --- a/telephony/java/com/google/android/mms/pdu/RetrieveConf.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -/** - * M-Retrieve.conf Pdu. - */ -public class RetrieveConf extends MultimediaMessagePdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - @UnsupportedAppUsage - public RetrieveConf() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - RetrieveConf(PduHeaders headers) { - super(headers); - } - - /** - * Constructor with given headers and body - * - * @param headers Headers for this PDU. - * @param body Body of this PDu. - */ - @UnsupportedAppUsage - RetrieveConf(PduHeaders headers, PduBody body) { - super(headers, body); - } - - /** - * Get CC value. - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue[] getCc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.CC); - } - - /** - * Add a "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void addCc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC); - } - - /** - * Get Content-type value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getContentType() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE); - } - - /** - * Set Content-type value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setContentType(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE); - } - - /** - * Get X-Mms-Delivery-Report value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - @UnsupportedAppUsage - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /** - * Get From value. - * From-value = Value-length - * (Address-present-token Encoded-string-value | Insert-address-token) - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue getFrom() { - return mPduHeaders.getEncodedStringValue(PduHeaders.FROM); - } - - /** - * Set From value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setFrom(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-Mms-Read-Report value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getReadReport() { - return mPduHeaders.getOctet(PduHeaders.READ_REPORT); - } - - /** - * Set X-Mms-Read-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - @UnsupportedAppUsage - public void setReadReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_REPORT); - } - - /** - * Get X-Mms-Retrieve-Status value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getRetrieveStatus() { - return mPduHeaders.getOctet(PduHeaders.RETRIEVE_STATUS); - } - - /** - * Set X-Mms-Retrieve-Status value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - @UnsupportedAppUsage - public void setRetrieveStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.RETRIEVE_STATUS); - } - - /** - * Get X-Mms-Retrieve-Text value. - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue getRetrieveText() { - return mPduHeaders.getEncodedStringValue(PduHeaders.RETRIEVE_TEXT); - } - - /** - * Set X-Mms-Retrieve-Text value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setRetrieveText(EncodedStringValue value) { - mPduHeaders.setEncodedStringValue(value, PduHeaders.RETRIEVE_TEXT); - } - - /** - * Get X-Mms-Transaction-Id. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getContentClass() {return 0x00;} - * public void setApplicId(byte value) {} - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public byte getDistributionIndicator() {return 0x00;} - * public void setDistributionIndicator(byte value) {} - * - * public PreviouslySentByValue getPreviouslySentBy() {return null;} - * public void setPreviouslySentBy(PreviouslySentByValue value) {} - * - * public PreviouslySentDateValue getPreviouslySentDate() {} - * public void setPreviouslySentDate(PreviouslySentDateValue value) {} - * - * public MmFlagsValue getMmFlags() {return null;} - * public void setMmFlags(MmFlagsValue value) {} - * - * public MmStateValue getMmState() {return null;} - * public void getMmState(MmStateValue value) {} - * - * public byte[] getReplaceId() {return 0x00;} - * public void setReplaceId(byte[] value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - */ -} diff --git a/telephony/java/com/google/android/mms/pdu/SendConf.java b/telephony/java/com/google/android/mms/pdu/SendConf.java deleted file mode 100644 index b85982791ada..000000000000 --- a/telephony/java/com/google/android/mms/pdu/SendConf.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2007 Esmertec AG. - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -public class SendConf extends GenericPdu { - /** - * Empty constructor. - * Since the Pdu corresponding to this class is constructed - * by the Proxy-Relay server, this class is only instantiated - * by the Pdu Parser. - * - * @throws InvalidHeaderValueException if error occurs. - */ - @UnsupportedAppUsage - public SendConf() throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_CONF); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - @UnsupportedAppUsage - SendConf(PduHeaders headers) { - super(headers); - } - - /** - * Get Message-ID value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getMessageId() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID); - } - - /** - * Set Message-ID value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setMessageId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID); - } - - /** - * Get X-Mms-Response-Status. - * - * @return the value - */ - @UnsupportedAppUsage - public int getResponseStatus() { - return mPduHeaders.getOctet(PduHeaders.RESPONSE_STATUS); - } - - /** - * Set X-Mms-Response-Status. - * - * @param value the values - * @throws InvalidHeaderValueException if the value is invalid. - */ - public void setResponseStatus(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.RESPONSE_STATUS); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - @UnsupportedAppUsage - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte[] getContentLocation() {return null;} - * public void setContentLocation(byte[] value) {} - * - * public EncodedStringValue getResponseText() {return null;} - * public void setResponseText(EncodedStringValue value) {} - * - * public byte getStoreStatus() {return 0x00;} - * public void setStoreStatus(byte value) {} - * - * public byte[] getStoreStatusText() {return null;} - * public void setStoreStatusText(byte[] value) {} - */ -} diff --git a/telephony/java/com/google/android/mms/pdu/SendReq.java b/telephony/java/com/google/android/mms/pdu/SendReq.java deleted file mode 100644 index c1b7f934c0f7..000000000000 --- a/telephony/java/com/google/android/mms/pdu/SendReq.java +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright (C) 2007-2008 Esmertec AG. - * Copyright (C) 2007-2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.pdu; - -import android.util.Log; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.InvalidHeaderValueException; - -public class SendReq extends MultimediaMessagePdu { - private static final String TAG = "SendReq"; - - @UnsupportedAppUsage - public SendReq() { - super(); - - try { - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ); - setMmsVersion(PduHeaders.CURRENT_MMS_VERSION); - // FIXME: Content-type must be decided according to whether - // SMIL part present. - setContentType("application/vnd.wap.multipart.related".getBytes()); - setFrom(new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes())); - setTransactionId(generateTransactionId()); - } catch (InvalidHeaderValueException e) { - // Impossible to reach here since all headers we set above are valid. - Log.e(TAG, "Unexpected InvalidHeaderValueException.", e); - throw new RuntimeException(e); - } - } - - private byte[] generateTransactionId() { - String transactionId = "T" + Long.toHexString(System.currentTimeMillis()); - return transactionId.getBytes(); - } - - /** - * Constructor, used when composing a M-Send.req pdu. - * - * @param contentType the content type value - * @param from the from value - * @param mmsVersion current viersion of mms - * @param transactionId the transaction-id value - * @throws InvalidHeaderValueException if parameters are invalid. - * NullPointerException if contentType, form or transactionId is null. - */ - public SendReq(byte[] contentType, - EncodedStringValue from, - int mmsVersion, - byte[] transactionId) throws InvalidHeaderValueException { - super(); - setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ); - setContentType(contentType); - setFrom(from); - setMmsVersion(mmsVersion); - setTransactionId(transactionId); - } - - /** - * Constructor with given headers. - * - * @param headers Headers for this PDU. - */ - SendReq(PduHeaders headers) { - super(headers); - } - - /** - * Constructor with given headers and body - * - * @param headers Headers for this PDU. - * @param body Body of this PDu. - */ - @UnsupportedAppUsage - SendReq(PduHeaders headers, PduBody body) { - super(headers, body); - } - - /** - * Get Bcc value. - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue[] getBcc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.BCC); - } - - /** - * Add a "BCC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void addBcc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.BCC); - } - - /** - * Set "BCC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setBcc(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.BCC); - } - - /** - * Get CC value. - * - * @return the value - */ - @UnsupportedAppUsage - public EncodedStringValue[] getCc() { - return mPduHeaders.getEncodedStringValues(PduHeaders.CC); - } - - /** - * Add a "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void addCc(EncodedStringValue value) { - mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC); - } - - /** - * Set "CC" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setCc(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.CC); - } - - /** - * Get Content-type value. - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getContentType() { - return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE); - } - - /** - * Set Content-type value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setContentType(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE); - } - - /** - * Get X-Mms-Delivery-Report value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getDeliveryReport() { - return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT); - } - - /** - * Set X-Mms-Delivery-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - @UnsupportedAppUsage - public void setDeliveryReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT); - } - - /** - * Get X-Mms-Expiry value. - * - * Expiry-value = Value-length - * (Absolute-token Date-value | Relative-token Delta-seconds-value) - * - * @return the value - */ - @UnsupportedAppUsage - public long getExpiry() { - return mPduHeaders.getLongInteger(PduHeaders.EXPIRY); - } - - /** - * Set X-Mms-Expiry value. - * - * @param value the value - */ - @UnsupportedAppUsage - public void setExpiry(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY); - } - - /** - * Get X-Mms-MessageSize value. - * - * Expiry-value = size of message - * - * @return the value - */ - @UnsupportedAppUsage - public long getMessageSize() { - return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE); - } - - /** - * Set X-Mms-MessageSize value. - * - * @param value the value - */ - @UnsupportedAppUsage - public void setMessageSize(long value) { - mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE); - } - - /** - * Get X-Mms-Message-Class value. - * Message-class-value = Class-identifier | Token-text - * Class-identifier = Personal | Advertisement | Informational | Auto - * - * @return the value - */ - @UnsupportedAppUsage - public byte[] getMessageClass() { - return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS); - } - - /** - * Set X-Mms-Message-Class value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setMessageClass(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS); - } - - /** - * Get X-Mms-Read-Report value. - * - * @return the value - */ - @UnsupportedAppUsage - public int getReadReport() { - return mPduHeaders.getOctet(PduHeaders.READ_REPORT); - } - - /** - * Set X-Mms-Read-Report value. - * - * @param value the value - * @throws InvalidHeaderValueException if the value is invalid. - */ - @UnsupportedAppUsage - public void setReadReport(int value) throws InvalidHeaderValueException { - mPduHeaders.setOctet(value, PduHeaders.READ_REPORT); - } - - /** - * Set "To" value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setTo(EncodedStringValue[] value) { - mPduHeaders.setEncodedStringValues(value, PduHeaders.TO); - } - - /** - * Get X-Mms-Transaction-Id field value. - * - * @return the X-Mms-Report-Allowed value - */ - @UnsupportedAppUsage - public byte[] getTransactionId() { - return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID); - } - - /** - * Set X-Mms-Transaction-Id field value. - * - * @param value the value - * @throws NullPointerException if the value is null. - */ - @UnsupportedAppUsage - public void setTransactionId(byte[] value) { - mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID); - } - - /* - * Optional, not supported header fields: - * - * public byte getAdaptationAllowed() {return 0}; - * public void setAdaptationAllowed(btye value) {}; - * - * public byte[] getApplicId() {return null;} - * public void setApplicId(byte[] value) {} - * - * public byte[] getAuxApplicId() {return null;} - * public void getAuxApplicId(byte[] value) {} - * - * public byte getContentClass() {return 0x00;} - * public void setApplicId(byte value) {} - * - * public long getDeliveryTime() {return 0}; - * public void setDeliveryTime(long value) {}; - * - * public byte getDrmContent() {return 0x00;} - * public void setDrmContent(byte value) {} - * - * public MmFlagsValue getMmFlags() {return null;} - * public void setMmFlags(MmFlagsValue value) {} - * - * public MmStateValue getMmState() {return null;} - * public void getMmState(MmStateValue value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getReplyCharging() {return 0x00;} - * public void setReplyCharging(byte value) {} - * - * public byte getReplyChargingDeadline() {return 0x00;} - * public void setReplyChargingDeadline(byte value) {} - * - * public byte[] getReplyChargingId() {return 0x00;} - * public void setReplyChargingId(byte[] value) {} - * - * public long getReplyChargingSize() {return 0;} - * public void setReplyChargingSize(long value) {} - * - * public byte[] getReplyApplicId() {return 0x00;} - * public void setReplyApplicId(byte[] value) {} - * - * public byte getStore() {return 0x00;} - * public void setStore(byte value) {} - */ -} diff --git a/telephony/java/com/google/android/mms/pdu/package.html b/telephony/java/com/google/android/mms/pdu/package.html deleted file mode 100755 index c9f96a66ab3b..000000000000 --- a/telephony/java/com/google/android/mms/pdu/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> - -{@hide} - -</body> diff --git a/telephony/java/com/google/android/mms/util/AbstractCache.java b/telephony/java/com/google/android/mms/util/AbstractCache.java deleted file mode 100644 index ab5d48a4ce3d..000000000000 --- a/telephony/java/com/google/android/mms/util/AbstractCache.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.util; - -import android.util.Log; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.util.HashMap; - -public abstract class AbstractCache<K, V> { - private static final String TAG = "AbstractCache"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - private static final int MAX_CACHED_ITEMS = 500; - - private final HashMap<K, CacheEntry<V>> mCacheMap; - - @UnsupportedAppUsage - protected AbstractCache() { - mCacheMap = new HashMap<K, CacheEntry<V>>(); - } - - @UnsupportedAppUsage - public boolean put(K key, V value) { - if (LOCAL_LOGV) { - Log.v(TAG, "Trying to put " + key + " into cache."); - } - - if (mCacheMap.size() >= MAX_CACHED_ITEMS) { - // TODO Should remove the oldest or least hit cached entry - // and then cache the new one. - if (LOCAL_LOGV) { - Log.v(TAG, "Failed! size limitation reached."); - } - return false; - } - - if (key != null) { - CacheEntry<V> cacheEntry = new CacheEntry<V>(); - cacheEntry.value = value; - mCacheMap.put(key, cacheEntry); - - if (LOCAL_LOGV) { - Log.v(TAG, key + " cached, " + mCacheMap.size() + " items total."); - } - return true; - } - return false; - } - - @UnsupportedAppUsage - public V get(K key) { - if (LOCAL_LOGV) { - Log.v(TAG, "Trying to get " + key + " from cache."); - } - - if (key != null) { - CacheEntry<V> cacheEntry = mCacheMap.get(key); - if (cacheEntry != null) { - cacheEntry.hit++; - if (LOCAL_LOGV) { - Log.v(TAG, key + " hit " + cacheEntry.hit + " times."); - } - return cacheEntry.value; - } - } - return null; - } - - @UnsupportedAppUsage - public V purge(K key) { - if (LOCAL_LOGV) { - Log.v(TAG, "Trying to purge " + key); - } - - CacheEntry<V> v = mCacheMap.remove(key); - - if (LOCAL_LOGV) { - Log.v(TAG, mCacheMap.size() + " items cached."); - } - - return v != null ? v.value : null; - } - - @UnsupportedAppUsage - public void purgeAll() { - if (LOCAL_LOGV) { - Log.v(TAG, "Purging cache, " + mCacheMap.size() - + " items dropped."); - } - mCacheMap.clear(); - } - - public int size() { - return mCacheMap.size(); - } - - private static class CacheEntry<V> { - int hit; - V value; - } -} diff --git a/telephony/java/com/google/android/mms/util/DownloadDrmHelper.java b/telephony/java/com/google/android/mms/util/DownloadDrmHelper.java deleted file mode 100644 index 118de465a518..000000000000 --- a/telephony/java/com/google/android/mms/util/DownloadDrmHelper.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.google.android.mms.util; - -import android.content.Context; -import android.drm.DrmManagerClient; -import android.util.Log; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -public class DownloadDrmHelper { - private static final String TAG = "DownloadDrmHelper"; - - /** The MIME type of special DRM files */ - public static final String MIMETYPE_DRM_MESSAGE = "application/vnd.oma.drm.message"; - - /** The extensions of special DRM files */ - public static final String EXTENSION_DRM_MESSAGE = ".dm"; - - public static final String EXTENSION_INTERNAL_FWDL = ".fl"; - - /** - * Checks if the Media Type is a DRM Media Type - * - * @param drmManagerClient A DrmManagerClient - * @param mimetype Media Type to check - * @return True if the Media Type is DRM else false - */ - public static boolean isDrmMimeType(Context context, String mimetype) { - boolean result = false; - if (context != null) { - try { - DrmManagerClient drmClient = new DrmManagerClient(context); - if (drmClient != null && mimetype != null && mimetype.length() > 0) { - result = drmClient.canHandle("", mimetype); - } - } catch (IllegalArgumentException e) { - Log.w(TAG, - "DrmManagerClient instance could not be created, context is Illegal."); - } catch (IllegalStateException e) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); - } - } - return result; - } - - /** - * Checks if the Media Type needs to be DRM converted - * - * @param mimetype Media type of the content - * @return True if convert is needed else false - */ - @UnsupportedAppUsage - public static boolean isDrmConvertNeeded(String mimetype) { - return MIMETYPE_DRM_MESSAGE.equals(mimetype); - } - - /** - * Modifies the file extension for a DRM Forward Lock file NOTE: This - * function shouldn't be called if the file shouldn't be DRM converted - */ - @UnsupportedAppUsage - public static String modifyDrmFwLockFileExtension(String filename) { - if (filename != null) { - int extensionIndex; - extensionIndex = filename.lastIndexOf("."); - if (extensionIndex != -1) { - filename = filename.substring(0, extensionIndex); - } - filename = filename.concat(EXTENSION_INTERNAL_FWDL); - } - return filename; - } - - /** - * Gets the original mime type of DRM protected content. - * - * @param context The context - * @param path Path to the file - * @param containingMime The current mime type of the file i.e. the - * containing mime type - * @return The original mime type of the file if DRM protected else the - * currentMime - */ - public static String getOriginalMimeType(Context context, String path, String containingMime) { - String result = containingMime; - DrmManagerClient drmClient = new DrmManagerClient(context); - try { - if (drmClient.canHandle(path, null)) { - result = drmClient.getOriginalMimeType(path); - } - } catch (IllegalArgumentException ex) { - Log.w(TAG, - "Can't get original mime type since path is null or empty string."); - } catch (IllegalStateException ex) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); - } - return result; - } -} diff --git a/telephony/java/com/google/android/mms/util/DrmConvertSession.java b/telephony/java/com/google/android/mms/util/DrmConvertSession.java deleted file mode 100644 index 0e8ec91f4ef6..000000000000 --- a/telephony/java/com/google/android/mms/util/DrmConvertSession.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package com.google.android.mms.util; - -import android.content.Context; -import android.drm.DrmConvertedStatus; -import android.drm.DrmManagerClient; -import android.provider.Downloads; -import android.util.Log; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; - - -public class DrmConvertSession { - private DrmManagerClient mDrmClient; - private int mConvertSessionId; - private static final String TAG = "DrmConvertSession"; - - private DrmConvertSession(DrmManagerClient drmClient, int convertSessionId) { - mDrmClient = drmClient; - mConvertSessionId = convertSessionId; - } - - /** - * Start of converting a file. - * - * @param context The context of the application running the convert session. - * @param mimeType Mimetype of content that shall be converted. - * @return A convert session or null in case an error occurs. - */ - @UnsupportedAppUsage - public static DrmConvertSession open(Context context, String mimeType) { - DrmManagerClient drmClient = null; - int convertSessionId = -1; - if (context != null && mimeType != null && !mimeType.equals("")) { - try { - drmClient = new DrmManagerClient(context); - try { - convertSessionId = drmClient.openConvertSession(mimeType); - } catch (IllegalArgumentException e) { - Log.w(TAG, "Conversion of Mimetype: " + mimeType - + " is not supported.", e); - } catch (IllegalStateException e) { - Log.w(TAG, "Could not access Open DrmFramework.", e); - } - } catch (IllegalArgumentException e) { - Log.w(TAG, - "DrmManagerClient instance could not be created, context is Illegal."); - } catch (IllegalStateException e) { - Log.w(TAG, "DrmManagerClient didn't initialize properly."); - } - } - - if (drmClient == null || convertSessionId < 0) { - return null; - } else { - return new DrmConvertSession(drmClient, convertSessionId); - } - } - /** - * Convert a buffer of data to protected format. - * - * @param buffer Buffer filled with data to convert. - * @param size The number of bytes that shall be converted. - * @return A Buffer filled with converted data, if execution is ok, in all - * other case null. - */ - @UnsupportedAppUsage - public byte [] convert(byte[] inBuffer, int size) { - byte[] result = null; - if (inBuffer != null) { - DrmConvertedStatus convertedStatus = null; - try { - if (size != inBuffer.length) { - byte[] buf = new byte[size]; - System.arraycopy(inBuffer, 0, buf, 0, size); - convertedStatus = mDrmClient.convertData(mConvertSessionId, buf); - } else { - convertedStatus = mDrmClient.convertData(mConvertSessionId, inBuffer); - } - - if (convertedStatus != null && - convertedStatus.statusCode == DrmConvertedStatus.STATUS_OK && - convertedStatus.convertedData != null) { - result = convertedStatus.convertedData; - } - } catch (IllegalArgumentException e) { - Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: " - + mConvertSessionId, e); - } catch (IllegalStateException e) { - Log.w(TAG, "Could not convert data. Convertsession: " + - mConvertSessionId, e); - } - } else { - throw new IllegalArgumentException("Parameter inBuffer is null"); - } - return result; - } - - /** - * Ends a conversion session of a file. - * - * @param fileName The filename of the converted file. - * @return Downloads.Impl.STATUS_SUCCESS if execution is ok. - * Downloads.Impl.STATUS_FILE_ERROR in case converted file can not - * be accessed. Downloads.Impl.STATUS_NOT_ACCEPTABLE if a problem - * occurs when accessing drm framework. - * Downloads.Impl.STATUS_UNKNOWN_ERROR if a general error occurred. - */ - @UnsupportedAppUsage - public int close(String filename) { - DrmConvertedStatus convertedStatus = null; - int result = Downloads.Impl.STATUS_UNKNOWN_ERROR; - if (mDrmClient != null && mConvertSessionId >= 0) { - try { - convertedStatus = mDrmClient.closeConvertSession(mConvertSessionId); - if (convertedStatus == null || - convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK || - convertedStatus.convertedData == null) { - result = Downloads.Impl.STATUS_NOT_ACCEPTABLE; - } else { - RandomAccessFile rndAccessFile = null; - try { - rndAccessFile = new RandomAccessFile(filename, "rw"); - rndAccessFile.seek(convertedStatus.offset); - rndAccessFile.write(convertedStatus.convertedData); - result = Downloads.Impl.STATUS_SUCCESS; - } catch (FileNotFoundException e) { - result = Downloads.Impl.STATUS_FILE_ERROR; - Log.w(TAG, "File: " + filename + " could not be found.", e); - } catch (IOException e) { - result = Downloads.Impl.STATUS_FILE_ERROR; - Log.w(TAG, "Could not access File: " + filename + " .", e); - } catch (IllegalArgumentException e) { - result = Downloads.Impl.STATUS_FILE_ERROR; - Log.w(TAG, "Could not open file in mode: rw", e); - } catch (SecurityException e) { - Log.w(TAG, "Access to File: " + filename + - " was denied denied by SecurityManager.", e); - } finally { - if (rndAccessFile != null) { - try { - rndAccessFile.close(); - } catch (IOException e) { - result = Downloads.Impl.STATUS_FILE_ERROR; - Log.w(TAG, "Failed to close File:" + filename - + ".", e); - } - } - } - } - } catch (IllegalStateException e) { - Log.w(TAG, "Could not close convertsession. Convertsession: " + - mConvertSessionId, e); - } - } - return result; - } -} diff --git a/telephony/java/com/google/android/mms/util/PduCache.java b/telephony/java/com/google/android/mms/util/PduCache.java deleted file mode 100644 index 94e38946f632..000000000000 --- a/telephony/java/com/google/android/mms/util/PduCache.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.util; - -import android.content.ContentUris; -import android.content.UriMatcher; -import android.net.Uri; -import android.provider.Telephony.Mms; -import android.util.Log; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import java.util.HashMap; -import java.util.HashSet; - -public final class PduCache extends AbstractCache<Uri, PduCacheEntry> { - private static final String TAG = "PduCache"; - private static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = false; - - private static final int MMS_ALL = 0; - private static final int MMS_ALL_ID = 1; - private static final int MMS_INBOX = 2; - private static final int MMS_INBOX_ID = 3; - private static final int MMS_SENT = 4; - private static final int MMS_SENT_ID = 5; - private static final int MMS_DRAFTS = 6; - private static final int MMS_DRAFTS_ID = 7; - private static final int MMS_OUTBOX = 8; - private static final int MMS_OUTBOX_ID = 9; - private static final int MMS_CONVERSATION = 10; - private static final int MMS_CONVERSATION_ID = 11; - - private static final UriMatcher URI_MATCHER; - private static final HashMap<Integer, Integer> MATCH_TO_MSGBOX_ID_MAP; - - private static PduCache sInstance; - - static { - URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH); - URI_MATCHER.addURI("mms", null, MMS_ALL); - URI_MATCHER.addURI("mms", "#", MMS_ALL_ID); - URI_MATCHER.addURI("mms", "inbox", MMS_INBOX); - URI_MATCHER.addURI("mms", "inbox/#", MMS_INBOX_ID); - URI_MATCHER.addURI("mms", "sent", MMS_SENT); - URI_MATCHER.addURI("mms", "sent/#", MMS_SENT_ID); - URI_MATCHER.addURI("mms", "drafts", MMS_DRAFTS); - URI_MATCHER.addURI("mms", "drafts/#", MMS_DRAFTS_ID); - URI_MATCHER.addURI("mms", "outbox", MMS_OUTBOX); - URI_MATCHER.addURI("mms", "outbox/#", MMS_OUTBOX_ID); - URI_MATCHER.addURI("mms-sms", "conversations", MMS_CONVERSATION); - URI_MATCHER.addURI("mms-sms", "conversations/#", MMS_CONVERSATION_ID); - - MATCH_TO_MSGBOX_ID_MAP = new HashMap<Integer, Integer>(); - MATCH_TO_MSGBOX_ID_MAP.put(MMS_INBOX, Mms.MESSAGE_BOX_INBOX); - MATCH_TO_MSGBOX_ID_MAP.put(MMS_SENT, Mms.MESSAGE_BOX_SENT); - MATCH_TO_MSGBOX_ID_MAP.put(MMS_DRAFTS, Mms.MESSAGE_BOX_DRAFTS); - MATCH_TO_MSGBOX_ID_MAP.put(MMS_OUTBOX, Mms.MESSAGE_BOX_OUTBOX); - } - - private final HashMap<Integer, HashSet<Uri>> mMessageBoxes; - private final HashMap<Long, HashSet<Uri>> mThreads; - private final HashSet<Uri> mUpdating; - - @UnsupportedAppUsage - private PduCache() { - mMessageBoxes = new HashMap<Integer, HashSet<Uri>>(); - mThreads = new HashMap<Long, HashSet<Uri>>(); - mUpdating = new HashSet<Uri>(); - } - - @UnsupportedAppUsage - synchronized public static final PduCache getInstance() { - if (sInstance == null) { - if (LOCAL_LOGV) { - Log.v(TAG, "Constructing new PduCache instance."); - } - sInstance = new PduCache(); - } - return sInstance; - } - - @Override - synchronized public boolean put(Uri uri, PduCacheEntry entry) { - int msgBoxId = entry.getMessageBox(); - HashSet<Uri> msgBox = mMessageBoxes.get(msgBoxId); - if (msgBox == null) { - msgBox = new HashSet<Uri>(); - mMessageBoxes.put(msgBoxId, msgBox); - } - - long threadId = entry.getThreadId(); - HashSet<Uri> thread = mThreads.get(threadId); - if (thread == null) { - thread = new HashSet<Uri>(); - mThreads.put(threadId, thread); - } - - Uri finalKey = normalizeKey(uri); - boolean result = super.put(finalKey, entry); - if (result) { - msgBox.add(finalKey); - thread.add(finalKey); - } - setUpdating(uri, false); - return result; - } - - synchronized public void setUpdating(Uri uri, boolean updating) { - if (updating) { - mUpdating.add(uri); - } else { - mUpdating.remove(uri); - } - } - - @UnsupportedAppUsage - synchronized public boolean isUpdating(Uri uri) { - return mUpdating.contains(uri); - } - - @Override - @UnsupportedAppUsage - synchronized public PduCacheEntry purge(Uri uri) { - int match = URI_MATCHER.match(uri); - switch (match) { - case MMS_ALL_ID: - return purgeSingleEntry(uri); - case MMS_INBOX_ID: - case MMS_SENT_ID: - case MMS_DRAFTS_ID: - case MMS_OUTBOX_ID: - String msgId = uri.getLastPathSegment(); - return purgeSingleEntry(Uri.withAppendedPath(Mms.CONTENT_URI, msgId)); - // Implicit batch of purge, return null. - case MMS_ALL: - case MMS_CONVERSATION: - purgeAll(); - return null; - case MMS_INBOX: - case MMS_SENT: - case MMS_DRAFTS: - case MMS_OUTBOX: - purgeByMessageBox(MATCH_TO_MSGBOX_ID_MAP.get(match)); - return null; - case MMS_CONVERSATION_ID: - purgeByThreadId(ContentUris.parseId(uri)); - return null; - default: - return null; - } - } - - private PduCacheEntry purgeSingleEntry(Uri key) { - mUpdating.remove(key); - PduCacheEntry entry = super.purge(key); - if (entry != null) { - removeFromThreads(key, entry); - removeFromMessageBoxes(key, entry); - return entry; - } - return null; - } - - @UnsupportedAppUsage - @Override - synchronized public void purgeAll() { - super.purgeAll(); - - mMessageBoxes.clear(); - mThreads.clear(); - mUpdating.clear(); - } - - /** - * @param uri The Uri to be normalized. - * @return Uri The normalized key of cached entry. - */ - private Uri normalizeKey(Uri uri) { - int match = URI_MATCHER.match(uri); - Uri normalizedKey = null; - - switch (match) { - case MMS_ALL_ID: - normalizedKey = uri; - break; - case MMS_INBOX_ID: - case MMS_SENT_ID: - case MMS_DRAFTS_ID: - case MMS_OUTBOX_ID: - String msgId = uri.getLastPathSegment(); - normalizedKey = Uri.withAppendedPath(Mms.CONTENT_URI, msgId); - break; - default: - return null; - } - - if (LOCAL_LOGV) { - Log.v(TAG, uri + " -> " + normalizedKey); - } - return normalizedKey; - } - - private void purgeByMessageBox(Integer msgBoxId) { - if (LOCAL_LOGV) { - Log.v(TAG, "Purge cache in message box: " + msgBoxId); - } - - if (msgBoxId != null) { - HashSet<Uri> msgBox = mMessageBoxes.remove(msgBoxId); - if (msgBox != null) { - for (Uri key : msgBox) { - mUpdating.remove(key); - PduCacheEntry entry = super.purge(key); - if (entry != null) { - removeFromThreads(key, entry); - } - } - } - } - } - - private void removeFromThreads(Uri key, PduCacheEntry entry) { - HashSet<Uri> thread = mThreads.get(entry.getThreadId()); - if (thread != null) { - thread.remove(key); - } - } - - private void purgeByThreadId(long threadId) { - if (LOCAL_LOGV) { - Log.v(TAG, "Purge cache in thread: " + threadId); - } - - HashSet<Uri> thread = mThreads.remove(threadId); - if (thread != null) { - for (Uri key : thread) { - mUpdating.remove(key); - PduCacheEntry entry = super.purge(key); - if (entry != null) { - removeFromMessageBoxes(key, entry); - } - } - } - } - - private void removeFromMessageBoxes(Uri key, PduCacheEntry entry) { - HashSet<Uri> msgBox = mThreads.get(Long.valueOf(entry.getMessageBox())); - if (msgBox != null) { - msgBox.remove(key); - } - } -} diff --git a/telephony/java/com/google/android/mms/util/PduCacheEntry.java b/telephony/java/com/google/android/mms/util/PduCacheEntry.java deleted file mode 100644 index 1ecd1bf93e7f..000000000000 --- a/telephony/java/com/google/android/mms/util/PduCacheEntry.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.util; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -import com.google.android.mms.pdu.GenericPdu; - -public final class PduCacheEntry { - private final GenericPdu mPdu; - private final int mMessageBox; - private final long mThreadId; - - @UnsupportedAppUsage - public PduCacheEntry(GenericPdu pdu, int msgBox, long threadId) { - mPdu = pdu; - mMessageBox = msgBox; - mThreadId = threadId; - } - - @UnsupportedAppUsage - public GenericPdu getPdu() { - return mPdu; - } - - @UnsupportedAppUsage - public int getMessageBox() { - return mMessageBox; - } - - @UnsupportedAppUsage - public long getThreadId() { - return mThreadId; - } -} diff --git a/telephony/java/com/google/android/mms/util/SqliteWrapper.java b/telephony/java/com/google/android/mms/util/SqliteWrapper.java deleted file mode 100644 index 2dd1dc11c2a9..000000000000 --- a/telephony/java/com/google/android/mms/util/SqliteWrapper.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2008 Esmertec AG. - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.mms.util; - -import android.app.ActivityManager; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteException; -import android.net.Uri; -import android.util.Log; -import android.widget.Toast; - -import dalvik.annotation.compat.UnsupportedAppUsage; - -public final class SqliteWrapper { - private static final String TAG = "SqliteWrapper"; - private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE - = "unable to open database file"; - - private SqliteWrapper() { - // Forbidden being instantiated. - } - - // FIXME: It looks like outInfo.lowMemory does not work well as we expected. - // after run command: adb shell fillup -p 100, outInfo.lowMemory is still false. - private static boolean isLowMemory(Context context) { - if (null == context) { - return false; - } - - ActivityManager am = (ActivityManager) - context.getSystemService(Context.ACTIVITY_SERVICE); - ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo(); - am.getMemoryInfo(outInfo); - - return outInfo.lowMemory; - } - - // FIXME: need to optimize this method. - private static boolean isLowMemory(SQLiteException e) { - return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE); - } - - @UnsupportedAppUsage - public static void checkSQLiteException(Context context, SQLiteException e) { - if (isLowMemory(e)) { - Toast.makeText(context, com.android.internal.R.string.low_memory, - Toast.LENGTH_SHORT).show(); - } else { - throw e; - } - } - - @UnsupportedAppUsage - public static Cursor query(Context context, ContentResolver resolver, Uri uri, - String[] projection, String selection, String[] selectionArgs, String sortOrder) { - try { - return resolver.query(uri, projection, selection, selectionArgs, sortOrder); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when query: ", e); - checkSQLiteException(context, e); - return null; - } - } - - @UnsupportedAppUsage - public static boolean requery(Context context, Cursor cursor) { - try { - return cursor.requery(); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when requery: ", e); - checkSQLiteException(context, e); - return false; - } - } - @UnsupportedAppUsage - public static int update(Context context, ContentResolver resolver, Uri uri, - ContentValues values, String where, String[] selectionArgs) { - try { - return resolver.update(uri, values, where, selectionArgs); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when update: ", e); - checkSQLiteException(context, e); - return -1; - } - } - - @UnsupportedAppUsage - public static int delete(Context context, ContentResolver resolver, Uri uri, - String where, String[] selectionArgs) { - try { - return resolver.delete(uri, where, selectionArgs); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when delete: ", e); - checkSQLiteException(context, e); - return -1; - } - } - - @UnsupportedAppUsage - public static Uri insert(Context context, ContentResolver resolver, - Uri uri, ContentValues values) { - try { - return resolver.insert(uri, values); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when insert: ", e); - checkSQLiteException(context, e); - return null; - } - } -} diff --git a/telephony/java/com/google/android/mms/util/package.html b/telephony/java/com/google/android/mms/util/package.html deleted file mode 100755 index c9f96a66ab3b..000000000000 --- a/telephony/java/com/google/android/mms/util/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> - -{@hide} - -</body> |