From 96d9299b95f3af870c1d10e408344e1085c0b265 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Tue, 17 Jul 2012 14:46:34 -0700 Subject: Fix our interpretation of apn setting's bearer. Between ICS and JB we changed it to use TelephonyManager's network type enumeration. This changes it back to represent the RIL's radio technology. The only diff between the two is 13 and 14 are swapped, so the change was causing problems with LTE and eHRPD. bug:6830908 Change-Id: I85a7c8037f370f368e5cbf6dc2c9395c6889b541 --- .../android/internal/telephony/gsm/GsmDataConnectionTracker.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 6b863a7d0e68..a971066a6bad 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -2374,7 +2374,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } String operator = mPhone.mIccRecords.getOperatorNumeric(); - int networkType = mPhone.getServiceState().getNetworkType(); + int radioTech = mPhone.getServiceState().getRilRadioTechnology(); if (canSetPreferApn && mPreferredApn != null && mPreferredApn.canHandleType(requestedApnType)) { @@ -2383,7 +2383,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { + mPreferredApn.numeric + ":" + mPreferredApn); } if (mPreferredApn.numeric.equals(operator)) { - if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == networkType) { + if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) { apnList.add(mPreferredApn); if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList); return apnList; @@ -2401,7 +2401,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (mAllApns != null) { for (ApnSetting apn : mAllApns) { if (apn.canHandleType(requestedApnType)) { - if (apn.bearer == 0 || apn.bearer == networkType) { + if (apn.bearer == 0 || apn.bearer == radioTech) { if (DBG) log("apn info : " +apn.toString()); apnList.add(apn); } -- cgit v1.2.3 From bececc79d608c40af442e10109ba4c71630b43ef Mon Sep 17 00:00:00 2001 From: Jake Hamby Date: Mon, 23 Jul 2012 14:42:33 -0700 Subject: Fix detection of CDMA cell broadcast messages. The bIsServicePresent field of an incoming CDMA SMS RIL message is not a reliable way to distinguish broadcast from point-to-point messages on some RILs. Change CDMA SmsMessage.getMessageType() to return MESSAGE_TYPE_BROADCAST when the service category is not 0, and MESSAGE_TYPE_POINT_TO_POINT when the service category is 0. Bug: 6853691 Change-Id: I0d44a8ce0bb295da5125271db90652570d655bc1 --- .../java/com/android/internal/telephony/cdma/SmsMessage.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index a723de3543c3..7292b86b9f42 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -468,7 +468,13 @@ public class SmsMessage extends SmsMessageBase { * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE}, */ /* package */ int getMessageType() { - return mEnvelope.messageType; + // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs. + // Use the service category parameter to detect CMAS and other cell broadcast messages. + if (mEnvelope.serviceCategory != 0) { + return SmsEnvelope.MESSAGE_TYPE_BROADCAST; + } else { + return SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; + } } /** -- cgit v1.2.3 From 3044d723cb9e9450361c6fc64b78797ecf03e2ef Mon Sep 17 00:00:00 2001 From: Jake Hamby Date: Tue, 24 Jul 2012 15:39:45 -0700 Subject: Implement CMAS service category program results. Correctly handle CDMA Service Category Program Data requests, and send the SCPT response to the message center. Parcel SCPD operations as an ArrayList instead of an array (current version will throw ClassCastException when the array is cast). Bug: 6853691 Change-Id: I949ea68891c78306059248832e59a593ab606e11 --- .../telephony/cdma/CdmaSmsCbProgramData.java | 18 +-- .../telephony/cdma/CdmaSmsCbProgramResults.java | 144 +++++++++++++++++++++ .../android/internal/telephony/SMSDispatcher.java | 16 +++ .../internal/telephony/cdma/CdmaSMSDispatcher.java | 93 +++++++++++-- .../internal/telephony/cdma/SmsMessage.java | 5 +- .../internal/telephony/cdma/sms/BearerData.java | 34 ++++- .../internal/telephony/cdma/CdmaSmsCbTest.java | 6 +- 7 files changed, 287 insertions(+), 29 deletions(-) create mode 100644 telephony/java/android/telephony/cdma/CdmaSmsCbProgramResults.java diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java index f94efd8f56d7..010ad2b0a2c8 100644 --- a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java +++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java @@ -81,8 +81,8 @@ public class CdmaSmsCbProgramData implements Parcelable { /** Service category to modify. */ private final int mCategory; - /** Language used for service category name (ISO 639 two character code). */ - private final String mLanguage; + /** Language used for service category name (defined in BearerData.LANGUAGE_*). */ + private final int mLanguage; /** Maximum number of messages to store for this service category. */ private final int mMaxMessages; @@ -94,7 +94,7 @@ public class CdmaSmsCbProgramData implements Parcelable { private final String mCategoryName; /** Create a new CdmaSmsCbProgramData object with the specified values. */ - public CdmaSmsCbProgramData(int operation, int category, String language, int maxMessages, + public CdmaSmsCbProgramData(int operation, int category, int language, int maxMessages, int alertOption, String categoryName) { mOperation = operation; mCategory = category; @@ -108,7 +108,7 @@ public class CdmaSmsCbProgramData implements Parcelable { CdmaSmsCbProgramData(Parcel in) { mOperation = in.readInt(); mCategory = in.readInt(); - mLanguage = in.readString(); + mLanguage = in.readInt(); mMaxMessages = in.readInt(); mAlertOption = in.readInt(); mCategoryName = in.readString(); @@ -124,7 +124,7 @@ public class CdmaSmsCbProgramData implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mOperation); dest.writeInt(mCategory); - dest.writeString(mLanguage); + dest.writeInt(mLanguage); dest.writeInt(mMaxMessages); dest.writeInt(mAlertOption); dest.writeString(mCategoryName); @@ -147,10 +147,10 @@ public class CdmaSmsCbProgramData implements Parcelable { } /** - * Returns the ISO-639-1 language code for the service category name, or null if not present. - * @return a two-digit ISO-639-1 language code, e.g. "en" for English + * Returns the CDMA language code for this service category. + * @return one of the language values defined in BearerData.LANGUAGE_* */ - public String getLanguageCode() { + public int getLanguage() { return mLanguage; } @@ -171,7 +171,7 @@ public class CdmaSmsCbProgramData implements Parcelable { } /** - * Returns the service category name, in the language specified by {@link #getLanguageCode()}. + * Returns the service category name, in the language specified by {@link #getLanguage()}. * @return an optional service category name */ public String getCategoryName() { diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramResults.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramResults.java new file mode 100644 index 000000000000..68bfa3ce9016 --- /dev/null +++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramResults.java @@ -0,0 +1,144 @@ +/* + * 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 android.telephony.cdma; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * CDMA Service Category Program Results from SCPT teleservice SMS. + * + * {@hide} + */ +public class CdmaSmsCbProgramResults implements Parcelable { + + /** Program result: success. */ + public static final int RESULT_SUCCESS = 0; + + /** Program result: memory limit exceeded. */ + public static final int RESULT_MEMORY_LIMIT_EXCEEDED = 1; + + /** Program result: limit exceeded. */ + public static final int RESULT_CATEGORY_LIMIT_EXCEEDED = 2; + + /** Program result: category already opted in. */ + public static final int RESULT_CATEGORY_ALREADY_ADDED = 3; + + /** Program result: category already opted in. */ + public static final int RESULT_CATEGORY_ALREADY_DELETED = 4; + + /** Program result: invalid MAX_MESSAGES. */ + public static final int RESULT_INVALID_MAX_MESSAGES = 5; + + /** Program result: invalid ALERT_OPTION. */ + public static final int RESULT_INVALID_ALERT_OPTION = 6; + + /** Program result: invalid service category name. */ + public static final int RESULT_INVALID_CATEGORY_NAME = 7; + + /** Program result: unspecified programming failure. */ + public static final int RESULT_UNSPECIFIED_FAILURE = 8; + + /** Service category to modify. */ + private final int mCategory; + + /** Language used for service category name (defined in BearerData.LANGUAGE_*). */ + private final int mLanguage; + + /** Result of service category programming for this category. */ + private final int mCategoryResult; + + /** Create a new CdmaSmsCbProgramResults object with the specified values. */ + public CdmaSmsCbProgramResults(int category, int language, int categoryResult) { + mCategory = category; + mLanguage = language; + mCategoryResult = categoryResult; + } + + /** Create a new CdmaSmsCbProgramResults object from a Parcel. */ + CdmaSmsCbProgramResults(Parcel in) { + mCategory = in.readInt(); + mLanguage = in.readInt(); + mCategoryResult = in.readInt(); + } + + /** + * Flatten this object into a Parcel. + * + * @param dest The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written (ignored). + */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mCategory); + dest.writeInt(mLanguage); + dest.writeInt(mCategoryResult); + } + + /** + * Returns the CDMA service category to modify. + * @return a 16-bit CDMA service category value + */ + public int getCategory() { + return mCategory; + } + + /** + * Returns the CDMA language code for this service category. + * @return one of the language values defined in BearerData.LANGUAGE_* + */ + public int getLanguage() { + return mLanguage; + } + + /** + * Returns the result of service programming for this category + * @return the result of service programming for this category + */ + public int getCategoryResult() { + return mCategoryResult; + } + + @Override + public String toString() { + return "CdmaSmsCbProgramResults{category=" + mCategory + + ", language=" + mLanguage + ", result=" + mCategoryResult + '}'; + } + + /** + * Describe the kinds of special objects contained in the marshalled representation. + * @return a bitmask indicating this Parcelable contains no special objects + */ + @Override + public int describeContents() { + return 0; + } + + /** Creator for unparcelling objects. */ + public static final Parcelable.Creator + CREATOR = new Parcelable.Creator() { + @Override + public CdmaSmsCbProgramResults createFromParcel(Parcel in) { + return new CdmaSmsCbProgramResults(in); + } + + @Override + public CdmaSmsCbProgramResults[] newArray(int size) { + return new CdmaSmsCbProgramResults[size]; + } + }; +} diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index 07d733eda9cf..40c22a72b01e 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -338,6 +338,22 @@ public abstract class SMSDispatcher extends Handler { this, Activity.RESULT_OK, null, null); } + /** + * Grabs a wake lock and sends intent as an ordered broadcast. + * Used for setting a custom result receiver for CDMA SCPD. + * + * @param intent intent to broadcast + * @param permission Receivers are required to have this permission + * @param resultReceiver the result receiver to use + */ + public void dispatch(Intent intent, String permission, BroadcastReceiver resultReceiver) { + // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any + // receivers time to take their own wake locks. + mWakeLock.acquire(WAKE_LOCK_TIMEOUT); + mContext.sendOrderedBroadcast(intent, permission, resultReceiver, + this, Activity.RESULT_OK, null, null); + } + /** * Called when SMS send completes. Broadcasts a sentIntent on success. * On failure, either sets up retries or broadcasts a sentIntent with diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index e6b45f6940e8..a6b32f9957b8 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -20,20 +20,23 @@ package com.android.internal.telephony.cdma; import android.app.Activity; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; -import android.content.ContentValues; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.database.Cursor; -import android.database.SQLException; +import android.content.res.Resources; +import android.os.Bundle; import android.os.Message; import android.os.SystemProperties; import android.preference.PreferenceManager; import android.provider.Telephony; import android.provider.Telephony.Sms.Intents; +import android.telephony.PhoneNumberUtils; import android.telephony.SmsCbMessage; import android.telephony.SmsManager; import android.telephony.SmsMessage.MessageClass; import android.telephony.cdma.CdmaSmsCbProgramData; +import android.telephony.cdma.CdmaSmsCbProgramResults; import android.util.Log; import com.android.internal.telephony.CommandsInterface; @@ -45,16 +48,17 @@ import com.android.internal.telephony.SmsStorageMonitor; import com.android.internal.telephony.SmsUsageMonitor; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.WspTypeDecoder; +import com.android.internal.telephony.cdma.sms.BearerData; +import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; import com.android.internal.telephony.cdma.sms.SmsEnvelope; import com.android.internal.telephony.cdma.sms.UserData; -import com.android.internal.util.HexDump; import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.List; - -import android.content.res.Resources; final class CdmaSMSDispatcher extends SMSDispatcher { @@ -107,15 +111,16 @@ final class CdmaSMSDispatcher extends SMSDispatcher { * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects. */ private void handleServiceCategoryProgramData(SmsMessage sms) { - List programDataList = sms.getSmsCbProgramData(); + ArrayList programDataList = sms.getSmsCbProgramData(); if (programDataList == null) { Log.e(TAG, "handleServiceCategoryProgramData: program data list is null!"); return; } Intent intent = new Intent(Intents.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION); - intent.putExtra("program_data_list", (CdmaSmsCbProgramData[]) programDataList.toArray()); - dispatch(intent, RECEIVE_SMS_PERMISSION); + intent.putExtra("sender", sms.getOriginatingAddress()); + intent.putParcelableArrayListExtra("program_data", programDataList); + dispatch(intent, RECEIVE_SMS_PERMISSION, mScpResultsReceiver); } /** {@inheritDoc} */ @@ -425,4 +430,72 @@ final class CdmaSMSDispatcher extends SMSDispatcher { } return false; } + + // Receiver for Service Category Program Data results. + // We already ACK'd the original SCPD SMS, so this sends a new response SMS. + // TODO: handle retries if the RIL returns an error. + private final BroadcastReceiver mScpResultsReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + int rc = getResultCode(); + boolean success = (rc == Activity.RESULT_OK) || (rc == Intents.RESULT_SMS_HANDLED); + if (!success) { + Log.e(TAG, "SCP results error: result code = " + rc); + return; + } + Bundle extras = getResultExtras(false); + if (extras == null) { + Log.e(TAG, "SCP results error: missing extras"); + return; + } + String sender = extras.getString("sender"); + if (sender == null) { + Log.e(TAG, "SCP results error: missing sender extra."); + return; + } + ArrayList results + = extras.getParcelableArrayList("results"); + if (results == null) { + Log.e(TAG, "SCP results error: missing results extra."); + return; + } + + BearerData bData = new BearerData(); + bData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; + bData.messageId = SmsMessage.getNextMessageId(); + bData.serviceCategoryProgramResults = results; + byte[] encodedBearerData = BearerData.encode(bData); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(100); + DataOutputStream dos = new DataOutputStream(baos); + try { + dos.writeInt(SmsEnvelope.TELESERVICE_SCPT); + dos.writeInt(0); //servicePresent + dos.writeInt(0); //serviceCategory + CdmaSmsAddress destAddr = CdmaSmsAddress.parse( + PhoneNumberUtils.cdmaCheckAndProcessPlusCode(sender)); + dos.write(destAddr.digitMode); + dos.write(destAddr.numberMode); + dos.write(destAddr.ton); // number_type + dos.write(destAddr.numberPlan); + dos.write(destAddr.numberOfDigits); + dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits + // Subaddress is not supported. + dos.write(0); //subaddressType + dos.write(0); //subaddr_odd + dos.write(0); //subaddr_nbr_of_digits + dos.write(encodedBearerData.length); + dos.write(encodedBearerData, 0, encodedBearerData.length); + // Ignore the RIL response. TODO: implement retry if SMS send fails. + mCm.sendCdmaSms(baos.toByteArray(), null); + } catch (IOException e) { + Log.e(TAG, "exception creating SCP results PDU", e); + } finally { + try { + dos.close(); + } catch (IOException ignored) { + } + } + } + }; } diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 7292b86b9f42..9a0ebedde40c 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -42,6 +42,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import static android.telephony.SmsMessage.MessageClass; @@ -781,7 +782,7 @@ public class SmsMessage extends SmsMessageBase { * binder-call, and hence should be thread-safe, it has been * synchronized. */ - private synchronized static int getNextMessageId() { + synchronized static int getNextMessageId() { // Testing and dialog with partners has indicated that // msgId==0 is (sometimes?) treated specially by lower levels. // Specifically, the ID is not preserved for delivery ACKs. @@ -997,7 +998,7 @@ public class SmsMessage extends SmsMessageBase { * Returns the list of service category program data, if present. * @return a list of CdmaSmsCbProgramData objects, or null if not present */ - List getSmsCbProgramData() { + ArrayList getSmsCbProgramData() { return mBearerData.serviceCategoryProgramData; } } diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java index 0f497625b8a2..5cacd23b8bf6 100755 --- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java @@ -18,9 +18,9 @@ package com.android.internal.telephony.cdma.sms; import android.content.res.Resources; import android.telephony.SmsCbCmasInfo; -import android.telephony.SmsCbMessage; import android.telephony.SmsMessage; import android.telephony.cdma.CdmaSmsCbProgramData; +import android.telephony.cdma.CdmaSmsCbProgramResults; import android.text.format.Time; import android.util.Log; @@ -32,8 +32,6 @@ import com.android.internal.util.BitwiseInputStream; import com.android.internal.util.BitwiseOutputStream; import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import java.util.TimeZone; import static android.telephony.SmsMessage.ENCODING_16BIT; @@ -353,7 +351,14 @@ public final class BearerData { * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects containing the * operation(s) to perform. */ - public List serviceCategoryProgramData; + public ArrayList serviceCategoryProgramData; + + /** + * The Service Category Program Results subparameter informs the message center + * of the results of a Service Category Program Data request. + */ + public ArrayList serviceCategoryProgramResults; + private static class CodingException extends Exception { public CodingException(String s) { @@ -857,6 +862,21 @@ public final class BearerData { outStream.skip(6); } + private static void encodeScpResults(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException + { + ArrayList results = bData.serviceCategoryProgramResults; + outStream.write(8, (results.size() * 4)); // 4 octets per program result + for (CdmaSmsCbProgramResults result : results) { + int category = result.getCategory(); + outStream.write(8, category >> 8); + outStream.write(8, category); + outStream.write(8, result.getLanguage()); + outStream.write(4, result.getCategoryResult()); + outStream.skip(4); + } + } + /** * Create serialized representation for BearerData object. * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details) @@ -916,6 +936,10 @@ public final class BearerData { outStream.write(8, SUBPARAM_MESSAGE_STATUS); encodeMsgStatus(bData, outStream); } + if (bData.serviceCategoryProgramResults != null) { + outStream.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS); + encodeScpResults(bData, outStream); + } return outStream.toByteArray(); } catch (BitwiseOutputStream.AccessException ex) { Log.e(LOG_TAG, "BearerData encode failed: " + ex); @@ -1638,7 +1662,7 @@ public final class BearerData { while (paramBits >= CATEGORY_FIELD_MIN_SIZE) { int operation = inStream.read(4); int category = (inStream.read(8) << 8) | inStream.read(8); - String language = getLanguageCodeForValue(inStream.read(8)); + int language = inStream.read(8); int maxMessages = inStream.read(8); int alertOption = inStream.read(4); int numFields = inStream.read(8); diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java index d2facebffb6a..a95f60c75f1c 100644 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java +++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java @@ -635,7 +635,7 @@ public class CdmaSmsCbTest extends AndroidTestCase { assertEquals(CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY, programData.getOperation()); assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, programData.getCategory()); assertEquals(CAT_EXTREME_THREAT, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); + assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage()); assertEquals(100, programData.getMaxMessages()); assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT, programData.getAlertOption()); } @@ -692,7 +692,7 @@ public class CdmaSmsCbTest extends AndroidTestCase { assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation()); assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, programData.getCategory()); assertEquals(CAT_SEVERE_THREAT, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); + assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage()); assertEquals(0, programData.getMaxMessages()); assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption()); @@ -701,7 +701,7 @@ public class CdmaSmsCbTest extends AndroidTestCase { assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY, programData.getCategory()); assertEquals(CAT_AMBER_ALERTS, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); + assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage()); assertEquals(0, programData.getMaxMessages()); assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption()); } -- cgit v1.2.3 From bf82980f7dea8a80fbec0dfe2e5283bac1ee80c5 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Tue, 17 Jul 2012 14:46:34 -0700 Subject: Fix our interpretation of apn setting's bearer. Between ICS and JB we changed it to use TelephonyManager's network type enumeration. This changes it back to represent the RIL's radio technology. The only diff between the two is 13 and 14 are swapped, so the change was causing problems with LTE and eHRPD. bug:6830908 Change-Id: I85a7c8037f370f368e5cbf6dc2c9395c6889b541 --- .../android/internal/telephony/gsm/GsmDataConnectionTracker.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 6b863a7d0e68..a971066a6bad 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -2374,7 +2374,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } String operator = mPhone.mIccRecords.getOperatorNumeric(); - int networkType = mPhone.getServiceState().getNetworkType(); + int radioTech = mPhone.getServiceState().getRilRadioTechnology(); if (canSetPreferApn && mPreferredApn != null && mPreferredApn.canHandleType(requestedApnType)) { @@ -2383,7 +2383,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { + mPreferredApn.numeric + ":" + mPreferredApn); } if (mPreferredApn.numeric.equals(operator)) { - if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == networkType) { + if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) { apnList.add(mPreferredApn); if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList); return apnList; @@ -2401,7 +2401,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (mAllApns != null) { for (ApnSetting apn : mAllApns) { if (apn.canHandleType(requestedApnType)) { - if (apn.bearer == 0 || apn.bearer == networkType) { + if (apn.bearer == 0 || apn.bearer == radioTech) { if (DBG) log("apn info : " +apn.toString()); apnList.add(apn); } -- cgit v1.2.3 From 54e963a6c9064640984774b241eb32571e18ef4d Mon Sep 17 00:00:00 2001 From: Jake Hamby Date: Mon, 23 Jul 2012 14:42:33 -0700 Subject: Fix detection of CDMA cell broadcast messages. The bIsServicePresent field of an incoming CDMA SMS RIL message is not a reliable way to distinguish broadcast from point-to-point messages on some RILs. Change CDMA SmsMessage.getMessageType() to return MESSAGE_TYPE_BROADCAST when the service category is not 0, and MESSAGE_TYPE_POINT_TO_POINT when the service category is 0. Bug: 6853691 Change-Id: I0d44a8ce0bb295da5125271db90652570d655bc1 --- .../java/com/android/internal/telephony/cdma/SmsMessage.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index a723de3543c3..7292b86b9f42 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -468,7 +468,13 @@ public class SmsMessage extends SmsMessageBase { * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE}, */ /* package */ int getMessageType() { - return mEnvelope.messageType; + // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs. + // Use the service category parameter to detect CMAS and other cell broadcast messages. + if (mEnvelope.serviceCategory != 0) { + return SmsEnvelope.MESSAGE_TYPE_BROADCAST; + } else { + return SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; + } } /** -- cgit v1.2.3 From 08063c9ee36e2a9dff9abbd0bc62bbd212c568cc Mon Sep 17 00:00:00 2001 From: Jake Hamby Date: Tue, 24 Jul 2012 15:39:45 -0700 Subject: Implement CMAS service category program results. Correctly handle CDMA Service Category Program Data requests, and send the SCPT response to the message center. Parcel SCPD operations as an ArrayList instead of an array (current version will throw ClassCastException when the array is cast). Bug: 6853691 Change-Id: I949ea68891c78306059248832e59a593ab606e11 --- .../telephony/cdma/CdmaSmsCbProgramData.java | 18 +-- .../telephony/cdma/CdmaSmsCbProgramResults.java | 144 +++++++++++++++++++++ .../android/internal/telephony/SMSDispatcher.java | 16 +++ .../internal/telephony/cdma/CdmaSMSDispatcher.java | 93 +++++++++++-- .../internal/telephony/cdma/SmsMessage.java | 5 +- .../internal/telephony/cdma/sms/BearerData.java | 34 ++++- .../internal/telephony/cdma/CdmaSmsCbTest.java | 6 +- 7 files changed, 287 insertions(+), 29 deletions(-) create mode 100644 telephony/java/android/telephony/cdma/CdmaSmsCbProgramResults.java diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java index f94efd8f56d7..010ad2b0a2c8 100644 --- a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java +++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java @@ -81,8 +81,8 @@ public class CdmaSmsCbProgramData implements Parcelable { /** Service category to modify. */ private final int mCategory; - /** Language used for service category name (ISO 639 two character code). */ - private final String mLanguage; + /** Language used for service category name (defined in BearerData.LANGUAGE_*). */ + private final int mLanguage; /** Maximum number of messages to store for this service category. */ private final int mMaxMessages; @@ -94,7 +94,7 @@ public class CdmaSmsCbProgramData implements Parcelable { private final String mCategoryName; /** Create a new CdmaSmsCbProgramData object with the specified values. */ - public CdmaSmsCbProgramData(int operation, int category, String language, int maxMessages, + public CdmaSmsCbProgramData(int operation, int category, int language, int maxMessages, int alertOption, String categoryName) { mOperation = operation; mCategory = category; @@ -108,7 +108,7 @@ public class CdmaSmsCbProgramData implements Parcelable { CdmaSmsCbProgramData(Parcel in) { mOperation = in.readInt(); mCategory = in.readInt(); - mLanguage = in.readString(); + mLanguage = in.readInt(); mMaxMessages = in.readInt(); mAlertOption = in.readInt(); mCategoryName = in.readString(); @@ -124,7 +124,7 @@ public class CdmaSmsCbProgramData implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mOperation); dest.writeInt(mCategory); - dest.writeString(mLanguage); + dest.writeInt(mLanguage); dest.writeInt(mMaxMessages); dest.writeInt(mAlertOption); dest.writeString(mCategoryName); @@ -147,10 +147,10 @@ public class CdmaSmsCbProgramData implements Parcelable { } /** - * Returns the ISO-639-1 language code for the service category name, or null if not present. - * @return a two-digit ISO-639-1 language code, e.g. "en" for English + * Returns the CDMA language code for this service category. + * @return one of the language values defined in BearerData.LANGUAGE_* */ - public String getLanguageCode() { + public int getLanguage() { return mLanguage; } @@ -171,7 +171,7 @@ public class CdmaSmsCbProgramData implements Parcelable { } /** - * Returns the service category name, in the language specified by {@link #getLanguageCode()}. + * Returns the service category name, in the language specified by {@link #getLanguage()}. * @return an optional service category name */ public String getCategoryName() { diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramResults.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramResults.java new file mode 100644 index 000000000000..68bfa3ce9016 --- /dev/null +++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramResults.java @@ -0,0 +1,144 @@ +/* + * 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 android.telephony.cdma; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * CDMA Service Category Program Results from SCPT teleservice SMS. + * + * {@hide} + */ +public class CdmaSmsCbProgramResults implements Parcelable { + + /** Program result: success. */ + public static final int RESULT_SUCCESS = 0; + + /** Program result: memory limit exceeded. */ + public static final int RESULT_MEMORY_LIMIT_EXCEEDED = 1; + + /** Program result: limit exceeded. */ + public static final int RESULT_CATEGORY_LIMIT_EXCEEDED = 2; + + /** Program result: category already opted in. */ + public static final int RESULT_CATEGORY_ALREADY_ADDED = 3; + + /** Program result: category already opted in. */ + public static final int RESULT_CATEGORY_ALREADY_DELETED = 4; + + /** Program result: invalid MAX_MESSAGES. */ + public static final int RESULT_INVALID_MAX_MESSAGES = 5; + + /** Program result: invalid ALERT_OPTION. */ + public static final int RESULT_INVALID_ALERT_OPTION = 6; + + /** Program result: invalid service category name. */ + public static final int RESULT_INVALID_CATEGORY_NAME = 7; + + /** Program result: unspecified programming failure. */ + public static final int RESULT_UNSPECIFIED_FAILURE = 8; + + /** Service category to modify. */ + private final int mCategory; + + /** Language used for service category name (defined in BearerData.LANGUAGE_*). */ + private final int mLanguage; + + /** Result of service category programming for this category. */ + private final int mCategoryResult; + + /** Create a new CdmaSmsCbProgramResults object with the specified values. */ + public CdmaSmsCbProgramResults(int category, int language, int categoryResult) { + mCategory = category; + mLanguage = language; + mCategoryResult = categoryResult; + } + + /** Create a new CdmaSmsCbProgramResults object from a Parcel. */ + CdmaSmsCbProgramResults(Parcel in) { + mCategory = in.readInt(); + mLanguage = in.readInt(); + mCategoryResult = in.readInt(); + } + + /** + * Flatten this object into a Parcel. + * + * @param dest The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written (ignored). + */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mCategory); + dest.writeInt(mLanguage); + dest.writeInt(mCategoryResult); + } + + /** + * Returns the CDMA service category to modify. + * @return a 16-bit CDMA service category value + */ + public int getCategory() { + return mCategory; + } + + /** + * Returns the CDMA language code for this service category. + * @return one of the language values defined in BearerData.LANGUAGE_* + */ + public int getLanguage() { + return mLanguage; + } + + /** + * Returns the result of service programming for this category + * @return the result of service programming for this category + */ + public int getCategoryResult() { + return mCategoryResult; + } + + @Override + public String toString() { + return "CdmaSmsCbProgramResults{category=" + mCategory + + ", language=" + mLanguage + ", result=" + mCategoryResult + '}'; + } + + /** + * Describe the kinds of special objects contained in the marshalled representation. + * @return a bitmask indicating this Parcelable contains no special objects + */ + @Override + public int describeContents() { + return 0; + } + + /** Creator for unparcelling objects. */ + public static final Parcelable.Creator + CREATOR = new Parcelable.Creator() { + @Override + public CdmaSmsCbProgramResults createFromParcel(Parcel in) { + return new CdmaSmsCbProgramResults(in); + } + + @Override + public CdmaSmsCbProgramResults[] newArray(int size) { + return new CdmaSmsCbProgramResults[size]; + } + }; +} diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index 07d733eda9cf..40c22a72b01e 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -338,6 +338,22 @@ public abstract class SMSDispatcher extends Handler { this, Activity.RESULT_OK, null, null); } + /** + * Grabs a wake lock and sends intent as an ordered broadcast. + * Used for setting a custom result receiver for CDMA SCPD. + * + * @param intent intent to broadcast + * @param permission Receivers are required to have this permission + * @param resultReceiver the result receiver to use + */ + public void dispatch(Intent intent, String permission, BroadcastReceiver resultReceiver) { + // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any + // receivers time to take their own wake locks. + mWakeLock.acquire(WAKE_LOCK_TIMEOUT); + mContext.sendOrderedBroadcast(intent, permission, resultReceiver, + this, Activity.RESULT_OK, null, null); + } + /** * Called when SMS send completes. Broadcasts a sentIntent on success. * On failure, either sets up retries or broadcasts a sentIntent with diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index e6b45f6940e8..a6b32f9957b8 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -20,20 +20,23 @@ package com.android.internal.telephony.cdma; import android.app.Activity; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; -import android.content.ContentValues; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.database.Cursor; -import android.database.SQLException; +import android.content.res.Resources; +import android.os.Bundle; import android.os.Message; import android.os.SystemProperties; import android.preference.PreferenceManager; import android.provider.Telephony; import android.provider.Telephony.Sms.Intents; +import android.telephony.PhoneNumberUtils; import android.telephony.SmsCbMessage; import android.telephony.SmsManager; import android.telephony.SmsMessage.MessageClass; import android.telephony.cdma.CdmaSmsCbProgramData; +import android.telephony.cdma.CdmaSmsCbProgramResults; import android.util.Log; import com.android.internal.telephony.CommandsInterface; @@ -45,16 +48,17 @@ import com.android.internal.telephony.SmsStorageMonitor; import com.android.internal.telephony.SmsUsageMonitor; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.WspTypeDecoder; +import com.android.internal.telephony.cdma.sms.BearerData; +import com.android.internal.telephony.cdma.sms.CdmaSmsAddress; import com.android.internal.telephony.cdma.sms.SmsEnvelope; import com.android.internal.telephony.cdma.sms.UserData; -import com.android.internal.util.HexDump; import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.List; - -import android.content.res.Resources; final class CdmaSMSDispatcher extends SMSDispatcher { @@ -107,15 +111,16 @@ final class CdmaSMSDispatcher extends SMSDispatcher { * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects. */ private void handleServiceCategoryProgramData(SmsMessage sms) { - List programDataList = sms.getSmsCbProgramData(); + ArrayList programDataList = sms.getSmsCbProgramData(); if (programDataList == null) { Log.e(TAG, "handleServiceCategoryProgramData: program data list is null!"); return; } Intent intent = new Intent(Intents.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION); - intent.putExtra("program_data_list", (CdmaSmsCbProgramData[]) programDataList.toArray()); - dispatch(intent, RECEIVE_SMS_PERMISSION); + intent.putExtra("sender", sms.getOriginatingAddress()); + intent.putParcelableArrayListExtra("program_data", programDataList); + dispatch(intent, RECEIVE_SMS_PERMISSION, mScpResultsReceiver); } /** {@inheritDoc} */ @@ -425,4 +430,72 @@ final class CdmaSMSDispatcher extends SMSDispatcher { } return false; } + + // Receiver for Service Category Program Data results. + // We already ACK'd the original SCPD SMS, so this sends a new response SMS. + // TODO: handle retries if the RIL returns an error. + private final BroadcastReceiver mScpResultsReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + int rc = getResultCode(); + boolean success = (rc == Activity.RESULT_OK) || (rc == Intents.RESULT_SMS_HANDLED); + if (!success) { + Log.e(TAG, "SCP results error: result code = " + rc); + return; + } + Bundle extras = getResultExtras(false); + if (extras == null) { + Log.e(TAG, "SCP results error: missing extras"); + return; + } + String sender = extras.getString("sender"); + if (sender == null) { + Log.e(TAG, "SCP results error: missing sender extra."); + return; + } + ArrayList results + = extras.getParcelableArrayList("results"); + if (results == null) { + Log.e(TAG, "SCP results error: missing results extra."); + return; + } + + BearerData bData = new BearerData(); + bData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; + bData.messageId = SmsMessage.getNextMessageId(); + bData.serviceCategoryProgramResults = results; + byte[] encodedBearerData = BearerData.encode(bData); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(100); + DataOutputStream dos = new DataOutputStream(baos); + try { + dos.writeInt(SmsEnvelope.TELESERVICE_SCPT); + dos.writeInt(0); //servicePresent + dos.writeInt(0); //serviceCategory + CdmaSmsAddress destAddr = CdmaSmsAddress.parse( + PhoneNumberUtils.cdmaCheckAndProcessPlusCode(sender)); + dos.write(destAddr.digitMode); + dos.write(destAddr.numberMode); + dos.write(destAddr.ton); // number_type + dos.write(destAddr.numberPlan); + dos.write(destAddr.numberOfDigits); + dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits + // Subaddress is not supported. + dos.write(0); //subaddressType + dos.write(0); //subaddr_odd + dos.write(0); //subaddr_nbr_of_digits + dos.write(encodedBearerData.length); + dos.write(encodedBearerData, 0, encodedBearerData.length); + // Ignore the RIL response. TODO: implement retry if SMS send fails. + mCm.sendCdmaSms(baos.toByteArray(), null); + } catch (IOException e) { + Log.e(TAG, "exception creating SCP results PDU", e); + } finally { + try { + dos.close(); + } catch (IOException ignored) { + } + } + } + }; } diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 7292b86b9f42..9a0ebedde40c 100644 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -42,6 +42,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import static android.telephony.SmsMessage.MessageClass; @@ -781,7 +782,7 @@ public class SmsMessage extends SmsMessageBase { * binder-call, and hence should be thread-safe, it has been * synchronized. */ - private synchronized static int getNextMessageId() { + synchronized static int getNextMessageId() { // Testing and dialog with partners has indicated that // msgId==0 is (sometimes?) treated specially by lower levels. // Specifically, the ID is not preserved for delivery ACKs. @@ -997,7 +998,7 @@ public class SmsMessage extends SmsMessageBase { * Returns the list of service category program data, if present. * @return a list of CdmaSmsCbProgramData objects, or null if not present */ - List getSmsCbProgramData() { + ArrayList getSmsCbProgramData() { return mBearerData.serviceCategoryProgramData; } } diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java index 0f497625b8a2..5cacd23b8bf6 100755 --- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java @@ -18,9 +18,9 @@ package com.android.internal.telephony.cdma.sms; import android.content.res.Resources; import android.telephony.SmsCbCmasInfo; -import android.telephony.SmsCbMessage; import android.telephony.SmsMessage; import android.telephony.cdma.CdmaSmsCbProgramData; +import android.telephony.cdma.CdmaSmsCbProgramResults; import android.text.format.Time; import android.util.Log; @@ -32,8 +32,6 @@ import com.android.internal.util.BitwiseInputStream; import com.android.internal.util.BitwiseOutputStream; import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import java.util.TimeZone; import static android.telephony.SmsMessage.ENCODING_16BIT; @@ -353,7 +351,14 @@ public final class BearerData { * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects containing the * operation(s) to perform. */ - public List serviceCategoryProgramData; + public ArrayList serviceCategoryProgramData; + + /** + * The Service Category Program Results subparameter informs the message center + * of the results of a Service Category Program Data request. + */ + public ArrayList serviceCategoryProgramResults; + private static class CodingException extends Exception { public CodingException(String s) { @@ -857,6 +862,21 @@ public final class BearerData { outStream.skip(6); } + private static void encodeScpResults(BearerData bData, BitwiseOutputStream outStream) + throws BitwiseOutputStream.AccessException + { + ArrayList results = bData.serviceCategoryProgramResults; + outStream.write(8, (results.size() * 4)); // 4 octets per program result + for (CdmaSmsCbProgramResults result : results) { + int category = result.getCategory(); + outStream.write(8, category >> 8); + outStream.write(8, category); + outStream.write(8, result.getLanguage()); + outStream.write(4, result.getCategoryResult()); + outStream.skip(4); + } + } + /** * Create serialized representation for BearerData object. * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details) @@ -916,6 +936,10 @@ public final class BearerData { outStream.write(8, SUBPARAM_MESSAGE_STATUS); encodeMsgStatus(bData, outStream); } + if (bData.serviceCategoryProgramResults != null) { + outStream.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS); + encodeScpResults(bData, outStream); + } return outStream.toByteArray(); } catch (BitwiseOutputStream.AccessException ex) { Log.e(LOG_TAG, "BearerData encode failed: " + ex); @@ -1638,7 +1662,7 @@ public final class BearerData { while (paramBits >= CATEGORY_FIELD_MIN_SIZE) { int operation = inStream.read(4); int category = (inStream.read(8) << 8) | inStream.read(8); - String language = getLanguageCodeForValue(inStream.read(8)); + int language = inStream.read(8); int maxMessages = inStream.read(8); int alertOption = inStream.read(4); int numFields = inStream.read(8); diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java index d2facebffb6a..a95f60c75f1c 100644 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java +++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java @@ -635,7 +635,7 @@ public class CdmaSmsCbTest extends AndroidTestCase { assertEquals(CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY, programData.getOperation()); assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, programData.getCategory()); assertEquals(CAT_EXTREME_THREAT, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); + assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage()); assertEquals(100, programData.getMaxMessages()); assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT, programData.getAlertOption()); } @@ -692,7 +692,7 @@ public class CdmaSmsCbTest extends AndroidTestCase { assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation()); assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, programData.getCategory()); assertEquals(CAT_SEVERE_THREAT, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); + assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage()); assertEquals(0, programData.getMaxMessages()); assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption()); @@ -701,7 +701,7 @@ public class CdmaSmsCbTest extends AndroidTestCase { assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY, programData.getCategory()); assertEquals(CAT_AMBER_ALERTS, programData.getCategoryName()); - assertEquals("en", programData.getLanguageCode()); + assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage()); assertEquals(0, programData.getMaxMessages()); assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption()); } -- cgit v1.2.3 From 7728854613b8191ba3cbde44e01ad89ece0dc5b6 Mon Sep 17 00:00:00 2001 From: Daniel Sandler Date: Tue, 24 Jul 2012 15:19:04 -0400 Subject: Fix 6804479: "Emergency calls only" in notification shade Add an additional codepath to the "no connectivity" logic in NetworkController to allow the PLMN bubble up from the GsmServiceStateTracker, where R.string.emergency_calls_only is returned if we're in emergency call mode. Bug: 6804479 Change-Id: I0a77261e4393cc0dc32bae3e631ef196b2342f06 --- .../com/android/systemui/statusbar/policy/NetworkController.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 106826701348..230114ad341a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -932,10 +932,12 @@ public class NetworkController extends BroadcastReceiver { if (mDataConnected) { mobileLabel = mNetworkName; - } else if (mConnected) { - if (hasService()) { + } else if (mConnected || mServiceState.isEmergencyOnly()) { + if (hasService() || mServiceState.isEmergencyOnly()) { + // The isEmergencyOnly test covers the case of a phone with no SIM mobileLabel = mNetworkName; } else { + // Tablets, basically mobileLabel = ""; } } else { -- cgit v1.2.3 From 4df2c7fa44a71f351ac9aab5eb9c6909d76e9419 Mon Sep 17 00:00:00 2001 From: Daniel Sandler Date: Wed, 25 Jul 2012 12:31:22 -0400 Subject: Fix NPE on some phones at startup. Bug: 6877589 Change-Id: I65ff37b4cf6b59a72a7aa665f252f5fb34f3b183 --- .../src/com/android/systemui/statusbar/policy/NetworkController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 230114ad341a..e3f2ca4e63f2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -917,6 +917,7 @@ public class NetworkController extends BroadcastReceiver { String wifiLabel = ""; String mobileLabel = ""; int N; + final boolean emergencyOnly = (mServiceState != null && mServiceState.isEmergencyOnly()); if (!mHasMobileDataFeature) { mDataSignalIconId = mPhoneSignalIconId = 0; @@ -932,8 +933,8 @@ public class NetworkController extends BroadcastReceiver { if (mDataConnected) { mobileLabel = mNetworkName; - } else if (mConnected || mServiceState.isEmergencyOnly()) { - if (hasService() || mServiceState.isEmergencyOnly()) { + } else if (mConnected || emergencyOnly) { + if (hasService() || emergencyOnly) { // The isEmergencyOnly test covers the case of a phone with no SIM mobileLabel = mNetworkName; } else { -- cgit v1.2.3 From f959d1084eae42af1403d9c3f423143869a2f6cb Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Thu, 2 Aug 2012 16:06:56 -0700 Subject: Fix a logging NPE problem bug:6864064 Change-Id: I3237e55cb164462b9616515b0de009bf687f1dca --- .../com/android/internal/telephony/cdma/CdmaServiceStateTracker.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index 25cd1126ec19..564ce3bd8cd0 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -1378,7 +1378,8 @@ public class CdmaServiceStateTracker extends ServiceStateTracker { mZoneTime = c.getTimeInMillis(); } if (DBG) { - log("NITZ: tzOffset=" + tzOffset + " dst=" + dst + " zone=" + zone.getID() + + log("NITZ: tzOffset=" + tzOffset + " dst=" + dst + " zone=" + + (zone!=null ? zone.getID() : "NULL") + " iso=" + iso + " mGotCountryCode=" + mGotCountryCode + " mNeedFixZone=" + mNeedFixZone); } -- cgit v1.2.3 From b046b20f1a5406ddda60c548036ed9e887da49df Mon Sep 17 00:00:00 2001 From: Madan Ankapura Date: Thu, 2 Aug 2012 19:10:22 -0700 Subject: show 3G icon for CDMA/1xRTT when config_showMin3G is enabled to true in a CDMA device Change-Id: I79a4fa200dc406fc7f9f4527165046541961ef69 Signed-off-by: Madan Ankapura --- .../statusbar/policy/NetworkController.java | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index e3f2ca4e63f2..89f4625c5f6f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -566,18 +566,26 @@ public class NetworkController extends BroadcastReceiver { } break; case TelephonyManager.NETWORK_TYPE_CDMA: - // display 1xRTT for IS95A/B - mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; - mDataTypeIconId = R.drawable.stat_sys_data_connected_1x; - mContentDescriptionDataType = mContext.getString( - R.string.accessibility_data_connection_cdma); - break; + if (!mShowAtLeastThreeGees) { + // display 1xRTT for IS95A/B + mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; + mDataTypeIconId = R.drawable.stat_sys_data_connected_1x; + mContentDescriptionDataType = mContext.getString( + R.string.accessibility_data_connection_cdma); + break; + } else { + // fall through + } case TelephonyManager.NETWORK_TYPE_1xRTT: - mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; - mDataTypeIconId = R.drawable.stat_sys_data_connected_1x; - mContentDescriptionDataType = mContext.getString( - R.string.accessibility_data_connection_cdma); - break; + if (!mShowAtLeastThreeGees) { + mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; + mDataTypeIconId = R.drawable.stat_sys_data_connected_1x; + mContentDescriptionDataType = mContext.getString( + R.string.accessibility_data_connection_cdma); + break; + } else { + // fall through + } case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through case TelephonyManager.NETWORK_TYPE_EVDO_A: case TelephonyManager.NETWORK_TYPE_EVDO_B: -- cgit v1.2.3