Merge "Telephony: Check SmsTracker's mSentIntent for null"
Jake Hamby [Wed, 9 Jan 2013 22:17:58 +0000 (14:17 -0800)]
161 files changed:
Android.mk
CleanSpec.mk
mockril/Android.mk
mockril/src/com/android/internal/telephony/mockril/MockRilController.java
src/java/android/provider/Telephony.java
src/java/android/telephony/SmsCbEtwsInfo.java
src/java/android/telephony/SmsManager.java
src/java/android/telephony/SmsMessage.java
src/java/com/android/internal/telephony/ApnContext.java
src/java/com/android/internal/telephony/BaseCommands.java
src/java/com/android/internal/telephony/Call.java
src/java/com/android/internal/telephony/CallManager.java
src/java/com/android/internal/telephony/CallTracker.java
src/java/com/android/internal/telephony/CommandException.java
src/java/com/android/internal/telephony/CommandsInterface.java
src/java/com/android/internal/telephony/Connection.java
src/java/com/android/internal/telephony/DataCallState.java
src/java/com/android/internal/telephony/DataConnectionAc.java
src/java/com/android/internal/telephony/DataConnectionTracker.java
src/java/com/android/internal/telephony/DebugService.java
src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
src/java/com/android/internal/telephony/DriverCall.java
src/java/com/android/internal/telephony/EventLogTags.logtags
src/java/com/android/internal/telephony/IIccPhoneBook.aidl
src/java/com/android/internal/telephony/ISms.aidl
src/java/com/android/internal/telephony/IccCard.java
src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
src/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java
src/java/com/android/internal/telephony/IccProvider.java
src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
src/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
src/java/com/android/internal/telephony/IccUtils.java
src/java/com/android/internal/telephony/MccTable.java
src/java/com/android/internal/telephony/Phone.java
src/java/com/android/internal/telephony/PhoneBase.java
src/java/com/android/internal/telephony/PhoneFactory.java
src/java/com/android/internal/telephony/PhoneNotifier.java
src/java/com/android/internal/telephony/PhoneProxy.java
src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
src/java/com/android/internal/telephony/PhoneSubInfo.java
src/java/com/android/internal/telephony/RIL.java
src/java/com/android/internal/telephony/RetryManager.java
src/java/com/android/internal/telephony/SMSDispatcher.java
src/java/com/android/internal/telephony/ServiceStateTracker.java
src/java/com/android/internal/telephony/SmsStorageMonitor.java
src/java/com/android/internal/telephony/SmsUsageMonitor.java
src/java/com/android/internal/telephony/TelephonyCapabilities.java
src/java/com/android/internal/telephony/WapPushOverSms.java
src/java/com/android/internal/telephony/WspTypeDecoder.java
src/java/com/android/internal/telephony/cat/AppInterface.java
src/java/com/android/internal/telephony/cat/CatCmdMessage.java
src/java/com/android/internal/telephony/cat/CatLog.java
src/java/com/android/internal/telephony/cat/CatResponseMessage.java
src/java/com/android/internal/telephony/cat/CatService.java
src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
src/java/com/android/internal/telephony/cat/IconLoader.java
src/java/com/android/internal/telephony/cat/ResponseData.java
src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
src/java/com/android/internal/telephony/cat/ValueParser.java
src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
src/java/com/android/internal/telephony/cdma/CDMAPhone.java
src/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
src/java/com/android/internal/telephony/cdma/CdmaConnection.java
src/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
src/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
src/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java [deleted file]
src/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java [deleted file]
src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
src/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
src/java/com/android/internal/telephony/cdma/EriManager.java
src/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
src/java/com/android/internal/telephony/cdma/RuimRecords.java [deleted file]
src/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
src/java/com/android/internal/telephony/cdma/SignalToneUtil.java
src/java/com/android/internal/telephony/cdma/SmsMessage.java
src/java/com/android/internal/telephony/cdma/sms/BearerData.java [changed mode: 0755->0644]
src/java/com/android/internal/telephony/gsm/GSMPhone.java
src/java/com/android/internal/telephony/gsm/GsmCallTracker.java
src/java/com/android/internal/telephony/gsm/GsmConnection.java
src/java/com/android/internal/telephony/gsm/GsmDataConnection.java
src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
src/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
src/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
src/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
src/java/com/android/internal/telephony/gsm/SmsCbHeader.java
src/java/com/android/internal/telephony/gsm/SmsMessage.java
src/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java
src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
src/java/com/android/internal/telephony/ims/IsimUiccRecords.java [deleted file]
src/java/com/android/internal/telephony/sip/SipConnectionBase.java
src/java/com/android/internal/telephony/sip/SipPhone.java
src/java/com/android/internal/telephony/sip/SipPhoneBase.java
src/java/com/android/internal/telephony/sip/SipPhoneFactory.java
src/java/com/android/internal/telephony/test/ModelInterpreter.java
src/java/com/android/internal/telephony/test/SimulatedCommands.java
src/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
src/java/com/android/internal/telephony/uicc/AdnRecord.aidl [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/AdnRecord.java [moved from src/java/com/android/internal/telephony/AdnRecord.java with 96% similarity]
src/java/com/android/internal/telephony/uicc/AdnRecordCache.java [moved from src/java/com/android/internal/telephony/AdnRecordCache.java with 98% similarity]
src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java [moved from src/java/com/android/internal/telephony/AdnRecordLoader.java with 97% similarity]
src/java/com/android/internal/telephony/uicc/CsimFileHandler.java [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java [moved from src/java/com/android/internal/telephony/IccCardApplication.java with 95% similarity]
src/java/com/android/internal/telephony/uicc/IccCardProxy.java [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/IccCardStatus.java [moved from src/java/com/android/internal/telephony/IccCardStatus.java with 63% similarity]
src/java/com/android/internal/telephony/uicc/IccConstants.java [moved from src/java/com/android/internal/telephony/IccConstants.java with 95% similarity]
src/java/com/android/internal/telephony/uicc/IccException.java [moved from src/java/com/android/internal/telephony/IccException.java with 94% similarity]
src/java/com/android/internal/telephony/uicc/IccFileHandler.java [moved from src/java/com/android/internal/telephony/IccFileHandler.java with 83% similarity]
src/java/com/android/internal/telephony/uicc/IccFileNotFound.java [moved from src/java/com/android/internal/telephony/IccFileNotFound.java with 95% similarity]
src/java/com/android/internal/telephony/uicc/IccFileTypeMismatch.java [moved from src/java/com/android/internal/telephony/IccFileTypeMismatch.java with 94% similarity]
src/java/com/android/internal/telephony/uicc/IccIoResult.java [moved from src/java/com/android/internal/telephony/IccIoResult.java with 97% similarity]
src/java/com/android/internal/telephony/uicc/IccRecords.java [moved from src/java/com/android/internal/telephony/IccRecords.java with 75% similarity]
src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java [moved from src/java/com/android/internal/telephony/IccRefreshResponse.java with 97% similarity]
src/java/com/android/internal/telephony/uicc/IccServiceTable.java [moved from src/java/com/android/internal/telephony/IccServiceTable.java with 93% similarity]
src/java/com/android/internal/telephony/uicc/IccUtils.java [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/IccVmFixedException.java [moved from src/java/com/android/internal/telephony/IccVmFixedException.java with 94% similarity]
src/java/com/android/internal/telephony/uicc/IccVmNotSupportedException.java [moved from src/java/com/android/internal/telephony/IccVmNotSupportedException.java with 94% similarity]
src/java/com/android/internal/telephony/uicc/IsimFileHandler.java [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/IsimRecords.java [moved from src/java/com/android/internal/telephony/ims/IsimRecords.java with 97% similarity]
src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/README [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/RuimFileHandler.java [moved from src/java/com/android/internal/telephony/cdma/RuimFileHandler.java with 63% similarity]
src/java/com/android/internal/telephony/uicc/RuimRecords.java [new file with mode: 0755]
src/java/com/android/internal/telephony/uicc/SIMFileHandler.java [copied from src/java/com/android/internal/telephony/gsm/SIMFileHandler.java with 59% similarity]
src/java/com/android/internal/telephony/uicc/SIMRecords.java [moved from src/java/com/android/internal/telephony/gsm/SIMRecords.java with 91% similarity]
src/java/com/android/internal/telephony/uicc/SpnOverride.java [moved from src/java/com/android/internal/telephony/gsm/SpnOverride.java with 91% similarity]
src/java/com/android/internal/telephony/uicc/UiccCard.java [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/UiccCardApplication.java [new file with mode: 0644]
src/java/com/android/internal/telephony/uicc/UiccController.java
src/java/com/android/internal/telephony/uicc/UsimFileHandler.java [moved from src/java/com/android/internal/telephony/gsm/SIMFileHandler.java with 52% similarity]
src/java/com/android/internal/telephony/uicc/UsimServiceTable.java [moved from src/java/com/android/internal/telephony/gsm/UsimServiceTable.java with 97% similarity]
src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java [moved from src/java/com/android/internal/telephony/gsm/VoiceMailConstants.java with 88% similarity]
tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java
tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java
tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java
tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java
tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java
tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java
tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java
tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java
tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java
tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java
tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java
tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java
tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java
tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java
tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java

index 2487766..9c43ee3 100644 (file)
@@ -16,12 +16,10 @@ LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := \
-       src/java/com/android/internal/telephony/ISms.aidl \
-    src/java/com/android/internal/telephony/IIccPhoneBook.aidl \
-    src/java/com/android/internal/telephony/EventLogTags.logtags \
-
-LOCAL_SRC_FILES += $(call all-java-files-under, src/java)
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src/java
+LOCAL_SRC_FILES := $(call all-java-files-under, src/java) \
+       $(call all-Iaidl-files-under, src/java) \
+       $(call all-logtags-files-under, src/java)
 
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := telephony-common
index 9a63705..f4475ef 100644 (file)
@@ -39,6 +39,8 @@
 # ************************************************
 
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
index 95ae84c..3778a58 100644 (file)
@@ -14,6 +14,7 @@
 # limitations under the License.
 #
 #
+ifneq ($(TARGET_BUILD_PDK),true)
 
 LOCAL_PATH:=$(call my-dir)
 
@@ -28,3 +29,5 @@ LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java
 LOCAL_MODULE := mockrilcontroller
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
+
+endif # !PDK
\ No newline at end of file
index 0e75c72..aef9fb5 100644 (file)
@@ -17,7 +17,7 @@
 package com.android.internal.telephony.mockril;
 
 import android.os.Bundle;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.communication.MsgHeader;
 import com.android.internal.communication.Msg;
@@ -62,7 +62,7 @@ public class MockRilController {
         try {
             Msg.send(mRilChannel, cmd, token, status, pbData);
         } catch (IOException e) {
-            Log.v(TAG, "send command : %d failed: " + e.getStackTrace());
+            Rlog.v(TAG, "send command : %d failed: " + e.getStackTrace());
             return false;
         }
         return true;
@@ -77,7 +77,7 @@ public class MockRilController {
         try {
             response = Msg.recv(mRilChannel);
         } catch (IOException e) {
-            Log.v(TAG, "receive response for getRadioState() error: " + e.getStackTrace());
+            Rlog.v(TAG, "receive response for getRadioState() error: " + e.getStackTrace());
             return null;
         }
         return response;
@@ -92,7 +92,7 @@ public class MockRilController {
         }
         Msg response = getCtrlResponse();
         if (response == null) {
-            Log.v(TAG, "failed to get response");
+            Rlog.v(TAG, "failed to get response");
             return -1;
         }
         response.printHeader(TAG);
@@ -113,17 +113,17 @@ public class MockRilController {
     public boolean setRadioState(int state) {
         RilCtrlCmds.CtrlReqRadioState req = new RilCtrlCmds.CtrlReqRadioState();
         if (state < 0 || state > RilCmds.RADIOSTATE_NV_READY) {
-            Log.v(TAG, "the give radio state is not valid.");
+            Rlog.v(TAG, "the give radio state is not valid.");
             return false;
         }
         req.setState(state);
         if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, req)) {
-            Log.v(TAG, "send set radio state request failed.");
+            Rlog.v(TAG, "send set radio state request failed.");
             return false;
         }
         Msg response = getCtrlResponse();
         if (response == null) {
-            Log.v(TAG, "failed to get response for setRadioState");
+            Rlog.v(TAG, "failed to get response for setRadioState");
             return false;
         }
         response.printHeader(TAG);
@@ -144,7 +144,7 @@ public class MockRilController {
 
         req.setPhoneNumber(phoneNumber);
         if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, req)) {
-            Log.v(TAG, "send CMD_SET_MT_CALL request failed");
+            Rlog.v(TAG, "send CMD_SET_MT_CALL request failed");
             return false;
         }
         return true;
@@ -163,7 +163,7 @@ public class MockRilController {
         req.setCallFailCause(failCause);
 
         if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, req)) {
-            Log.v(TAG, "send CTRL_CMD_HANGUP_CONN_REMOTE request failed");
+            Rlog.v(TAG, "send CTRL_CMD_HANGUP_CONN_REMOTE request failed");
             return false;
         }
         return true;
@@ -183,7 +183,7 @@ public class MockRilController {
         req.setFlag(flag);
 
         if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, req)) {
-            Log.v(TAG, "send CTRL_CMD_SET_CALL_TRANSITION_FLAG request failed");
+            Rlog.v(TAG, "send CTRL_CMD_SET_CALL_TRANSITION_FLAG request failed");
             return false;
         }
         return true;
@@ -196,7 +196,7 @@ public class MockRilController {
      */
     public boolean setDialCallToAlert() {
         if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null)) {
-            Log.v(TAG, "send CTRL_CMD_SET_CALL_ALERT request failed");
+            Rlog.v(TAG, "send CTRL_CMD_SET_CALL_ALERT request failed");
             return false;
         }
         return true;
@@ -209,7 +209,7 @@ public class MockRilController {
     */
    public boolean setAlertCallToActive() {
         if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null)) {
-            Log.v(TAG, "send CTRL_CMD_SET_CALL_ACTIVE request failed");
+            Rlog.v(TAG, "send CTRL_CMD_SET_CALL_ACTIVE request failed");
             return false;
         }
         return true;
index dd8be66..50f3203 100644 (file)
@@ -28,7 +28,7 @@ import android.net.Uri;
 import android.os.Environment;
 import android.telephony.SmsMessage;
 import android.text.TextUtils;
-import android.util.Log;
+import android.telephony.Rlog;
 import android.util.Patterns;
 
 
@@ -746,6 +746,12 @@ public final class Telephony {
         public static final String SEEN = "seen";
 
         /**
+         * Indicates whether this message has only a text part (can also have a subject) and
+         * no picture, slideshow, or sound, etc., parts. The value is a boolean, 1 or 0.
+         */
+        public static final String TEXT_ONLY = "text_only";
+
+        /**
          * The Message-ID of the message.
          * <P>Type: TEXT</P>
          */
@@ -1287,7 +1293,7 @@ public final class Telephony {
             }
 
             Uri uri = uriBuilder.build();
-            //if (DEBUG) Log.v(TAG, "getOrCreateThreadId uri: " + uri);
+            //if (DEBUG) Rlog.v(TAG, "getOrCreateThreadId uri: " + uri);
 
             Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
                     uri, ID_PROJECTION, null, null, null);
@@ -1296,14 +1302,14 @@ public final class Telephony {
                     if (cursor.moveToFirst()) {
                         return cursor.getLong(0);
                     } else {
-                        Log.e(TAG, "getOrCreateThreadId returned no rows!");
+                        Rlog.e(TAG, "getOrCreateThreadId returned no rows!");
                     }
                 } finally {
                     cursor.close();
                 }
             }
 
-            Log.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString());
+            Rlog.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString());
             throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
         }
     }
index 0890d52..f208fbf 100644 (file)
@@ -20,7 +20,7 @@ import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.format.Time;
 
-import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.uicc.IccUtils;
 
 import java.util.Arrays;
 
index 44bdaeb..da9d7e7 100644 (file)
@@ -22,8 +22,8 @@ import android.os.ServiceManager;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.ISms;
-import com.android.internal.telephony.IccConstants;
 import com.android.internal.telephony.SmsRawData;
+import com.android.internal.telephony.uicc.IccConstants;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -98,8 +98,13 @@ public final class SmsManager {
      * @param text the original message.  Must not be null.
      * @return an <code>ArrayList</code> of strings that, in order,
      *   comprise the original message
+     *
+     * @throws IllegalArgumentException if text is null
      */
     public ArrayList<String> divideMessage(String text) {
+        if (null == text) {
+            throw new IllegalArgumentException("text is null");
+        }
         return SmsMessage.fragmentText(text);
     }
 
@@ -242,11 +247,15 @@ public final class SmsManager {
      *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
      * @return true for success
      *
+     * @throws IllegalArgumentException if pdu is NULL
      * {@hide}
      */
     public boolean copyMessageToIcc(byte[] smsc, byte[] pdu, int status) {
         boolean success = false;
 
+        if (null == pdu) {
+            throw new IllegalArgumentException("pdu is NULL");
+        }
         try {
             ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
             if (iccISms != null) {
@@ -414,11 +423,15 @@ public final class SmsManager {
      * @return true if successful, false otherwise
      * @see #disableCellBroadcastRange(int, int)
      *
+     * @throws IllegalArgumentException if endMessageId < startMessageId
      * {@hide}
      */
     public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
         boolean success = false;
 
+        if (endMessageId < startMessageId) {
+            throw new IllegalArgumentException("endMessageId < startMessageId");
+        }
         try {
             ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
             if (iccISms != null) {
@@ -445,11 +458,15 @@ public final class SmsManager {
      *
      * @see #enableCellBroadcastRange(int, int)
      *
+     * @throws IllegalArgumentException if endMessageId < startMessageId
      * {@hide}
      */
     public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
         boolean success = false;
 
+        if (endMessageId < startMessageId) {
+            throw new IllegalArgumentException("endMessageId < startMessageId");
+        }
         try {
             ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
             if (iccISms != null) {
index b94609e..c35f09e 100644 (file)
@@ -17,7 +17,7 @@
 package android.telephony;
 
 import android.os.Parcel;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
@@ -158,7 +158,7 @@ public class SmsMessage {
         } else if (SmsConstants.FORMAT_3GPP.equals(format)) {
             wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
         } else {
-            Log.e(LOG_TAG, "createFromPdu(): unsupported message format " + format);
+            Rlog.e(LOG_TAG, "createFromPdu(): unsupported message format " + format);
             return null;
         }
 
@@ -337,7 +337,7 @@ public class SmsMessage {
                 nextPos = pos + Math.min(limit / 2, textLen - pos);
             }
             if ((nextPos <= pos) || (nextPos > textLen)) {
-                Log.e(LOG_TAG, "fragmentText failed (" + pos + " >= " + nextPos + " or " +
+                Rlog.e(LOG_TAG, "fragmentText failed (" + pos + " >= " + nextPos + " or " +
                           nextPos + " >= " + textLen + ")");
                 break;
             }
index 4817a7b..b6083ad 100644 (file)
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.util.Log;
+import android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -237,7 +237,7 @@ public class ApnContext {
     }
 
     protected void log(String s) {
-        Log.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
+        Rlog.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
index 1b54656..49d3c76 100644 (file)
@@ -24,7 +24,7 @@ import android.os.Handler;
 import android.os.AsyncResult;
 import android.os.SystemProperties;
 import android.telephony.TelephonyManager;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -555,11 +555,11 @@ public abstract class BaseCommands implements CommandsInterface {
      */
     @Override
     public void registerForRilConnected(Handler h, int what, Object obj) {
-        Log.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what);
+        Rlog.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what);
         Registrant r = new Registrant (h, what, obj);
         mRilConnectedRegistrants.add(r);
         if (mRilVersion != -1) {
-            Log.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion);
+            Rlog.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion);
             r.notifyRegistrant(new AsyncResult(null, new Integer(mRilVersion), null));
         }
     }
@@ -592,7 +592,7 @@ public abstract class BaseCommands implements CommandsInterface {
 
         synchronized (mStateMonitor) {
             if (false) {
-                Log.v(LOG_TAG, "setRadioState old: " + mState
+                Rlog.v(LOG_TAG, "setRadioState old: " + mState
                     + " new " + newState);
             }
 
@@ -607,25 +607,25 @@ public abstract class BaseCommands implements CommandsInterface {
             mRadioStateChangedRegistrants.notifyRegistrants();
 
             if (mState.isAvailable() && !oldState.isAvailable()) {
-                Log.d(LOG_TAG,"Notifying: radio available");
+                Rlog.d(LOG_TAG,"Notifying: radio available");
                 mAvailRegistrants.notifyRegistrants();
                 onRadioAvailable();
             }
 
             if (!mState.isAvailable() && oldState.isAvailable()) {
-                Log.d(LOG_TAG,"Notifying: radio not available");
+                Rlog.d(LOG_TAG,"Notifying: radio not available");
                 mNotAvailRegistrants.notifyRegistrants();
             }
 
             if (mState.isOn() && !oldState.isOn()) {
-                Log.d(LOG_TAG,"Notifying: Radio On");
+                Rlog.d(LOG_TAG,"Notifying: Radio On");
                 mOnRegistrants.notifyRegistrants();
             }
 
             if ((!mState.isOn() || !mState.isAvailable())
                 && !((!oldState.isOn() || !oldState.isAvailable()))
             ) {
-                Log.d(LOG_TAG,"Notifying: radio off or not available");
+                Rlog.d(LOG_TAG,"Notifying: radio off or not available");
                 mOffOrNotAvailRegistrants.notifyRegistrants();
             }
         }
index 4967ab8..2127258 100644 (file)
@@ -18,7 +18,7 @@ package com.android.internal.telephony;
 
 import java.util.List;
 
-import android.util.Log;
+import android.telephony.Rlog;
 
 /**
  * {@hide}
@@ -248,7 +248,7 @@ public abstract class Call {
             try {
                 hangup();
             } catch (CallStateException ex) {
-                Log.w(LOG_TAG, " hangupIfActive: caught " + ex);
+                Rlog.w(LOG_TAG, " hangupIfActive: caught " + ex);
             }
         }
     }
index b87ea50..1c1799f 100644 (file)
@@ -27,7 +27,7 @@ import android.os.RegistrantList;
 import android.os.Registrant;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -100,6 +100,8 @@ public final class CallManager {
     // default phone as the first phone registered, which is PhoneBase obj
     private Phone mDefaultPhone;
 
+    private boolean mSpeedUpAudioForMtCall = false;
+
     // state registrants
     protected final RegistrantList mPreciseCallStateRegistrants
     = new RegistrantList();
@@ -293,7 +295,7 @@ public final class CallManager {
         if (basePhone != null && !mPhones.contains(basePhone)) {
 
             if (DBG) {
-                Log.d(LOG_TAG, "registerPhone(" +
+                Rlog.d(LOG_TAG, "registerPhone(" +
                         phone.getPhoneName() + " " + phone + ")");
             }
 
@@ -320,7 +322,7 @@ public final class CallManager {
         if (basePhone != null && mPhones.contains(basePhone)) {
 
             if (DBG) {
-                Log.d(LOG_TAG, "unregisterPhone(" +
+                Rlog.d(LOG_TAG, "unregisterPhone(" +
                         phone.getPhoneName() + " " + phone + ")");
             }
 
@@ -377,14 +379,21 @@ public final class CallManager {
         // but only on audio mode transitions
         switch (getState()) {
             case RINGING:
-                if (audioManager.getMode() != AudioManager.MODE_RINGTONE) {
+                int curAudioMode = audioManager.getMode();
+                if (curAudioMode != AudioManager.MODE_RINGTONE) {
                     // only request audio focus if the ringtone is going to be heard
                     if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
-                        if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
+                        if (VDBG) Rlog.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
                         audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
                                 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                     }
-                    audioManager.setMode(AudioManager.MODE_RINGTONE);
+                    if(!mSpeedUpAudioForMtCall) {
+                        audioManager.setMode(AudioManager.MODE_RINGTONE);
+                    }
+                }
+
+                if (mSpeedUpAudioForMtCall && (curAudioMode != AudioManager.MODE_IN_CALL)) {
+                    audioManager.setMode(AudioManager.MODE_IN_CALL);
                 }
                 break;
             case OFFHOOK:
@@ -400,21 +409,23 @@ public final class CallManager {
                     // enable IN_COMMUNICATION audio mode instead for sipPhone
                     newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
                 }
-                if (audioManager.getMode() != newAudioMode) {
+                if (audioManager.getMode() != newAudioMode || mSpeedUpAudioForMtCall) {
                     // request audio focus before setting the new mode
-                    if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
+                    if (VDBG) Rlog.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
                     audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
                             AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                     audioManager.setMode(newAudioMode);
                 }
+                mSpeedUpAudioForMtCall = false;
                 break;
             case IDLE:
                 if (audioManager.getMode() != AudioManager.MODE_NORMAL) {
                     audioManager.setMode(AudioManager.MODE_NORMAL);
-                    if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus");
+                    if (VDBG) Rlog.d(LOG_TAG, "abandonAudioFocus");
                     // abandon audio focus after the mode has been set back to normal
                     audioManager.abandonAudioFocusForCall();
                 }
+                mSpeedUpAudioForMtCall = false;
                 break;
         }
     }
@@ -507,8 +518,8 @@ public final class CallManager {
         Phone ringingPhone = ringingCall.getPhone();
 
         if (VDBG) {
-            Log.d(LOG_TAG, "acceptCall(" +ringingCall + " from " + ringingCall.getPhone() + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "acceptCall(" +ringingCall + " from " + ringingCall.getPhone() + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if ( hasActiveFgCall() ) {
@@ -517,7 +528,7 @@ public final class CallManager {
             boolean sameChannel = (activePhone == ringingPhone);
 
             if (VDBG) {
-                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel);
+                Rlog.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel);
             }
 
             if (sameChannel && hasBgCall) {
@@ -529,11 +540,28 @@ public final class CallManager {
             }
         }
 
+        Context context = getContext();
+        if (context == null) {
+            Rlog.d(LOG_TAG, "Speedup Audio Path enhancement: Context is null");
+        } else if (context.getResources().getBoolean(
+                com.android.internal.R.bool.config_speed_up_audio_on_mt_calls)) {
+            Rlog.d(LOG_TAG, "Speedup Audio Path enhancement");
+            AudioManager audioManager = (AudioManager)
+                    context.getSystemService(Context.AUDIO_SERVICE);
+            int currMode = audioManager.getMode();
+            if ((currMode != AudioManager.MODE_IN_CALL) && !(ringingPhone instanceof SipPhone)) {
+                Rlog.d(LOG_TAG, "setAudioMode Setting audio mode from " +
+                                currMode + " to " + AudioManager.MODE_IN_CALL);
+                audioManager.setMode(AudioManager.MODE_IN_CALL);
+                mSpeedUpAudioForMtCall = true;
+            }
+        }
+
         ringingPhone.acceptCall();
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End acceptCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End acceptCall(" +ringingCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
     }
 
@@ -548,8 +576,8 @@ public final class CallManager {
      */
     public void rejectCall(Call ringingCall) throws CallStateException {
         if (VDBG) {
-            Log.d(LOG_TAG, "rejectCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "rejectCall(" +ringingCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         Phone ringingPhone = ringingCall.getPhone();
@@ -557,8 +585,8 @@ public final class CallManager {
         ringingPhone.rejectCall();
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End rejectCall(" +ringingCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End rejectCall(" +ringingCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
     }
 
@@ -585,8 +613,8 @@ public final class CallManager {
         Phone heldPhone = null;
 
         if (VDBG) {
-            Log.d(LOG_TAG, "switchHoldingAndActive(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "switchHoldingAndActive(" +heldCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (hasActiveFgCall()) {
@@ -606,8 +634,8 @@ public final class CallManager {
         }
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End switchHoldingAndActive(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End switchHoldingAndActive(" +heldCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
     }
 
@@ -624,8 +652,8 @@ public final class CallManager {
         Phone backgroundPhone = null;
 
         if (VDBG) {
-            Log.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (hasActiveFgCall()) {
@@ -643,8 +671,8 @@ public final class CallManager {
         }
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
     }
 
@@ -680,8 +708,8 @@ public final class CallManager {
     public void conference(Call heldCall) throws CallStateException {
 
         if (VDBG) {
-            Log.d(LOG_TAG, "conference(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "conference(" +heldCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
 
@@ -695,8 +723,8 @@ public final class CallManager {
         }
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End conference(" +heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End conference(" +heldCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
     }
@@ -716,8 +744,8 @@ public final class CallManager {
         Connection result;
 
         if (VDBG) {
-            Log.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (!canDial(phone)) {
@@ -729,15 +757,15 @@ public final class CallManager {
             boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle());
 
             if (DBG) {
-                Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone));
+                Rlog.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone));
             }
 
             if (activePhone != basePhone) {
                 if (hasBgCall) {
-                    Log.d(LOG_TAG, "Hangup");
+                    Rlog.d(LOG_TAG, "Hangup");
                     getActiveFgCall().hangup();
                 } else {
-                    Log.d(LOG_TAG, "Switch");
+                    Rlog.d(LOG_TAG, "Switch");
                     activePhone.switchHoldingAndActive();
                 }
             }
@@ -746,8 +774,8 @@ public final class CallManager {
         result = basePhone.dial(dialString);
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         return result;
@@ -802,7 +830,7 @@ public final class CallManager {
                     || (fgCallState == Call.State.DISCONNECTED)));
 
         if (result == false) {
-            Log.d(LOG_TAG, "canDial serviceState=" + serviceState
+            Rlog.d(LOG_TAG, "canDial serviceState=" + serviceState
                             + " hasRingingCall=" + hasRingingCall
                             + " hasActiveCall=" + hasActiveCall
                             + " hasHoldingCall=" + hasHoldingCall
@@ -846,8 +874,8 @@ public final class CallManager {
      */
     public void explicitCallTransfer(Call heldCall) throws CallStateException {
         if (VDBG) {
-            Log.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (canTransfer(heldCall)) {
@@ -855,8 +883,8 @@ public final class CallManager {
         }
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
     }
@@ -871,7 +899,7 @@ public final class CallManager {
      * @return null if phone doesn't have or support mmi code
      */
     public List<? extends MmiCode> getPendingMmiCodes(Phone phone) {
-        Log.e(LOG_TAG, "getPendingMmiCodes not implemented");
+        Rlog.e(LOG_TAG, "getPendingMmiCodes not implemented");
         return null;
     }
 
@@ -884,7 +912,7 @@ public final class CallManager {
      * @return false if phone doesn't support ussd service
      */
     public boolean sendUssdResponse(Phone phone, String ussdMessge) {
-        Log.e(LOG_TAG, "sendUssdResponse not implemented");
+        Rlog.e(LOG_TAG, "sendUssdResponse not implemented");
         return false;
     }
 
@@ -899,8 +927,8 @@ public final class CallManager {
 
     public void setMute(boolean muted) {
         if (VDBG) {
-            Log.d(LOG_TAG, " setMute(" + muted + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, " setMute(" + muted + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (hasActiveFgCall()) {
@@ -908,8 +936,8 @@ public final class CallManager {
         }
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End setMute(" + muted + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End setMute(" + muted + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
     }
 
@@ -936,8 +964,8 @@ public final class CallManager {
      */
     public void setEchoSuppressionEnabled(boolean enabled) {
         if (VDBG) {
-            Log.d(LOG_TAG, " setEchoSuppression(" + enabled + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, " setEchoSuppression(" + enabled + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (hasActiveFgCall()) {
@@ -945,8 +973,8 @@ public final class CallManager {
         }
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
     }
 
@@ -962,8 +990,8 @@ public final class CallManager {
         boolean result = false;
 
         if (VDBG) {
-            Log.d(LOG_TAG, " sendDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, " sendDtmf(" + c + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (hasActiveFgCall()) {
@@ -972,8 +1000,8 @@ public final class CallManager {
         }
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End sendDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End sendDtmf(" + c + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
         return result;
     }
@@ -991,8 +1019,8 @@ public final class CallManager {
         boolean result = false;
 
         if (VDBG) {
-            Log.d(LOG_TAG, " startDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, " startDtmf(" + c + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (hasActiveFgCall()) {
@@ -1001,8 +1029,8 @@ public final class CallManager {
         }
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End startDtmf(" + c + ")");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End startDtmf(" + c + ")");
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         return result;
@@ -1014,15 +1042,15 @@ public final class CallManager {
      */
     public void stopDtmf() {
         if (VDBG) {
-            Log.d(LOG_TAG, " stopDtmf()" );
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, " stopDtmf()" );
+            Rlog.d(LOG_TAG, this.toString());
         }
 
         if (hasActiveFgCall()) getFgPhone().stopDtmf();
 
         if (VDBG) {
-            Log.d(LOG_TAG, "End stopDtmf()");
-            Log.d(LOG_TAG, this.toString());
+            Rlog.d(LOG_TAG, "End stopDtmf()");
+            Rlog.d(LOG_TAG, this.toString());
         }
     }
 
@@ -1714,98 +1742,98 @@ public final class CallManager {
 
             switch (msg.what) {
                 case EVENT_DISCONNECT:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)");
                     mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_PRECISE_CALL_STATE_CHANGED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)");
                     mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_NEW_RINGING_CONNECTION:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)");
                     if (getActiveFgCallState().isDialing() || hasMoreThanOneRingingCall()) {
                         Connection c = (Connection) ((AsyncResult) msg.obj).result;
                         try {
-                            Log.d(LOG_TAG, "silently drop incoming call: " + c.getCall());
+                            Rlog.d(LOG_TAG, "silently drop incoming call: " + c.getCall());
                             c.getCall().hangup();
                         } catch (CallStateException e) {
-                            Log.w(LOG_TAG, "new ringing connection", e);
+                            Rlog.w(LOG_TAG, "new ringing connection", e);
                         }
                     } else {
                         mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     }
                     break;
                 case EVENT_UNKNOWN_CONNECTION:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)");
                     mUnknownConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_INCOMING_RING:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)");
                     // The event may come from RIL who's not aware of an ongoing fg call
                     if (!hasActiveFgCall()) {
                         mIncomingRingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     }
                     break;
                 case EVENT_RINGBACK_TONE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)");
                     mRingbackToneRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_IN_CALL_VOICE_PRIVACY_ON:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)");
                     mInCallVoicePrivacyOnRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_IN_CALL_VOICE_PRIVACY_OFF:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)");
                     mInCallVoicePrivacyOffRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_CALL_WAITING:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)");
                     mCallWaitingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_DISPLAY_INFO:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)");
                     mDisplayInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_SIGNAL_INFO:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)");
                     mSignalInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_CDMA_OTA_STATUS_CHANGE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)");
                     mCdmaOtaStatusChangeRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_RESEND_INCALL_MUTE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)");
                     mResendIncallMuteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_MMI_INITIATE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)");
                     mMmiInitiateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_MMI_COMPLETE:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_COMPLETE)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_MMI_COMPLETE)");
                     mMmiCompleteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_ECM_TIMER_RESET:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)");
                     mEcmTimerResetRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_SUBSCRIPTION_INFO_READY:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)");
                     mSubscriptionInfoReadyRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_SUPP_SERVICE_FAILED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)");
                     mSuppServiceFailedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_SERVICE_STATE_CHANGED:
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)");
                     mServiceStateChangedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
                     break;
                 case EVENT_POST_DIAL_CHARACTER:
                     // we need send the character that is being processed in msg.arg1
                     // so can't use notifyRegistrants()
-                    if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)");
+                    if (VDBG) Rlog.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)");
                     for(int i=0; i < mPostDialCharacterRegistrants.size(); i++) {
                         Message notifyMsg;
                         notifyMsg = ((Registrant)mPostDialCharacterRegistrants.get(i)).messageForRegistrant();
index 62caf01..efe53c9 100644 (file)
@@ -21,7 +21,7 @@ import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
 import android.text.TextUtils;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.telephony.CommandException;
 
index 94c544e..d1085f6 100644 (file)
@@ -18,7 +18,7 @@ package com.android.internal.telephony;
 
 import com.android.internal.telephony.RILConstants;
 
-import android.util.Log;
+import android.telephony.Rlog;
 
 /**
  * {@hide}
@@ -84,7 +84,7 @@ public class CommandException extends RuntimeException {
             case RILConstants.ILLEGAL_SIM_OR_ME:
                 return new CommandException(Error.ILLEGAL_SIM_OR_ME);
             default:
-                Log.e("GSM", "Unrecognized RIL errno " + ril_errno);
+                Rlog.e("GSM", "Unrecognized RIL errno " + ril_errno);
                 return new CommandException(Error.INVALID_RESPONSE);
         }
     }
index f7757b3..d9c3dc7 100644 (file)
 package com.android.internal.telephony;
 
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+import com.android.internal.telephony.uicc.IccCardStatus;
 
 import android.os.Message;
 import android.os.Handler;
-import android.util.Log;
+import android.telephony.Rlog;
 
 /**
  * {@hide}
index 554d974..8e10af5 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.telephony.Rlog;
 import android.util.Log;
 
 /**
@@ -293,7 +294,7 @@ public abstract class Connection {
     public String toString() {
         StringBuilder str = new StringBuilder(128);
 
-        if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
+        if (Rlog.isLoggable(LOG_TAG, Log.DEBUG)) {
             str.append("addr: " + getAddress())
                     .append(" pres.: " + getNumberPresentation())
                     .append(" dial: " + getOrigDialString())
index efbf608..c3a3b1d 100644 (file)
@@ -22,7 +22,7 @@ import android.net.LinkProperties;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
 import android.os.SystemProperties;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.telephony.DataConnection.FailCause;
 
@@ -149,7 +149,7 @@ public class DataCallState {
                                 // Assume point to point
                                 addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128;
                             }
-                            if (DBG) Log.d(LOG_TAG, "addr/pl=" + addr + "/" + addrPrefixLen);
+                            if (DBG) Rlog.d(LOG_TAG, "addr/pl=" + addr + "/" + addrPrefixLen);
                             la = new LinkAddress(ia, addrPrefixLen);
                             linkProperties.addLinkAddress(la);
                         }
@@ -219,7 +219,7 @@ public class DataCallState {
 
                 result = SetupResult.SUCCESS;
             } catch (UnknownHostException e) {
-                Log.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e);
+                Rlog.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e);
                 e.printStackTrace();
                 result = SetupResult.ERR_UnacceptableParameter;
             }
@@ -234,7 +234,7 @@ public class DataCallState {
         // An error occurred so clear properties
         if (result != SetupResult.SUCCESS) {
             if(DBG) {
-                Log.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " +
+                Rlog.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " +
                         "status=" + status + " result=" + result);
             }
             linkProperties.clear();
index a24414f..2cd64e1 100644 (file)
@@ -586,6 +586,6 @@ public class DataConnectionAc extends AsyncChannel {
     }
 
     private void log(String s) {
-        android.util.Log.d(mLogTag, "DataConnectionAc " + s);
+        android.telephony.Rlog.d(mLogTag, "DataConnectionAc " + s);
     }
 }
index 89a02d3..f1855d2 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -42,11 +43,14 @@ import android.provider.Settings.SettingNotFoundException;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.Log;
+import android.util.EventLog;
+import android.telephony.Rlog;
 
 import com.android.internal.R;
 import com.android.internal.telephony.DataConnection.FailCause;
 import com.android.internal.telephony.DctConstants;
+import com.android.internal.telephony.uicc.IccRecords;
+import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.util.AsyncChannel;
 
 import java.io.FileDescriptor;
@@ -57,6 +61,7 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * {@hide}
@@ -64,7 +69,15 @@ import java.util.concurrent.atomic.AtomicInteger;
 public abstract class DataConnectionTracker extends Handler {
     protected static final boolean DBG = true;
     protected static final boolean VDBG = false;
+    protected static final boolean RADIO_TESTS = false;
 
+    /**
+     * Constants for the data connection activity:
+     * physical link down/up
+     */
+    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE = 0;
+    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1;
+    protected static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2;
 
     /** Delay between APN attempts.
         Note the property override mechanism is there just for testing purpose only. */
@@ -135,6 +148,12 @@ public abstract class DataConnectionTracker extends Handler {
     // Tag for tracking stale alarms
     protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
 
+    protected static final boolean DATA_STALL_SUSPECTED = true;
+    protected static final boolean DATA_STALL_NOT_SUSPECTED = false;
+
+    protected String RADIO_RESET_PROPERTY = "gsm.radioreset";
+
+
     // TODO: See if we can remove INTENT_RECONNECT_ALARM
     //       having to have different values for GSM and
     //       CDMA. If so we can then remove the need for
@@ -159,11 +178,12 @@ public abstract class DataConnectionTracker extends Handler {
 
     // member variables
     protected PhoneBase mPhone;
+    protected UiccController mUiccController;
+    protected AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
     protected DctConstants.Activity mActivity = DctConstants.Activity.NONE;
     protected DctConstants.State mState = DctConstants.State.IDLE;
     protected Handler mDataConnectionTracker = null;
 
-
     protected long mTxPkts;
     protected long mRxPkts;
     protected int mNetStatPollPeriod;
@@ -230,6 +250,8 @@ public abstract class DataConnectionTracker extends Handler {
     /* Once disposed dont handle any messages */
     protected boolean mIsDisposed = false;
 
+    protected ContentResolver mResolver;
+
     protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
     {
         @Override
@@ -277,6 +299,26 @@ public abstract class DataConnectionTracker extends Handler {
     };
 
     private final DataRoamingSettingObserver mDataRoamingSettingObserver;
+    private Runnable mPollNetStat = new Runnable()
+    {
+        @Override
+        public void run() {
+            updateDataActivity();
+
+            if (mIsScreenOn) {
+                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
+                        Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
+            } else {
+                mNetStatPollPeriod = Settings.Global.getInt(mResolver,
+                        Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
+                        POLL_NETSTAT_SCREEN_OFF_MILLIS);
+            }
+
+            if (mNetStatPollEnabled) {
+                mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
+            }
+        }
+    };
 
     private class DataRoamingSettingObserver extends ContentObserver {
         public DataRoamingSettingObserver(Handler handler) {
@@ -286,7 +328,7 @@ public abstract class DataConnectionTracker extends Handler {
         public void register(Context context) {
             final ContentResolver resolver = context.getContentResolver();
             resolver.registerContentObserver(
-                    Settings.Secure.getUriFor(Settings.Secure.DATA_ROAMING), false, this);
+                    Settings.Global.getUriFor(Settings.Global.DATA_ROAMING), false, this);
         }
 
         public void unregister(Context context) {
@@ -335,34 +377,8 @@ public abstract class DataConnectionTracker extends Handler {
         }
 
         public void updateTxRxSum() {
-            boolean txUpdated = false, rxUpdated = false;
-            long txSum = 0, rxSum = 0;
-            for (ApnContext apnContext : mApnContexts.values()) {
-                if (apnContext.getState() == DctConstants.State.CONNECTED) {
-                    DataConnectionAc dcac = apnContext.getDataConnectionAc();
-                    if (dcac == null) continue;
-
-                    LinkProperties linkProp = dcac.getLinkPropertiesSync();
-                    if (linkProp == null) continue;
-
-                    String iface = linkProp.getInterfaceName();
-
-                    if (iface != null) {
-                        long stats = TrafficStats.getTxPackets(iface);
-                        if (stats > 0) {
-                            txUpdated = true;
-                            txSum += stats;
-                        }
-                        stats = TrafficStats.getRxPackets(iface);
-                        if (stats > 0) {
-                            rxUpdated = true;
-                            rxSum += stats;
-                        }
-                    }
-                }
-            }
-            if (txUpdated) this.txPkts = txSum;
-            if (rxUpdated) this.rxPkts = rxSum;
+            this.txPkts = TrafficStats.getMobileTxPackets();
+            this.rxPkts = TrafficStats.getMobileRxPackets();
         }
     }
 
@@ -412,6 +428,8 @@ public abstract class DataConnectionTracker extends Handler {
         super();
         if (DBG) log("DCT.constructor");
         mPhone = phone;
+        mUiccController = UiccController.getInstance();
+        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(getActionIntentReconnectAlarm());
@@ -420,9 +438,10 @@ public abstract class DataConnectionTracker extends Handler {
         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         filter.addAction(INTENT_SET_FAIL_DATA_SETUP_COUNTER);
+        filter.addAction(getActionIntentDataStallAlarm());
 
-        mUserDataEnabled = Settings.Secure.getInt(
-                mPhone.getContext().getContentResolver(), Settings.Secure.MOBILE_DATA, 1) == 1;
+        mUserDataEnabled = Settings.Global.getInt(
+                mPhone.getContext().getContentResolver(), Settings.Global.MOBILE_DATA, 1) == 1;
 
         // TODO: Why is this registering the phone as the receiver of the intent
         //       and not its own handler?
@@ -440,9 +459,11 @@ public abstract class DataConnectionTracker extends Handler {
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
         mAutoAttachOnCreation = sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false);
 
-        // watch for changes to Settings.Secure.DATA_ROAMING
+        // watch for changes to Settings.Global.DATA_ROAMING
         mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone);
         mDataRoamingSettingObserver.register(mPhone.getContext());
+
+        mResolver = mPhone.getContext().getContentResolver();
     }
 
     public void dispose() {
@@ -454,6 +475,7 @@ public abstract class DataConnectionTracker extends Handler {
         mIsDisposed = true;
         mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
         mDataRoamingSettingObserver.unregister(mPhone.getContext());
+        mUiccController.unregisterForIccChanged(this);
     }
 
     protected void broadcastMessenger() {
@@ -483,11 +505,11 @@ public abstract class DataConnectionTracker extends Handler {
             return null;
         }
         Context c = mPhone.getContext();
-        String apnData = Settings.Secure.getString(c.getContentResolver(),
-                Settings.Secure.TETHER_DUN_APN);
+        String apnData = Settings.Global.getString(c.getContentResolver(),
+                Settings.Global.TETHER_DUN_APN);
         ApnSetting dunSetting = ApnSetting.fromString(apnData);
         if (dunSetting != null) {
-            if (VDBG) log("fetchDunApn: secure TETHER_DUN_APN dunSetting=" + dunSetting);
+            if (VDBG) log("fetchDunApn: global TETHER_DUN_APN dunSetting=" + dunSetting);
             return dunSetting;
         }
 
@@ -518,23 +540,23 @@ public abstract class DataConnectionTracker extends Handler {
     }
 
     /**
-     * Modify {@link Settings.Secure#DATA_ROAMING} value.
+     * Modify {@link Settings.Global#DATA_ROAMING} value.
      */
     public void setDataOnRoamingEnabled(boolean enabled) {
         if (getDataOnRoamingEnabled() != enabled) {
             final ContentResolver resolver = mPhone.getContext().getContentResolver();
-            Settings.Secure.putInt(resolver, Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
+            Settings.Global.putInt(resolver, Settings.Global.DATA_ROAMING, enabled ? 1 : 0);
             // will trigger handleDataOnRoamingChange() through observer
         }
     }
 
     /**
-     * Return current {@link Settings.Secure#DATA_ROAMING} value.
+     * Return current {@link Settings.Global#DATA_ROAMING} value.
      */
     public boolean getDataOnRoamingEnabled() {
         try {
             final ContentResolver resolver = mPhone.getContext().getContentResolver();
-            return Settings.Secure.getInt(resolver, Settings.Secure.DATA_ROAMING) != 0;
+            return Settings.Global.getInt(resolver, Settings.Global.DATA_ROAMING) != 0;
         } catch (SettingNotFoundException snfe) {
             return false;
         }
@@ -552,9 +574,6 @@ public abstract class DataConnectionTracker extends Handler {
     // abstract methods
     protected abstract String getActionIntentReconnectAlarm();
     protected abstract String getActionIntentDataStallAlarm();
-    protected abstract void startNetStatPoll();
-    protected abstract void stopNetStatPoll();
-    protected abstract void restartDataStallAlarm();
     protected abstract void restartRadio();
     protected abstract void log(String s);
     protected abstract void loge(String s);
@@ -576,10 +595,7 @@ public abstract class DataConnectionTracker extends Handler {
     protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
     protected abstract void onCleanUpAllConnections(String cause);
     protected abstract boolean isDataPossible(String apnType);
-
-    protected void onDataStallAlarm(int tag) {
-        loge("onDataStallAlarm: not impleted tag=" + tag);
-    }
+    protected abstract void onUpdateIcc();
 
     @Override
     public void handleMessage(Message msg) {
@@ -686,8 +702,12 @@ public abstract class DataConnectionTracker extends Handler {
                 onSetPolicyDataEnabled(enabled);
                 break;
             }
+            case DctConstants.EVENT_ICC_CHANGED:
+                onUpdateIcc();
+                break;
+
             default:
-                Log.e("DATA", "Unidentified event msg=" + msg);
+                Rlog.e("DATA", "Unidentified event msg=" + msg);
                 break;
         }
     }
@@ -1054,8 +1074,8 @@ public abstract class DataConnectionTracker extends Handler {
             final boolean prevEnabled = getAnyDataEnabled();
             if (mUserDataEnabled != enabled) {
                 mUserDataEnabled = enabled;
-                Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                        Settings.Secure.MOBILE_DATA, enabled ? 1 : 0);
+                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
                 if (getDataOnRoamingEnabled() == false &&
                         mPhone.getServiceState().getRoaming() == true) {
                     if (enabled) {
@@ -1126,8 +1146,296 @@ public abstract class DataConnectionTracker extends Handler {
         }
     }
 
+    protected void resetPollStats() {
+        mTxPkts = -1;
+        mRxPkts = -1;
+        mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
+    }
+
+    protected abstract DctConstants.State getOverallState();
+
+    protected void startNetStatPoll() {
+        if (getOverallState() == DctConstants.State.CONNECTED && mNetStatPollEnabled == false) {
+            if (DBG) log("startNetStatPoll");
+            resetPollStats();
+            mNetStatPollEnabled = true;
+            mPollNetStat.run();
+        }
+    }
+
+    protected void stopNetStatPoll() {
+        mNetStatPollEnabled = false;
+        removeCallbacks(mPollNetStat);
+        if (DBG) log("stopNetStatPoll");
+    }
+
+    public void updateDataActivity() {
+        long sent, received;
+
+        DctConstants.Activity newActivity;
+
+        TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
+        TxRxSum curTxRxSum = new TxRxSum();
+        curTxRxSum.updateTxRxSum();
+        mTxPkts = curTxRxSum.txPkts;
+        mRxPkts = curTxRxSum.rxPkts;
+
+        if (VDBG) {
+            log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
+        }
+
+        if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
+            sent = mTxPkts - preTxRxSum.txPkts;
+            received = mRxPkts - preTxRxSum.rxPkts;
+
+            if (VDBG)
+                log("updateDataActivity: sent=" + sent + " received=" + received);
+            if (sent > 0 && received > 0) {
+                newActivity = DctConstants.Activity.DATAINANDOUT;
+            } else if (sent > 0 && received == 0) {
+                newActivity = DctConstants.Activity.DATAOUT;
+            } else if (sent == 0 && received > 0) {
+                newActivity = DctConstants.Activity.DATAIN;
+            } else {
+                newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
+                        mActivity : DctConstants.Activity.NONE;
+            }
+
+            if (mActivity != newActivity && mIsScreenOn) {
+                if (VDBG)
+                    log("updateDataActivity: newActivity=" + newActivity);
+                mActivity = newActivity;
+                mPhone.notifyDataActivity();
+            }
+        }
+    }
+
+    // Recovery action taken in case of data stall
+    protected static class RecoveryAction {
+        public static final int GET_DATA_CALL_LIST      = 0;
+        public static final int CLEANUP                 = 1;
+        public static final int REREGISTER              = 2;
+        public static final int RADIO_RESTART           = 3;
+        public static final int RADIO_RESTART_WITH_PROP = 4;
+
+        private static boolean isAggressiveRecovery(int value) {
+            return ((value == RecoveryAction.CLEANUP) ||
+                    (value == RecoveryAction.REREGISTER) ||
+                    (value == RecoveryAction.RADIO_RESTART) ||
+                    (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
+        }
+    }
+
+    public int getRecoveryAction() {
+        int action = Settings.System.getInt(mPhone.getContext().getContentResolver(),
+                "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
+        if (VDBG) log("getRecoveryAction: " + action);
+        return action;
+    }
+    public void putRecoveryAction(int action) {
+        Settings.System.putInt(mPhone.getContext().getContentResolver(),
+                "radio.data.stall.recovery.action", action);
+        if (VDBG) log("putRecoveryAction: " + action);
+    }
+
+    protected boolean isConnected() {
+        return false;
+    }
+
+    protected void doRecovery() {
+        if (getOverallState() == DctConstants.State.CONNECTED) {
+            // Go through a series of recovery steps, each action transitions to the next action
+            int recoveryAction = getRecoveryAction();
+            switch (recoveryAction) {
+            case RecoveryAction.GET_DATA_CALL_LIST:
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
+                        mSentSinceLastRecv);
+                if (DBG) log("doRecovery() get data call list");
+                mPhone.mCM.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
+                putRecoveryAction(RecoveryAction.CLEANUP);
+                break;
+            case RecoveryAction.CLEANUP:
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
+                if (DBG) log("doRecovery() cleanup all connections");
+                cleanUpAllConnections(Phone.REASON_PDP_RESET);
+                putRecoveryAction(RecoveryAction.REREGISTER);
+                break;
+            case RecoveryAction.REREGISTER:
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
+                        mSentSinceLastRecv);
+                if (DBG) log("doRecovery() re-register");
+                mPhone.getServiceStateTracker().reRegisterNetwork(null);
+                putRecoveryAction(RecoveryAction.RADIO_RESTART);
+                break;
+            case RecoveryAction.RADIO_RESTART:
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
+                        mSentSinceLastRecv);
+                if (DBG) log("restarting radio");
+                putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
+                restartRadio();
+                break;
+            case RecoveryAction.RADIO_RESTART_WITH_PROP:
+                // This is in case radio restart has not recovered the data.
+                // It will set an additional "gsm.radioreset" property to tell
+                // RIL or system to take further action.
+                // The implementation of hard reset recovery action is up to OEM product.
+                // Once RADIO_RESET property is consumed, it is expected to set back
+                // to false by RIL.
+                EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
+                if (DBG) log("restarting radio with gsm.radioreset to true");
+                SystemProperties.set(RADIO_RESET_PROPERTY, "true");
+                // give 1 sec so property change can be notified.
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {}
+                restartRadio();
+                putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
+                break;
+            default:
+                throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
+                    recoveryAction);
+            }
+        }
+    }
+
+    private void updateDataStallInfo() {
+        long sent, received;
+
+        TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
+        mDataStallTxRxSum.updateTxRxSum();
+
+        if (VDBG) {
+            log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
+                    " preTxRxSum=" + preTxRxSum);
+        }
+
+        sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
+        received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
+
+        if (RADIO_TESTS) {
+            if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
+                log("updateDataStallInfo: radio.test.data.stall true received = 0;");
+                received = 0;
+            }
+        }
+        if ( sent > 0 && received > 0 ) {
+            if (VDBG) log("updateDataStallInfo: IN/OUT");
+            mSentSinceLastRecv = 0;
+            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
+        } else if (sent > 0 && received == 0) {
+            if (mPhone.getState() == PhoneConstants.State.IDLE) {
+                mSentSinceLastRecv += sent;
+            } else {
+                mSentSinceLastRecv = 0;
+            }
+            if (DBG) {
+                log("updateDataStallInfo: OUT sent=" + sent +
+                        " mSentSinceLastRecv=" + mSentSinceLastRecv);
+            }
+        } else if (sent == 0 && received > 0) {
+            if (VDBG) log("updateDataStallInfo: IN");
+            mSentSinceLastRecv = 0;
+            putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
+        } else {
+            if (VDBG) log("updateDataStallInfo: NONE");
+        }
+    }
+
+    protected void onDataStallAlarm(int tag) {
+        if (mDataStallAlarmTag != tag) {
+            if (DBG) {
+                log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
+            }
+            return;
+        }
+        updateDataStallInfo();
+
+        int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
+                Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
+                NUMBER_SENT_PACKETS_OF_HANG);
+
+        boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
+        if (mSentSinceLastRecv >= hangWatchdogTrigger) {
+            if (DBG) {
+                log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
+            }
+            suspectedStall = DATA_STALL_SUSPECTED;
+            sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
+        } else {
+            if (VDBG) {
+                log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
+                    " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
+            }
+        }
+        startDataStallAlarm(suspectedStall);
+    }
+
+    protected void startDataStallAlarm(boolean suspectedStall) {
+        int nextAction = getRecoveryAction();
+        int delayInMs;
+
+        if (getOverallState() == DctConstants.State.CONNECTED) {
+            // If screen is on or data stall is currently suspected, set the alarm
+            // with an aggresive timeout.
+            if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
+                delayInMs = Settings.Global.getInt(mResolver,
+                        Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
+                        DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
+            } else {
+                delayInMs = Settings.Global.getInt(mResolver,
+                        Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
+                        DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
+            }
+
+            mDataStallAlarmTag += 1;
+            if (VDBG) {
+                log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
+                        " delay=" + (delayInMs / 1000) + "s");
+            }
+            AlarmManager am =
+                    (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
+
+            Intent intent = new Intent(getActionIntentDataStallAlarm());
+            intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
+            mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
+                    PendingIntent.FLAG_UPDATE_CURRENT);
+            am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
+        }
+    }
+
+    protected void stopDataStallAlarm() {
+        AlarmManager am =
+            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
+
+        if (VDBG) {
+            log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
+                    " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
+        }
+        mDataStallAlarmTag += 1;
+        if (mDataStallAlarmIntent != null) {
+            am.cancel(mDataStallAlarmIntent);
+            mDataStallAlarmIntent = null;
+        }
+    }
+
+    protected void restartDataStallAlarm() {
+        if (isConnected() == false) return;
+        // To be called on screen status change.
+        // Do not cancel the alarm if it is set with aggressive timeout.
+        int nextAction = getRecoveryAction();
+
+        if (RecoveryAction.isAggressiveRecovery(nextAction)) {
+            if (DBG) log("data stall recovery action is pending. not resetting the alarm.");
+            return;
+        }
+        stopDataStallAlarm();
+        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("DataConnectionTracker:");
+        pw.println(" RADIO_TESTS=" + RADIO_TESTS);
         pw.println(" mInternalDataEnabled=" + mInternalDataEnabled);
         pw.println(" mUserDataEnabled=" + mUserDataEnabled);
         pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled);
@@ -1149,6 +1457,7 @@ public abstract class DataConnectionTracker extends Handler {
         pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
         pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
         pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
+        pw.println(" mResolver=" + mResolver);
         pw.println(" mIsWifiConnected=" + mIsWifiConnected);
         pw.println(" mReconnectIntent=" + mReconnectIntent);
         pw.println(" mCidActive=" + mCidActive);
index 29fea6e..deba3eb 100644 (file)
 
 package com.android.internal.telephony;
 
-import android.util.Log;
+import android.telephony.Rlog;
+
+import com.android.internal.telephony.uicc.UiccController;
+import com.android.internal.telephony.uicc.IccCardProxy;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -99,10 +102,24 @@ public class DebugService {
         }
         pw.flush();
         pw.println("++++++++++++++++++++++++++++++++");
+        try {
+            UiccController.getInstance().dump(fd, pw, args);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        pw.flush();
+        pw.println("++++++++++++++++++++++++++++++++");
+        try {
+            ((IccCardProxy)phoneProxy.getIccCard()).dump(fd, pw, args);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        pw.flush();
+        pw.println("++++++++++++++++++++++++++++++++");
         log("dump: -");
     }
 
     private static void log(String s) {
-        Log.d(TAG, "DebugService " + s);
+        Rlog.d(TAG, "DebugService " + s);
     }
 }
index 4d16443..8f4ae84 100644 (file)
@@ -24,10 +24,12 @@ import android.os.ServiceManager;
 import android.telephony.CellInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.telephony.ITelephonyRegistry;
 
+import java.util.List;
+
 /**
  * broadcast intents
  */
@@ -157,7 +159,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
         }
     }
 
-    public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
+    public void notifyCellInfo(Phone sender, List<CellInfo> cellInfo) {
         try {
             mRegistry.notifyCellInfo(cellInfo);
         } catch (RemoteException ex) {
@@ -174,7 +176,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
     }
 
     private void log(String s) {
-        Log.d(LOG_TAG, "[PhoneNotifier] " + s);
+        Rlog.d(LOG_TAG, "[PhoneNotifier] " + s);
     }
 
     /**
index b1e63ae..c76be5f 100644 (file)
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 //import com.android.internal.telephony.*;
-import android.util.Log;
+import android.telephony.Rlog;
 import java.lang.Comparable;
 import android.telephony.PhoneNumberUtils;
 
@@ -90,7 +90,7 @@ public class DriverCall implements Comparable {
 
             }
         } catch (ATParseEx ex) {
-            Log.e(LOG_TAG,"Invalid CLCC line: '" + line + "'");
+            Rlog.e(LOG_TAG,"Invalid CLCC line: '" + line + "'");
             return null;
         }
 
index 427e5da..91247b3 100644 (file)
@@ -71,3 +71,7 @@ option java_package com.android.internal.telephony;
 
 # Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP
 50122 data_stall_recovery_radio_restart_with_prop (out_packet_count|1|1)
+
+# SMS denied by user
+50125 sms_denied_by_user (app_signature|3)
+50128 sms_sent_by_user (app_signature|3)
index f700dfe..95b3efb 100644 (file)
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import com.android.internal.telephony.AdnRecord;
+import com.android.internal.telephony.uicc.AdnRecord;
 
 
 
index 735f986..1fd9f70 100644 (file)
@@ -198,4 +198,15 @@ interface ISms {
      */
     boolean disableCellBroadcastRange(int startMessageId, int endMessageId);
 
+    /**
+     * Returns the premium SMS send permission for the specified package.
+     * Requires system permission.
+     */
+    int getPremiumSmsPermission(String packageName);
+
+    /**
+     * Set the SMS send permission for the specified package.
+     * Requires system permission.
+     */
+    void setPremiumSmsPermission(String packageName, int permission);
 }
index 740292c..1ec4f18 100644 (file)
 
 package com.android.internal.telephony;
 
-import static android.Manifest.permission.READ_PHONE_STATE;
-import android.app.ActivityManagerNative;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.util.Log;
-import android.view.WindowManager;
 
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.CommandsInterface.RadioState;
-import com.android.internal.telephony.gsm.SIMFileHandler;
-import com.android.internal.telephony.gsm.SIMRecords;
-import com.android.internal.telephony.cat.CatService;
-import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler;
-import com.android.internal.telephony.cdma.CdmaLteUiccRecords;
-import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
-import com.android.internal.telephony.cdma.RuimFileHandler;
-import com.android.internal.telephony.cdma.RuimRecords;
-
-import com.android.internal.R;
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus;
+import com.android.internal.telephony.uicc.IccFileHandler;
+import com.android.internal.telephony.uicc.IccRecords;
 
 /**
  * {@hide}
+ * @Deprecated use UiccController.getUiccCard instead.
+ *
+ * Integrated Circuit Card (ICC) interface
+ * An object of a class implementing this interface is used by external
+ * apps (specifically PhoneApp) to perform icc card related functionality.
+ *
+ * Apps (those that have access to Phone object) can retrieve this object
+ * by calling phone.getIccCard()
+ *
+ * This interface is implemented by IccCardProxy and the object PhoneApp
+ * gets when it calls getIccCard is IccCardProxy.
  */
-public class IccCard {
-    protected String mLogTag;
-    protected boolean mDbg;
-
-    protected IccCardStatus mIccCardStatus = null;
-    protected IccCardConstants.State mState = null;
-    private final Object mStateMonitor = new Object();
-
-    protected boolean is3gpp = true;
-    protected boolean isSubscriptionFromIccCard = true;
-    protected CdmaSubscriptionSourceManager mCdmaSSM = null;
-    protected PhoneBase mPhone;
-    private IccRecords mIccRecords;
-    private IccFileHandler mIccFileHandler;
-    private CatService mCatService;
-
-    private RegistrantList mAbsentRegistrants = new RegistrantList();
-    private RegistrantList mPinLockedRegistrants = new RegistrantList();
-    private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
-    protected RegistrantList mReadyRegistrants = new RegistrantList();
-    protected RegistrantList mRuimReadyRegistrants = new RegistrantList();
-
-    private boolean mDesiredPinLocked;
-    private boolean mDesiredFdnEnabled;
-    private boolean mIccPinLocked = true; // Default to locked
-    private boolean mIccFdnEnabled = false; // Default to disabled.
-                                            // Will be updated when SIM_READY.
-
-    /* Parameter is3gpp's values to be passed to constructor */
-    public final static boolean CARD_IS_3GPP = true;
-    public final static boolean CARD_IS_NOT_3GPP = false;
-
-    protected static final int EVENT_ICC_LOCKED = 1;
-    private static final int EVENT_GET_ICC_STATUS_DONE = 2;
-    protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
-    private static final int EVENT_PINPUK_DONE = 4;
-    private static final int EVENT_REPOLL_STATUS_DONE = 5;
-    protected static final int EVENT_ICC_READY = 6;
-    private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
-    private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
-    private static final int EVENT_CHANGE_ICC_PASSWORD_DONE = 9;
-    private static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
-    private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
-    private static final int EVENT_ICC_STATUS_CHANGED = 12;
-    private static final int EVENT_CARD_REMOVED = 13;
-    private static final int EVENT_CARD_ADDED = 14;
-    protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 15;
-    protected static final int EVENT_RADIO_ON = 16;
-
-    public IccCardConstants.State getState() {
-        if (mState == null) {
-            switch(mPhone.mCM.getRadioState()) {
-                /* This switch block must not return anything in
-                 * IccCardConstants.State.isLocked() or IccCardConstants.State.ABSENT.
-                 * If it does, handleSimStatus() may break
-                 */
-                case RADIO_OFF:
-                case RADIO_UNAVAILABLE:
-                    return IccCardConstants.State.UNKNOWN;
-                default:
-                    if (!is3gpp && !isSubscriptionFromIccCard) {
-                        // CDMA can get subscription from NV. In that case,
-                        // subscription is ready as soon as Radio is ON.
-                        return IccCardConstants.State.READY;
-                    }
-            }
-        } else {
-            return mState;
-        }
-
-        return IccCardConstants.State.UNKNOWN;
-    }
-
-    public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) {
-        mLogTag = logTag;
-        mDbg = dbg;
-        if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2"));
-        mPhone = phone;
-        this.is3gpp = is3gpp;
-        mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(),
-                mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
-        if (phone.mCM.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE
-                && phone instanceof CDMALTEPhone) {
-            mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
-            mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
-        } else {
-            // Correct aid will be set later (when GET_SIM_STATUS returns)
-            mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
-                                       new RuimFileHandler(this, "", mPhone.mCM);
-            mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
-                                   new RuimRecords(this, mPhone.mContext, mPhone.mCM);
-        }
-        mCatService = CatService.getInstance(mPhone.mCM, mIccRecords,
-                mPhone.mContext, mIccFileHandler, this);
-        mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
-        mPhone.mCM.registerForOn(mHandler, EVENT_RADIO_ON, null);
-        mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null);
-    }
-
-    public void dispose() {
-        if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
-        mPhone.mCM.unregisterForIccStatusChanged(mHandler);
-        mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
-        mPhone.mCM.unregisterForOn(mHandler);
-        mCatService.dispose();
-        mCdmaSSM.dispose(mHandler);
-        mIccRecords.dispose();
-        mIccFileHandler.dispose();
-    }
-
-    protected void finalize() {
-        if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2"));
-    }
+public interface IccCard {
+    /**
+     * @return combined Card and current App state
+     */
+    public State getState();
 
-    public IccRecords getIccRecords() {
-        return mIccRecords;
-    }
+    /**
+     * @return IccRecords object belonging to current UiccCardApplication
+     */
+    public IccRecords getIccRecords();
 
-    public IccFileHandler getIccFileHandler() {
-        return mIccFileHandler;
-    }
+    /**
+     * @return IccFileHandler object belonging to current UiccCardApplication
+     */
+    public IccFileHandler getIccFileHandler();
 
     /**
      * Notifies handler of any transition into IccCardConstants.State.ABSENT
      */
-    public void registerForAbsent(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mAbsentRegistrants.add(r);
-
-        if (getState() == IccCardConstants.State.ABSENT) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForAbsent(Handler h) {
-        mAbsentRegistrants.remove(h);
-    }
+    public void registerForAbsent(Handler h, int what, Object obj);
+    public void unregisterForAbsent(Handler h);
 
     /**
      * Notifies handler of any transition into IccCardConstants.State.NETWORK_LOCKED
      */
-    public void registerForNetworkLocked(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mNetworkLockedRegistrants.add(r);
-
-        if (getState() == IccCardConstants.State.NETWORK_LOCKED) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForNetworkLocked(Handler h) {
-        mNetworkLockedRegistrants.remove(h);
-    }
+    public void registerForNetworkLocked(Handler h, int what, Object obj);
+    public void unregisterForNetworkLocked(Handler h);
 
     /**
      * Notifies handler of any transition into IccCardConstants.State.isPinLocked()
      */
-    public void registerForLocked(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        mPinLockedRegistrants.add(r);
-
-        if (getState().isPinLocked()) {
-            r.notifyRegistrant();
-        }
-    }
-
-    public void unregisterForLocked(Handler h) {
-        mPinLockedRegistrants.remove(h);
-    }
-
-    public void registerForReady(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mReadyRegistrants.add(r);
-
-            if (getState() == IccCardConstants.State.READY) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForReady(Handler h) {
-        synchronized (mStateMonitor) {
-            mReadyRegistrants.remove(h);
-        }
-    }
-
-    public IccCardConstants.State getRuimState() {
-        if(mIccCardStatus != null) {
-            return getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
-        } else {
-            return IccCardConstants.State.UNKNOWN;
-        }
-    }
-
-    public void registerForRuimReady(Handler h, int what, Object obj) {
-        Registrant r = new Registrant (h, what, obj);
-
-        synchronized (mStateMonitor) {
-            mRuimReadyRegistrants.add(r);
-
-            if (getState() == IccCardConstants.State.READY &&
-                    getRuimState() == IccCardConstants.State.READY ) {
-                r.notifyRegistrant(new AsyncResult(null, null, null));
-            }
-        }
-    }
-
-    public void unregisterForRuimReady(Handler h) {
-        synchronized (mStateMonitor) {
-            mRuimReadyRegistrants.remove(h);
-        }
-    }
+    public void registerForLocked(Handler h, int what, Object obj);
+    public void unregisterForLocked(Handler h);
 
     /**
      * Supply the ICC PIN to the ICC
@@ -284,33 +89,28 @@ public class IccCard {
      *       instanceof com.android.internal.telephony.gsm.CommandException)
      * && ((CommandException)(((AsyncResult)onComplete.obj).exception))
      *          .getCommandError() == CommandException.Error.PASSWORD_INCORRECT
-     *
-     *
      */
+    public void supplyPin (String pin, Message onComplete);
 
-    public void supplyPin (String pin, Message onComplete) {
-        mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
-
-    public void supplyPuk (String puk, String newPin, Message onComplete) {
-        mPhone.mCM.supplyIccPuk(puk, newPin,
-                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
+    /**
+     * Supply the ICC PUK to the ICC
+     */
+    public void supplyPuk (String puk, String newPin, Message onComplete);
 
-    public void supplyPin2 (String pin2, Message onComplete) {
-        mPhone.mCM.supplyIccPin2(pin2,
-                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
+    /**
+     * Supply the ICC PIN2 to the ICC
+     */
+    public void supplyPin2 (String pin2, Message onComplete);
 
-    public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
-        mPhone.mCM.supplyIccPuk2(puk2, newPin2,
-                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
+    /**
+     * Supply the ICC PUK2 to the ICC
+     */
+    public void supplyPuk2 (String puk2, String newPin2, Message onComplete);
 
-    public void supplyNetworkDepersonalization (String pin, Message onComplete) {
-        mPhone.mCM.supplyNetworkDepersonalization(pin,
-                mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
-    }
+    /**
+     * Supply Network depersonalization code to the RIL
+     */
+    public void supplyNetworkDepersonalization (String pin, Message onComplete);
 
     /**
      * Check whether ICC pin lock is enabled
@@ -319,9 +119,7 @@ public class IccCard {
      * @return true for ICC locked enabled
      *         false for ICC locked disabled
      */
-    public boolean getIccLockEnabled() {
-        return mIccPinLocked;
-     }
+    public boolean getIccLockEnabled();
 
     /**
      * Check whether ICC fdn (fixed dialing number) is enabled
@@ -330,9 +128,7 @@ public class IccCard {
      * @return true for ICC fdn enabled
      *         false for ICC fdn disabled
      */
-     public boolean getIccFdnEnabled() {
-        return mIccFdnEnabled;
-     }
+    public boolean getIccFdnEnabled();
 
      /**
       * Set the ICC pin lock enabled or disabled
@@ -346,18 +142,7 @@ public class IccCard {
       *        ((AsyncResult)onComplete.obj).exception != null on fail
       */
      public void setIccLockEnabled (boolean enabled,
-             String password, Message onComplete) {
-         int serviceClassX;
-         serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
-                 CommandsInterface.SERVICE_CLASS_DATA +
-                 CommandsInterface.SERVICE_CLASS_FAX;
-
-         mDesiredPinLocked = enabled;
-
-         mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM,
-                 enabled, password, serviceClassX,
-                 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete));
-     }
+             String password, Message onComplete);
 
      /**
       * Set the ICC fdn enabled or disabled
@@ -371,19 +156,7 @@ public class IccCard {
       *        ((AsyncResult)onComplete.obj).exception != null on fail
       */
      public void setIccFdnEnabled (boolean enabled,
-             String password, Message onComplete) {
-         int serviceClassX;
-         serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
-                 CommandsInterface.SERVICE_CLASS_DATA +
-                 CommandsInterface.SERVICE_CLASS_FAX +
-                 CommandsInterface.SERVICE_CLASS_SMS;
-
-         mDesiredFdnEnabled = enabled;
-
-         mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD,
-                 enabled, password, serviceClassX,
-                 mHandler.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete));
-     }
+             String password, Message onComplete);
 
      /**
       * Change the ICC password used in ICC pin lock
@@ -397,11 +170,7 @@ public class IccCard {
       *        ((AsyncResult)onComplete.obj).exception != null on fail
       */
      public void changeIccLockPassword(String oldPassword, String newPassword,
-             Message onComplete) {
-         mPhone.mCM.changeIccPin(oldPassword, newPassword,
-                 mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
-
-     }
+             Message onComplete);
 
      /**
       * Change the ICC password used in ICC fdn enable
@@ -415,12 +184,7 @@ public class IccCard {
       *        ((AsyncResult)onComplete.obj).exception != null on fail
       */
      public void changeIccFdnPassword(String oldPassword, String newPassword,
-             Message onComplete) {
-         mPhone.mCM.changeIccPin2(oldPassword, newPassword,
-                 mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
-
-     }
-
+             Message onComplete);
 
     /**
      * Returns service provider name stored in ICC card.
@@ -438,521 +202,16 @@ public class IccCard {
      *         yet available
      *
      */
-    public String getServiceProviderName () {
-        return mPhone.mIccRecords.getServiceProviderName();
-    }
-
-    protected void updateStateProperty() {
-        mPhone.setSystemProperty(TelephonyProperties.PROPERTY_SIM_STATE, getState().toString());
-    }
-
-    private void getIccCardStatusDone(AsyncResult ar) {
-        if (ar.exception != null) {
-            Log.e(mLogTag,"Error getting ICC status. "
-                    + "RIL_REQUEST_GET_ICC_STATUS should "
-                    + "never return an error", ar.exception);
-            return;
-        }
-        handleIccCardStatus((IccCardStatus) ar.result);
-    }
-
-    private void handleIccCardStatus(IccCardStatus newCardStatus) {
-        boolean transitionedIntoPinLocked;
-        boolean transitionedIntoAbsent;
-        boolean transitionedIntoNetworkLocked;
-        boolean transitionedIntoPermBlocked;
-        boolean isIccCardRemoved;
-        boolean isIccCardAdded;
-
-        IccCardConstants.State oldState, newState;
-        IccCardConstants.State oldRuimState = getRuimState();
-
-        oldState = mState;
-        mIccCardStatus = newCardStatus;
-        newState = getIccCardState();
-
-        synchronized (mStateMonitor) {
-            mState = newState;
-            updateStateProperty();
-            if (oldState != IccCardConstants.State.READY &&
-                    newState == IccCardConstants.State.READY) {
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_READY));
-                mReadyRegistrants.notifyRegistrants();
-            } else if (newState.isPinLocked()) {
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_LOCKED));
-            }
-            if (oldRuimState != IccCardConstants.State.READY &&
-                    getRuimState() == IccCardConstants.State.READY) {
-                mRuimReadyRegistrants.notifyRegistrants();
-            }
-        }
-
-        transitionedIntoPinLocked = (
-                 (oldState != IccCardConstants.State.PIN_REQUIRED &&
-                     newState == IccCardConstants.State.PIN_REQUIRED)
-              || (oldState != IccCardConstants.State.PUK_REQUIRED &&
-                      newState == IccCardConstants.State.PUK_REQUIRED));
-        transitionedIntoAbsent = (oldState != IccCardConstants.State.ABSENT &&
-                newState == IccCardConstants.State.ABSENT);
-        transitionedIntoNetworkLocked = (oldState != IccCardConstants.State.NETWORK_LOCKED
-                && newState == IccCardConstants.State.NETWORK_LOCKED);
-        transitionedIntoPermBlocked = (oldState != IccCardConstants.State.PERM_DISABLED
-                && newState == IccCardConstants.State.PERM_DISABLED);
-        isIccCardRemoved = (oldState != null && oldState.iccCardExist() &&
-                    newState == IccCardConstants.State.ABSENT);
-        isIccCardAdded = (oldState == IccCardConstants.State.ABSENT &&
-                        newState != null && newState.iccCardExist());
-
-        if (transitionedIntoPinLocked) {
-            if (mDbg) log("Notify SIM pin or puk locked.");
-            mPinLockedRegistrants.notifyRegistrants();
-            broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_LOCKED,
-                    (newState == IccCardConstants.State.PIN_REQUIRED) ?
-                            IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN :
-                                IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK);
-        } else if (transitionedIntoAbsent) {
-            if (mDbg) log("Notify SIM missing.");
-            mAbsentRegistrants.notifyRegistrants();
-            broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_ABSENT, null);
-        } else if (transitionedIntoNetworkLocked) {
-            if (mDbg) log("Notify SIM network locked.");
-            mNetworkLockedRegistrants.notifyRegistrants();
-            broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_LOCKED,
-                    IccCardConstants.INTENT_VALUE_LOCKED_NETWORK);
-        } else if (transitionedIntoPermBlocked) {
-            if (mDbg) log("Notify SIM permanently disabled.");
-            broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_ABSENT,
-                    IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED);
-        }
-
-        if (isIccCardRemoved) {
-            mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null));
-        } else if (isIccCardAdded) {
-            mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null));
-        }
-
-        // Call onReady Record(s) on the IccCard becomes ready (not NV)
-        if (oldState != IccCardConstants.State.READY && newState == IccCardConstants.State.READY &&
-                (is3gpp || isSubscriptionFromIccCard)) {
-            if (!(mIccFileHandler instanceof CdmaLteUiccFileHandler)) {
-                // CdmaLteUicc File Handler deals with both USIM and CSIM.
-                // Do not lock onto one AID for now.
-                mIccFileHandler.setAid(getAid());
-            }
-            mIccRecords.onReady();
-        }
-    }
-
-    private void onIccSwap(boolean isAdded) {
-        // TODO: Here we assume the device can't handle SIM hot-swap
-        //      and has to reboot. We may want to add a property,
-        //      e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support
-        //      hot-swap.
-        DialogInterface.OnClickListener listener = null;
-
-
-        // TODO: SimRecords is not reset while SIM ABSENT (only reset while
-        //       Radio_off_or_not_available). Have to reset in both both
-        //       added or removed situation.
-        listener = new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                if (which == DialogInterface.BUTTON_POSITIVE) {
-                    if (mDbg) log("Reboot due to SIM swap");
-                    PowerManager pm = (PowerManager) mPhone.getContext()
-                    .getSystemService(Context.POWER_SERVICE);
-                    pm.reboot("SIM is added.");
-                }
-            }
-
-        };
-
-        Resources r = Resources.getSystem();
-
-        String title = (isAdded) ? r.getString(R.string.sim_added_title) :
-            r.getString(R.string.sim_removed_title);
-        String message = (isAdded) ? r.getString(R.string.sim_added_message) :
-            r.getString(R.string.sim_removed_message);
-        String buttonTxt = r.getString(R.string.sim_restart_button);
-
-        AlertDialog dialog = new AlertDialog.Builder(mPhone.getContext())
-            .setTitle(title)
-            .setMessage(message)
-            .setPositiveButton(buttonTxt, listener)
-            .create();
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        dialog.show();
-    }
-
-    /**
-     * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
-     * @param ar is asyncResult of Query_Facility_Locked
-     */
-    private void onQueryFdnEnabled(AsyncResult ar) {
-        if(ar.exception != null) {
-            if(mDbg) log("Error in querying facility lock:" + ar.exception);
-            return;
-        }
-
-        int[] ints = (int[])ar.result;
-        if(ints.length != 0) {
-            mIccFdnEnabled = (0!=ints[0]);
-            if(mDbg) log("Query facility lock : "  + mIccFdnEnabled);
-        } else {
-            Log.e(mLogTag, "[IccCard] Bogus facility lock response");
-        }
-    }
+    public String getServiceProviderName ();
 
     /**
-     * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
-     * @param ar is asyncResult of Query_Facility_Locked
+     * Checks if an Application of specified type present on the card
+     * @param type is AppType to look for
      */
-    private void onQueryFacilityLock(AsyncResult ar) {
-        if(ar.exception != null) {
-            if (mDbg) log("Error in querying facility lock:" + ar.exception);
-            return;
-        }
-
-        int[] ints = (int[])ar.result;
-        if(ints.length != 0) {
-            mIccPinLocked = (0!=ints[0]);
-            if(mDbg) log("Query facility lock : "  + mIccPinLocked);
-        } else {
-            Log.e(mLogTag, "[IccCard] Bogus facility lock response");
-        }
-    }
-
-    public void broadcastIccStateChangedIntent(String value, String reason) {
-        Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra(PhoneConstants.PHONE_NAME_KEY, mPhone.getPhoneName());
-        intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value);
-        intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
-        if(mDbg) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
-                + " reason " + reason);
-        ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE);
-    }
-
-    protected Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg){
-            AsyncResult ar;
-            int serviceClassX;
-
-            serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
-                            CommandsInterface.SERVICE_CLASS_DATA +
-                            CommandsInterface.SERVICE_CLASS_FAX;
-
-            if (!mPhone.mIsTheCurrentActivePhone) {
-                Log.e(mLogTag, "Received message " + msg + "[" + msg.what
-                        + "] while being destroyed. Ignoring.");
-                return;
-            }
-
-            switch (msg.what) {
-                case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
-                    mState = null;
-                    updateStateProperty();
-                    broadcastIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_NOT_READY,
-                            null);
-                    break;
-                case EVENT_RADIO_ON:
-                    if (!is3gpp) {
-                        handleCdmaSubscriptionSource();
-                    }
-                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
-                    break;
-                case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
-                    handleCdmaSubscriptionSource();
-                    break;
-                case EVENT_ICC_READY:
-                    if(isSubscriptionFromIccCard) {
-                        mPhone.mCM.queryFacilityLock (
-                                CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
-                                obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
-                        mPhone.mCM.queryFacilityLock (
-                                CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
-                                obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
-                    }
-                    break;
-                case EVENT_ICC_LOCKED:
-                    mPhone.mCM.queryFacilityLock (
-                             CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
-                             obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
-                     break;
-                case EVENT_GET_ICC_STATUS_DONE:
-                    ar = (AsyncResult)msg.obj;
-
-                    getIccCardStatusDone(ar);
-                    break;
-                case EVENT_PINPUK_DONE:
-                    // a PIN/PUK/PIN2/PUK2/Network Personalization
-                    // request has completed. ar.userObj is the response Message
-                    // Repoll before returning
-                    ar = (AsyncResult)msg.obj;
-                    // TODO should abstract these exceptions
-                    AsyncResult.forMessage(((Message)ar.userObj)).exception
-                                                        = ar.exception;
-                    mPhone.mCM.getIccCardStatus(
-                        obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
-                    break;
-                case EVENT_REPOLL_STATUS_DONE:
-                    // Finished repolling status after PIN operation
-                    // ar.userObj is the response messaeg
-                    // ar.userObj.obj is already an AsyncResult with an
-                    // appropriate exception filled in if applicable
-
-                    ar = (AsyncResult)msg.obj;
-                    getIccCardStatusDone(ar);
-                    ((Message)ar.userObj).sendToTarget();
-                    break;
-                case EVENT_QUERY_FACILITY_LOCK_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    onQueryFacilityLock(ar);
-                    break;
-                case EVENT_QUERY_FACILITY_FDN_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    onQueryFdnEnabled(ar);
-                    break;
-                case EVENT_CHANGE_FACILITY_LOCK_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    if (ar.exception == null) {
-                        mIccPinLocked = mDesiredPinLocked;
-                        if (mDbg) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " +
-                                "mIccPinLocked= " + mIccPinLocked);
-                    } else {
-                        Log.e(mLogTag, "Error change facility lock with exception "
-                            + ar.exception);
-                    }
-                    AsyncResult.forMessage(((Message)ar.userObj)).exception
-                                                        = ar.exception;
-                    ((Message)ar.userObj).sendToTarget();
-                    break;
-                case EVENT_CHANGE_FACILITY_FDN_DONE:
-                    ar = (AsyncResult)msg.obj;
-
-                    if (ar.exception == null) {
-                        mIccFdnEnabled = mDesiredFdnEnabled;
-                        if (mDbg) log("EVENT_CHANGE_FACILITY_FDN_DONE: " +
-                                "mIccFdnEnabled=" + mIccFdnEnabled);
-                    } else {
-                        Log.e(mLogTag, "Error change facility fdn with exception "
-                                + ar.exception);
-                    }
-                    AsyncResult.forMessage(((Message)ar.userObj)).exception
-                                                        = ar.exception;
-                    ((Message)ar.userObj).sendToTarget();
-                    break;
-                case EVENT_CHANGE_ICC_PASSWORD_DONE:
-                    ar = (AsyncResult)msg.obj;
-                    if(ar.exception != null) {
-                        Log.e(mLogTag, "Error in change sim password with exception"
-                            + ar.exception);
-                    }
-                    AsyncResult.forMessage(((Message)ar.userObj)).exception
-                                                        = ar.exception;
-                    ((Message)ar.userObj).sendToTarget();
-                    break;
-                case EVENT_ICC_STATUS_CHANGED:
-                    Log.d(mLogTag, "Received Event EVENT_ICC_STATUS_CHANGED");
-                    mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
-                    break;
-                case EVENT_CARD_REMOVED:
-                    onIccSwap(false);
-                    break;
-                case EVENT_CARD_ADDED:
-                    onIccSwap(true);
-                    break;
-                default:
-                    Log.e(mLogTag, "[IccCard] Unknown Event " + msg.what);
-            }
-        }
-    };
-
-    private void handleCdmaSubscriptionSource() {
-        if(mCdmaSSM != null)  {
-            int newSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource();
-
-            Log.d(mLogTag, "Received Cdma subscription source: " + newSubscriptionSource);
-
-            boolean isNewSubFromRuim =
-                (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
-
-            if (isNewSubFromRuim != isSubscriptionFromIccCard) {
-                isSubscriptionFromIccCard = isNewSubFromRuim;
-                // Parse the Stored IccCardStatus Message to set mState correctly.
-                handleIccCardStatus(mIccCardStatus);
-            }
-        }
-    }
-
-    public IccCardConstants.State getIccCardState() {
-        if(!is3gpp && !isSubscriptionFromIccCard) {
-            // CDMA can get subscription from NV. In that case,
-            // subscription is ready as soon as Radio is ON.
-            return IccCardConstants.State.READY;
-        }
-
-        if (mIccCardStatus == null) {
-            Log.e(mLogTag, "[IccCard] IccCardStatus is null");
-            return IccCardConstants.State.ABSENT;
-        }
-
-        // this is common for all radio technologies
-        if (!mIccCardStatus.getCardState().isCardPresent()) {
-            return IccCardConstants.State.ABSENT;
-        }
-
-        RadioState currentRadioState = mPhone.mCM.getRadioState();
-        // check radio technology
-        if( currentRadioState == RadioState.RADIO_OFF         ||
-            currentRadioState == RadioState.RADIO_UNAVAILABLE) {
-            return IccCardConstants.State.NOT_READY;
-        }
-
-        if( currentRadioState == RadioState.RADIO_ON ) {
-            IccCardConstants.State csimState =
-                getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
-            IccCardConstants.State usimState =
-                getAppState(mIccCardStatus.getGsmUmtsSubscriptionAppIndex());
-
-            if(mDbg) log("USIM=" + usimState + " CSIM=" + csimState);
-
-            if (mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE) {
-                // UICC card contains both USIM and CSIM
-                // Return consolidated status
-                return getConsolidatedState(csimState, usimState, csimState);
-            }
-
-            // check for CDMA radio technology
-            if (!is3gpp) {
-                return csimState;
-            }
-            return usimState;
-        }
-
-        return IccCardConstants.State.ABSENT;
-    }
-
-    private IccCardConstants.State getAppState(int appIndex) {
-        IccCardApplication app;
-        if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) {
-            app = mIccCardStatus.getApplication(appIndex);
-        } else {
-            Log.e(mLogTag, "[IccCard] Invalid Subscription Application index:" + appIndex);
-            return IccCardConstants.State.ABSENT;
-        }
-
-        if (app == null) {
-            Log.e(mLogTag, "[IccCard] Subscription Application in not present");
-            return IccCardConstants.State.ABSENT;
-        }
-
-        // check if PIN required
-        if (app.pin1.isPermBlocked()) {
-            return IccCardConstants.State.PERM_DISABLED;
-        }
-        if (app.app_state.isPinRequired()) {
-            return IccCardConstants.State.PIN_REQUIRED;
-        }
-        if (app.app_state.isPukRequired()) {
-            return IccCardConstants.State.PUK_REQUIRED;
-        }
-        if (app.app_state.isSubscriptionPersoEnabled()) {
-            return IccCardConstants.State.NETWORK_LOCKED;
-        }
-        if (app.app_state.isAppReady()) {
-            return IccCardConstants.State.READY;
-        }
-        if (app.app_state.isAppNotReady()) {
-            return IccCardConstants.State.NOT_READY;
-        }
-        return IccCardConstants.State.NOT_READY;
-    }
-
-    private IccCardConstants.State getConsolidatedState(IccCardConstants.State left,
-            IccCardConstants.State right, IccCardConstants.State preferredState) {
-        // Check if either is absent.
-        if (right == IccCardConstants.State.ABSENT) return left;
-        if (left == IccCardConstants.State.ABSENT) return right;
-
-        // Only if both are ready, return ready
-        if ((left == IccCardConstants.State.READY) && (right == IccCardConstants.State.READY)) {
-            return IccCardConstants.State.READY;
-        }
-
-        // Case one is ready, but the other is not.
-        if (((right == IccCardConstants.State.NOT_READY) &&
-                (left == IccCardConstants.State.READY)) ||
-            ((left == IccCardConstants.State.NOT_READY) &&
-                    (right == IccCardConstants.State.READY))) {
-            return IccCardConstants.State.NOT_READY;
-        }
-
-        // At this point, the other state is assumed to be one of locked state
-        if (right == IccCardConstants.State.NOT_READY) return left;
-        if (left == IccCardConstants.State.NOT_READY) return right;
-
-        // At this point, FW currently just assumes the status will be
-        // consistent across the applications...
-        return preferredState;
-    }
-
-    public boolean isApplicationOnIcc(IccCardApplication.AppType type) {
-        if (mIccCardStatus == null) return false;
-
-        for (int i = 0 ; i < mIccCardStatus.getNumApplications(); i++) {
-            IccCardApplication app = mIccCardStatus.getApplication(i);
-            if (app != null && app.app_type == type) {
-                return true;
-            }
-        }
-        return false;
-    }
+    public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type);
 
     /**
      * @return true if a ICC card is present
      */
-    public boolean hasIccCard() {
-        if (mIccCardStatus == null) {
-            return false;
-        } else {
-            // Returns ICC card status for both GSM and CDMA mode
-            return mIccCardStatus.getCardState().isCardPresent();
-        }
-    }
-
-    private void log(String msg) {
-        Log.d(mLogTag, "[IccCard] " + msg);
-    }
-
-    protected int getCurrentApplicationIndex() {
-        if (is3gpp) {
-            return mIccCardStatus.getGsmUmtsSubscriptionAppIndex();
-        } else {
-            return mIccCardStatus.getCdmaSubscriptionAppIndex();
-        }
-    }
-
-    public String getAid() {
-        String aid = "";
-        if (mIccCardStatus == null) {
-            return aid;
-        }
-
-        int appIndex = getCurrentApplicationIndex();
-
-        if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) {
-            IccCardApplication app = mIccCardStatus.getApplication(appIndex);
-            if (app != null) {
-                aid = app.aid;
-            } else {
-                Log.e(mLogTag, "[IccCard] getAid: no current application index=" + appIndex);
-            }
-        } else {
-            Log.e(mLogTag, "[IccCard] getAid: Invalid Subscription Application index=" + appIndex);
-        }
-
-        return aid;
-    }
+    public boolean hasIccCard();
 }
index 45562ca..2bab4bb 100644 (file)
@@ -23,6 +23,13 @@ import android.os.Looper;
 import android.os.Message;
 import android.os.ServiceManager;
 
+import com.android.internal.telephony.uicc.AdnRecord;
+import com.android.internal.telephony.uicc.AdnRecordCache;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
+import com.android.internal.telephony.uicc.IccConstants;
+import com.android.internal.telephony.uicc.IccRecords;
+
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -103,11 +110,23 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
 
     public IccPhoneBookInterfaceManager(PhoneBase phone) {
         this.phone = phone;
+        IccRecords r = phone.mIccRecords.get();
+        if (r != null) {
+            adnCache = r.getAdnCache();
+        }
     }
 
     public void dispose() {
     }
 
+    public void updateIccRecords(IccRecords iccRecords) {
+        if (iccRecords != null) {
+            adnCache = iccRecords.getAdnCache();
+        } else {
+            adnCache = null;
+        }
+    }
+
     protected void publish() {
         //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
         ServiceManager.addService("simphonebook", this);
@@ -279,7 +298,7 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
     private int updateEfForIccType(int efid) {
         // Check if we are trying to read ADN records
         if (efid == IccConstants.EF_ADN) {
-            if (phone.getIccCard().isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) {
+            if (phone.getCurrentUiccAppType() == AppType.APPTYPE_USIM) {
                 return IccConstants.EF_PBR;
             }
         }
index 1c0fc52..6810fb0 100644 (file)
@@ -23,7 +23,10 @@ import android.os.Looper;
 import android.os.Message;
 import android.os.ServiceManager;
 import android.telephony.PhoneNumberUtils;
-import android.util.Log;
+import android.telephony.Rlog;
+
+import com.android.internal.telephony.uicc.AdnRecord;
+
 
 import java.util.ArrayList;
 import java.util.List;
index a66e19d..6f2c4ed 100644 (file)
@@ -25,13 +25,13 @@ import android.net.Uri;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.text.TextUtils;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import java.util.List;
 
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.AdnRecord;
 import com.android.internal.telephony.IIccPhoneBook;
+import com.android.internal.telephony.uicc.AdnRecord;
+import com.android.internal.telephony.uicc.IccConstants;
 
 
 /**
@@ -207,12 +207,7 @@ public class IccProvider extends ContentProvider {
             String param = tokens[n];
             if (DBG) log("parsing '" + param + "'");
 
-            String[] pair = param.split("=");
-
-            if (pair.length != 2) {
-                Log.e(TAG, "resolve: bad whereClause parameter: " + param);
-                continue;
-            }
+            String[] pair = param.split("=", 2);
 
             String key = pair[0].trim();
             String val = pair[1].trim();
@@ -312,7 +307,7 @@ public class IccProvider extends ContentProvider {
             return cursor;
         } else {
             // No results to load
-            Log.w(TAG, "Cannot load ADN records");
+            Rlog.w(TAG, "Cannot load ADN records");
             return new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES);
         }
     }
@@ -425,7 +420,7 @@ public class IccProvider extends ContentProvider {
     }
 
     private void log(String msg) {
-        Log.d(TAG, "[IccProvider] " + msg);
+        Rlog.d(TAG, "[IccProvider] " + msg);
     }
 
 }
index 5fef6de..b911b10 100644 (file)
@@ -18,8 +18,10 @@ package com.android.internal.telephony;
 
 import android.app.PendingIntent;
 import android.content.Context;
+import android.telephony.Rlog;
 import android.util.Log;
 
+import com.android.internal.telephony.uicc.IccConstants;
 import com.android.internal.util.HexDump;
 
 import java.util.ArrayList;
@@ -78,7 +80,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub {
         mPhone.getContext().enforceCallingPermission(
                 "android.permission.SEND_SMS",
                 "Sending SMS message");
-        if (Log.isLoggable("SMS", Log.VERBOSE)) {
+        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
             log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
                 destPort + " data='"+ HexDump.toHexString(data)  + "' sentIntent=" +
                 sentIntent + " deliveryIntent=" + deliveryIntent);
@@ -115,7 +117,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub {
         mPhone.getContext().enforceCallingPermission(
                 "android.permission.SEND_SMS",
                 "Sending SMS message");
-        if (Log.isLoggable("SMS", Log.VERBOSE)) {
+        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
             log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +
                 " text='"+ text + "' sentIntent=" +
                 sentIntent + " deliveryIntent=" + deliveryIntent);
@@ -153,7 +155,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub {
         mPhone.getContext().enforceCallingPermission(
                 "android.permission.SEND_SMS",
                 "Sending SMS message");
-        if (Log.isLoggable("SMS", Log.VERBOSE)) {
+        if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
             int i = 0;
             for (String part : parts) {
                 log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr +
@@ -164,6 +166,14 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub {
                 (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
     }
 
+    public int getPremiumSmsPermission(String packageName) {
+        return mDispatcher.getPremiumSmsPermission(packageName);
+    }
+
+    public void setPremiumSmsPermission(String packageName, int permission) {
+        mDispatcher.setPremiumSmsPermission(packageName, permission);
+    }
+
     /**
      * create SmsRawData lists from all sms record byte[]
      * Use null to indicate "free" record
index 54de508..f80aa67 100644 (file)
@@ -85,4 +85,12 @@ public class IccSmsInterfaceManagerProxy extends ISms.Stub {
             throws android.os.RemoteException {
         return mIccSmsInterfaceManager.disableCellBroadcastRange(startMessageId, endMessageId);
     }
+
+    public int getPremiumSmsPermission(String packageName) {
+        return mIccSmsInterfaceManager.getPremiumSmsPermission(packageName);
+    }
+
+    public void setPremiumSmsPermission(String packageName, int permission) {
+        mIccSmsInterfaceManager.setPremiumSmsPermission(packageName, permission);
+    }
 }
index a966f76..795740c 100644 (file)
@@ -20,7 +20,7 @@ import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.graphics.Bitmap;
 import android.graphics.Color;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.telephony.GsmAlphabet;
 import java.io.UnsupportedEncodingException;
@@ -187,7 +187,7 @@ public class IccUtils {
                 try {
                     ret = new String(data, offset + 1, ucslen * 2, "utf-16be");
                 } catch (UnsupportedEncodingException ex) {
-                    Log.e(LOG_TAG, "implausible UnsupportedEncodingException",
+                    Rlog.e(LOG_TAG, "implausible UnsupportedEncodingException",
                           ex);
                 }
 
@@ -360,7 +360,7 @@ public class IccUtils {
                             offset + 1, length - 1, "utf-16");
                 } catch (UnsupportedEncodingException ex) {
                     ret = "";
-                    Log.e(LOG_TAG,"implausible UnsupportedEncodingException", ex);
+                    Rlog.e(LOG_TAG,"implausible UnsupportedEncodingException", ex);
                 }
             break;
 
@@ -409,7 +409,7 @@ public class IccUtils {
         };
 
         if (pixelIndex != numOfPixels) {
-            Log.e(LOG_TAG, "parse end and size error");
+            Rlog.e(LOG_TAG, "parse end and size error");
         }
         return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
     }
@@ -461,7 +461,7 @@ public class IccUtils {
     private static int[] mapTo2OrderBitColor(byte[] data, int valueIndex,
             int length, int[] colorArray, int bits) {
         if (0 != (8 % bits)) {
-            Log.e(LOG_TAG, "not event number of color");
+            Rlog.e(LOG_TAG, "not event number of color");
             return mapToNon2OrderBitColor(data, valueIndex, length, colorArray,
                     bits);
         }
@@ -499,7 +499,7 @@ public class IccUtils {
     private static int[] mapToNon2OrderBitColor(byte[] data, int valueIndex,
             int length, int[] colorArray, int bits) {
         if (0 == (8 % bits)) {
-            Log.e(LOG_TAG, "not odd number of color");
+            Rlog.e(LOG_TAG, "not odd number of color");
             return mapTo2OrderBitColor(data, valueIndex, length, colorArray,
                     bits);
         }
index cb33521..7d5a4e7 100644 (file)
@@ -26,7 +26,7 @@ import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -180,11 +180,11 @@ public final class MccTable
                 mcc = Integer.parseInt(mccmnc.substring(0,3));
                 mnc = Integer.parseInt(mccmnc.substring(3));
             } catch (NumberFormatException e) {
-                Log.e(LOG_TAG, "Error parsing IMSI");
+                Rlog.e(LOG_TAG, "Error parsing IMSI");
                 return;
             }
 
-            Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
+            Rlog.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
 
             if (mcc != 0) {
                 setTimezoneFromMccIfNeeded(context, mcc);
@@ -201,7 +201,7 @@ public final class MccTable
                 }
                 ActivityManagerNative.getDefault().updateConfiguration(config);
             } catch (RemoteException e) {
-                Log.e(LOG_TAG, "Can't update configuration", e);
+                Rlog.e(LOG_TAG, "Can't update configuration", e);
             }
         }
     }
@@ -273,7 +273,7 @@ public final class MccTable
                 AlarmManager alarm =
                         (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                 alarm.setTimeZone(zoneId);
-                Log.d(LOG_TAG, "timezone set to "+zoneId);
+                Rlog.d(LOG_TAG, "timezone set to "+zoneId);
             }
         }
     }
@@ -292,7 +292,7 @@ public final class MccTable
         String language = MccTable.defaultLanguageForMcc(mcc);
         String country = MccTable.countryCodeForMcc(mcc);
 
-        Log.d(LOG_TAG, "locale set to "+language+"_"+country);
+        Rlog.d(LOG_TAG, "locale set to "+language+"_"+country);
         setSystemLocale(context, language, country);
     }
 
@@ -305,7 +305,7 @@ public final class MccTable
     private static void setWifiCountryCodeFromMcc(Context context, int mcc) {
         String country = MccTable.countryCodeForMcc(mcc);
         if (!country.isEmpty()) {
-            Log.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country);
+            Rlog.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country);
             WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
             //persist
             wM.setCountryCode(country, true);
index 34aa96c..fbce476 100644 (file)
@@ -22,15 +22,16 @@ import android.net.LinkProperties;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
+import android.telephony.CellInfo;
 import android.telephony.CellLocation;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 
 import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
 import com.android.internal.telephony.test.SimulatedRadioControl;
+import com.android.internal.telephony.uicc.IsimRecords;
+import com.android.internal.telephony.uicc.UsimServiceTable;
 
 import com.android.internal.telephony.PhoneConstants.*; // ???? 
 
@@ -125,9 +126,12 @@ public interface Phone {
     int NT_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
     int NT_MODE_GLOBAL       = RILConstants.NETWORK_MODE_GLOBAL;
 
-    int NT_MODE_LTE_ONLY     = RILConstants.NETWORK_MODE_LTE_ONLY;
-    int PREFERRED_NT_MODE    = RILConstants.PREFERRED_NETWORK_MODE;
-
+    int NT_MODE_LTE_CDMA_AND_EVDO        = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO;
+    int NT_MODE_LTE_GSM_WCDMA            = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA;
+    int NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA  = RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA;
+    int NT_MODE_LTE_ONLY                 = RILConstants.NETWORK_MODE_LTE_ONLY;
+    int NT_MODE_LTE_WCDMA                = RILConstants.NETWORK_MODE_LTE_WCDMA;
+    int PREFERRED_NT_MODE                = RILConstants.PREFERRED_NETWORK_MODE;
 
     // Used for CDMA roaming mode
     static final int CDMA_RM_HOME        = 0;  // Home Networks only, as defined in PRL
@@ -135,6 +139,7 @@ public interface Phone {
     static final int CDMA_RM_ANY         = 2;  // Roaming on Any Network, as defined in PRL
 
     // Used for CDMA subscription mode
+    static final int CDMA_SUBSCRIPTION_UNKNOWN  =-1; // Unknown
     static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // RUIM/SIM (default)
     static final int CDMA_SUBSCRIPTION_NV       = 1; // NV -> non-volatile memory
 
@@ -176,6 +181,11 @@ public interface Phone {
     CellLocation getCellLocation();
 
     /**
+     * @return all available cell information or null if none.
+     */
+    public List<CellInfo> getAllCellInfo();
+
+    /**
      * Get the current for the default apn DataState. No change notification
      * exists at this interface -- use
      * {@link android.telephony.PhoneStateListener} instead.
index b55240a..c62f72f 100644 (file)
@@ -32,18 +32,27 @@ import android.os.RegistrantList;
 import android.os.SystemProperties;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.telephony.CellInfo;
 import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
 import android.text.TextUtils;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.R;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
 import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.gsm.SIMRecords;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
+import com.android.internal.telephony.uicc.IccFileHandler;
+import com.android.internal.telephony.uicc.IccRecords;
+import com.android.internal.telephony.uicc.IsimRecords;
+import com.android.internal.telephony.uicc.SIMRecords;
+import com.android.internal.telephony.uicc.UiccCardApplication;
+import com.android.internal.telephony.uicc.UiccController;
+import com.android.internal.telephony.uicc.UsimServiceTable;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -110,6 +119,7 @@ public abstract class PhoneBase extends Handler implements Phone {
     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
     protected static final int EVENT_NEW_ICC_SMS                    = 29;
     protected static final int EVENT_ICC_RECORD_EVENTS              = 30;
+    protected static final int EVENT_ICC_CHANGED                    = 31;
 
     // Key used to read/write current CLIR setting
     public static final String CLIR_KEY = "clir_key";
@@ -126,10 +136,12 @@ public abstract class PhoneBase extends Handler implements Phone {
     int mCallRingDelay;
     public boolean mIsTheCurrentActivePhone = true;
     boolean mIsVoiceCapable = true;
-    public IccRecords mIccRecords;
-    protected AtomicReference<IccCard> mIccCard = new AtomicReference<IccCard>();
+    protected UiccController mUiccController = null;
+    public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
     public SmsStorageMonitor mSmsStorageMonitor;
     public SmsUsageMonitor mSmsUsageMonitor;
+    protected AtomicReference<UiccCardApplication> mUiccApplication =
+            new AtomicReference<UiccCardApplication>();
     public SMSDispatcher mSMS;
 
     /**
@@ -189,9 +201,10 @@ public abstract class PhoneBase extends Handler implements Phone {
     /**
      * Constructs a PhoneBase in normal (non-unit test) mode.
      *
-     * @param context Context object from hosting application
      * @param notifier An instance of DefaultPhoneNotifier,
+     * @param context Context object from hosting application
      * unless unit testing.
+     * @param ci the CommandsInterface
      */
     protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci) {
         this(notifier, context, ci, false);
@@ -200,9 +213,10 @@ public abstract class PhoneBase extends Handler implements Phone {
     /**
      * Constructs a PhoneBase in normal (non-unit test) mode.
      *
-     * @param context Context object from hosting application
      * @param notifier An instance of DefaultPhoneNotifier,
+     * @param context Context object from hosting application
      * unless unit testing.
+     * @param ci is CommandsInterface
      * @param unitTestMode when true, prevents notifications
      * of state change events
      */
@@ -242,15 +256,17 @@ public abstract class PhoneBase extends Handler implements Phone {
          */
         mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
                 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
-        Log.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
+        Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
 
         mCallRingDelay = SystemProperties.getInt(
                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
-        Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
+        Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
 
         // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
         mSmsStorageMonitor = new SmsStorageMonitor(this);
         mSmsUsageMonitor = new SmsUsageMonitor(context);
+        mUiccController = UiccController.getInstance();
+        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
     }
 
     public void dispose() {
@@ -262,6 +278,7 @@ public abstract class PhoneBase extends Handler implements Phone {
             // Dispose the SMS usage and storage monitors
             mSmsStorageMonitor.dispose();
             mSmsUsageMonitor.dispose();
+            mUiccController.unregisterForIccChanged(this);
         }
     }
 
@@ -269,9 +286,10 @@ public abstract class PhoneBase extends Handler implements Phone {
         mSmsStorageMonitor = null;
         mSmsUsageMonitor = null;
         mSMS = null;
-        mIccRecords = null;
-        mIccCard.set(null);
+        mIccRecords.set(null);
+        mUiccApplication.set(null);
         mDataConnectionTracker = null;
+        mUiccController = null;
     }
 
     /**
@@ -287,7 +305,7 @@ public abstract class PhoneBase extends Handler implements Phone {
 
         switch(msg.what) {
             case EVENT_CALL_RING:
-                Log.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
+                Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
                 ar = (AsyncResult)msg.obj;
                 if (ar.exception == null) {
                     PhoneConstants.State state = getState();
@@ -303,12 +321,16 @@ public abstract class PhoneBase extends Handler implements Phone {
                 break;
 
             case EVENT_CALL_RING_CONTINUE:
-                Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
+                Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
                 if (getState() == PhoneConstants.State.RINGING) {
                     sendIncomingCallRingNotification(msg.arg1);
                 }
                 break;
 
+            case EVENT_ICC_CHANGED:
+                onUpdateIccAvailability();
+                break;
+
             default:
                 throw new RuntimeException("unexpected event not handled");
         }
@@ -319,6 +341,9 @@ public abstract class PhoneBase extends Handler implements Phone {
         return mContext;
     }
 
+    // Will be called when icc changed
+    protected abstract void onUpdateIccAvailability();
+
     /**
      * Disables the DNS check (i.e., allows "0.0.0.0").
      * Useful for lab testing environment.
@@ -611,8 +636,8 @@ public abstract class PhoneBase extends Handler implements Phone {
 
                 if (!country.isEmpty()) {
                     try {
-                        Settings.Secure.getInt(mContext.getContentResolver(),
-                                Settings.Secure.WIFI_COUNTRY_CODE);
+                        Settings.Global.getInt(mContext.getContentResolver(),
+                                Settings.Global.WIFI_COUNTRY_CODE);
                     } catch (Settings.SettingNotFoundException e) {
                         // note this is not persisting
                         WifiManager wM = (WifiManager)
@@ -634,9 +659,9 @@ public abstract class PhoneBase extends Handler implements Phone {
      * Retrieves the IccFileHandler of the Phone instance
      */
     public IccFileHandler getIccFileHandler(){
-        IccCard iccCard = mIccCard.get();
-        if (iccCard == null) return null;
-        return iccCard.getIccFileHandler();
+        UiccCardApplication uiccApplication = mUiccApplication.get();
+        if (uiccApplication == null) return null;
+        return uiccApplication.getIccFileHandler();
     }
 
     /*
@@ -660,29 +685,50 @@ public abstract class PhoneBase extends Handler implements Phone {
         return null;
     }
 
+    public AppType getCurrentUiccAppType() {
+        UiccCardApplication currentApp = mUiccApplication.get();
+        if (currentApp != null) {
+            return currentApp.getType();
+        }
+        return AppType.APPTYPE_UNKNOWN;
+    }
+
     @Override
     public IccCard getIccCard() {
-        return mIccCard.get();
+        return null;
+        //throw new Exception("getIccCard Shouldn't be called from PhoneBase");
     }
 
     @Override
     public String getIccSerialNumber() {
-        return mIccRecords.iccid;
+        IccRecords r = mIccRecords.get();
+        return (r != null) ? r.iccid : "";
     }
 
     @Override
     public boolean getIccRecordsLoaded() {
-        return mIccRecords.getRecordsLoaded();
+        IccRecords r = mIccRecords.get();
+        return (r != null) ? r.getRecordsLoaded() : false;
+    }
+
+    /**
+     * @return all available cell information or null if none.
+     */
+    @Override
+    public List<CellInfo> getAllCellInfo() {
+        return getServiceStateTracker().getAllCellInfo();
     }
 
     @Override
     public boolean getMessageWaitingIndicator() {
-        return mIccRecords.getVoiceMessageWaiting();
+        IccRecords r = mIccRecords.get();
+        return (r != null) ? r.getVoiceMessageWaiting() : false;
     }
 
     @Override
     public boolean getCallForwardingIndicator() {
-        return mIccRecords.getVoiceCallForwardingFlag();
+        IccRecords r = mIccRecords.get();
+        return (r != null) ? r.getVoiceCallForwardingFlag() : false;
     }
 
     /**
@@ -693,6 +739,19 @@ public abstract class PhoneBase extends Handler implements Phone {
     }
 
     /**
+     * Get the signal strength
+     */
+    @Override
+    public SignalStrength getSignalStrength() {
+        ServiceStateTracker sst = getServiceStateTracker();
+        if (sst == null) {
+            return new SignalStrength();
+        } else {
+            return sst.getSignalStrength();
+        }
+    }
+
+    /**
      *  Set the status of the CDMA roaming preference
      */
     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
@@ -792,6 +851,14 @@ public abstract class PhoneBase extends Handler implements Phone {
         mNotifier.notifyOtaspChanged(this, otaspMode);
     }
 
+    public void notifySignalStrength() {
+        mNotifier.notifySignalStrength(this);
+    }
+
+    public void notifyCellInfo(List<CellInfo> cellInfo) {
+        mNotifier.notifyCellInfo(this, cellInfo);
+    }
+
     /**
      * @return true if a mobile originating emergency call is active
      */
@@ -1054,12 +1121,12 @@ public abstract class PhoneBase extends Handler implements Phone {
     private void sendIncomingCallRingNotification(int token) {
         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
                 (token == mCallRingContinueToken)) {
-            Log.d(LOG_TAG, "Sending notifyIncomingRing");
+            Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
             notifyIncomingRing();
             sendMessageDelayed(
                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
         } else {
-            Log.d(LOG_TAG, "Ignoring ring notification request,"
+            Rlog.d(LOG_TAG, "Ignoring ring notification request,"
                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
                     + " token=" + token
                     + " mCallRingContinueToken=" + mCallRingContinueToken
@@ -1075,12 +1142,12 @@ public abstract class PhoneBase extends Handler implements Phone {
     }
 
     public IsimRecords getIsimRecords() {
-        Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
+        Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
         return null;
     }
 
     public void requestIsimAuthentication(String nonce, Message result) {
-        Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices");
+        Rlog.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices");
     }
 
     public String getMsisdn() {
@@ -1093,7 +1160,7 @@ public abstract class PhoneBase extends Handler implements Phone {
      */
     private static void logUnexpectedCdmaMethodCall(String name)
     {
-        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
+        Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
                 "called, CDMAPhone inactive.");
     }
 
@@ -1105,14 +1172,14 @@ public abstract class PhoneBase extends Handler implements Phone {
      * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
      */
     private static void logUnexpectedGsmMethodCall(String name) {
-        Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
+        Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
                 "called, GSMPhone inactive.");
     }
 
     // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
     public void notifyCallForwardingIndicator() {
         // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
-        Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+        Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
     }
 
     public void notifyDataConnectionFailed(String reason, String apnType) {
@@ -1136,7 +1203,10 @@ public abstract class PhoneBase extends Handler implements Phone {
      */
     @Override
     public void setVoiceMessageWaiting(int line, int countWaiting) {
-        mIccRecords.setVoiceMessageWaiting(line, countWaiting);
+        IccRecords r = mIccRecords.get();
+        if (r != null) {
+            r.setVoiceMessageWaiting(line, countWaiting);
+        }
     }
 
     /**
@@ -1145,7 +1215,8 @@ public abstract class PhoneBase extends Handler implements Phone {
      */
     @Override
     public UsimServiceTable getUsimServiceTable() {
-        return mIccRecords.getUsimServiceTable();
+        IccRecords r = mIccRecords.get();
+        return (r != null) ? r.getUsimServiceTable() : null;
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1158,8 +1229,8 @@ public abstract class PhoneBase extends Handler implements Phone {
         pw.println(" mCallRingDelay=" + mCallRingDelay);
         pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
         pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
-        pw.println(" mIccRecords=" + mIccRecords);
-        pw.println(" mIccCard=" + mIccCard.get());
+        pw.println(" mIccRecords=" + mIccRecords.get());
+        pw.println(" mUiccApplication=" + mUiccApplication.get());
         pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
         pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
         pw.println(" mSMS=" + mSMS);
index 2c85dc6..c0641d5 100644 (file)
@@ -21,7 +21,7 @@ import android.net.LocalServerSocket;
 import android.os.Looper;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
-import android.util.Log;
+import android.telephony.Rlog;
 import android.os.SystemProperties;
 
 import com.android.internal.telephony.cdma.CDMAPhone;
@@ -30,6 +30,7 @@ import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.gsm.GSMPhone;
 import com.android.internal.telephony.sip.SipPhone;
 import com.android.internal.telephony.sip.SipPhoneFactory;
+import com.android.internal.telephony.uicc.UiccController;
 
 /**
  * {@hide}
@@ -105,9 +106,9 @@ public class PhoneFactory {
                 if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
                     preferredNetworkMode = Phone.NT_MODE_GLOBAL;
                 }
-                int networkMode = Settings.Secure.getInt(context.getContentResolver(),
-                        Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
-                Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
+                int networkMode = Settings.Global.getInt(context.getContentResolver(),
+                        Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);
+                Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
 
                 // Get cdmaSubscription
                 // TODO: Change when the ril will provides a way to know at runtime
@@ -118,41 +119,44 @@ public class PhoneFactory {
                 switch (lteOnCdma) {
                     case PhoneConstants.LTE_ON_CDMA_FALSE:
                         cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV;
-                        Log.i(LOG_TAG, "lteOnCdma is 0 use SUBSCRIPTION_FROM_NV");
+                        Rlog.i(LOG_TAG, "lteOnCdma is 0 use SUBSCRIPTION_FROM_NV");
                         break;
                     case PhoneConstants.LTE_ON_CDMA_TRUE:
                         cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM;
-                        Log.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM");
+                        Rlog.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM");
                         break;
                     case PhoneConstants.LTE_ON_CDMA_UNKNOWN:
                     default:
                         //Get cdmaSubscription mode from Settings.System
-                        cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(),
-                                Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
+                        cdmaSubscription = Settings.Global.getInt(context.getContentResolver(),
+                                Settings.Global.PREFERRED_CDMA_SUBSCRIPTION,
                                 preferredCdmaSubscription);
-                        Log.i(LOG_TAG, "lteOnCdma not set, using PREFERRED_CDMA_SUBSCRIPTION");
+                        Rlog.i(LOG_TAG, "lteOnCdma not set, using PREFERRED_CDMA_SUBSCRIPTION");
                         break;
                 }
-                Log.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
+                Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
 
                 //reads the system properties and makes commandsinterface
                 sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
 
+                // Instantiate UiccController so that all other classes can just call getInstance()
+                UiccController.make(context, sCommandsInterface);
+
                 int phoneType = TelephonyManager.getPhoneType(networkMode);
                 if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    Log.i(LOG_TAG, "Creating GSMPhone");
+                    Rlog.i(LOG_TAG, "Creating GSMPhone");
                     sProxyPhone = new PhoneProxy(new GSMPhone(context,
                             sCommandsInterface, sPhoneNotifier));
                 } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                     switch (TelephonyManager.getLteOnCdmaModeStatic()) {
                         case PhoneConstants.LTE_ON_CDMA_TRUE:
-                            Log.i(LOG_TAG, "Creating CDMALTEPhone");
+                            Rlog.i(LOG_TAG, "Creating CDMALTEPhone");
                             sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
                                 sCommandsInterface, sPhoneNotifier));
                             break;
                         case PhoneConstants.LTE_ON_CDMA_FALSE:
                         default:
-                            Log.i(LOG_TAG, "Creating CDMAPhone");
+                            Rlog.i(LOG_TAG, "Creating CDMAPhone");
                             sProxyPhone = new PhoneProxy(new CDMAPhone(context,
                                     sCommandsInterface, sPhoneNotifier));
                             break;
index efc7a13..0a4a05d 100644 (file)
@@ -18,6 +18,8 @@ package com.android.internal.telephony;
 
 import android.telephony.CellInfo;
 
+import java.util.List;
+
 /**
  * {@hide}
  */
@@ -45,6 +47,5 @@ public interface PhoneNotifier {
 
     public void notifyOtaspChanged(Phone sender, int otaspMode);
 
-    // TODO - trigger notifyCellInfo from ServiceStateTracker
-    public void notifyCellInfo(Phone sender, CellInfo cellInfo);
+    public void notifyCellInfo(Phone sender, List<CellInfo> cellInfo);
 }
index 77135d4..300529b 100644 (file)
@@ -26,16 +26,19 @@ import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.telephony.CellInfo;
 import android.telephony.CellLocation;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.telephony.cdma.CDMAPhone;
 import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
 import com.android.internal.telephony.test.SimulatedRadioControl;
+import com.android.internal.telephony.uicc.IccCardProxy;
+import com.android.internal.telephony.uicc.IsimRecords;
+import com.android.internal.telephony.uicc.UsimServiceTable;
 import com.android.internal.telephony.CallManager;
 
 import java.util.List;
@@ -48,6 +51,7 @@ public class PhoneProxy extends Handler implements Phone {
     private IccSmsInterfaceManagerProxy mIccSmsInterfaceManagerProxy;
     private IccPhoneBookInterfaceManagerProxy mIccPhoneBookInterfaceManagerProxy;
     private PhoneSubInfoProxy mPhoneSubInfoProxy;
+    private IccCardProxy mIccCardProxy;
 
     private boolean mResetModemOnRadioTechnologyChange = false;
 
@@ -61,7 +65,7 @@ public class PhoneProxy extends Handler implements Phone {
     private static final String LOG_TAG = "PHONE";
 
     //***** Class Methods
-    public PhoneProxy(Phone phone) {
+    public PhoneProxy(PhoneBase phone) {
         mActivePhone = phone;
         mResetModemOnRadioTechnologyChange = SystemProperties.getBoolean(
                 TelephonyProperties.PROPERTY_RESET_ON_RADIO_TECH_CHANGE, false);
@@ -76,6 +80,13 @@ public class PhoneProxy extends Handler implements Phone {
         mCommandsInterface.registerForOn(this, EVENT_RADIO_ON, null);
         mCommandsInterface.registerForVoiceRadioTechChanged(
                              this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
+        mIccCardProxy = new IccCardProxy(phone.getContext(), mCommandsInterface);
+        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) {
+            // For the purpose of IccCardProxy we only care about the technology family
+            mIccCardProxy.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
+        } else if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            mIccCardProxy.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT);
+        }
     }
 
     @Override
@@ -121,15 +132,15 @@ public class PhoneProxy extends Handler implements Phone {
     }
 
     private static void logd(String msg) {
-        Log.d(LOG_TAG, "[PhoneProxy] " + msg);
+        Rlog.d(LOG_TAG, "[PhoneProxy] " + msg);
     }
 
     private void logw(String msg) {
-        Log.w(LOG_TAG, "[PhoneProxy] " + msg);
+        Rlog.w(LOG_TAG, "[PhoneProxy] " + msg);
     }
 
     private void loge(String msg) {
-        Log.e(LOG_TAG, "[PhoneProxy] " + msg);
+        Rlog.e(LOG_TAG, "[PhoneProxy] " + msg);
     }
 
     private void updatePhoneObject(int newVoiceRadioTech) {
@@ -197,12 +208,13 @@ public class PhoneProxy extends Handler implements Phone {
         mPhoneSubInfoProxy.setmPhoneSubInfo(this.mActivePhone.getPhoneSubInfo());
 
         mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
+        mIccCardProxy.setVoiceRadioTech(newVoiceRadioTech);
 
         // Send an Intent to the PhoneApp that we had a radio technology change
         Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
         intent.putExtra(PhoneConstants.PHONE_NAME_KEY, mActivePhone.getPhoneName());
-        ActivityManagerNative.broadcastStickyIntent(intent, null);
+        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
 
     }
 
@@ -256,6 +268,14 @@ public class PhoneProxy extends Handler implements Phone {
         return mActivePhone.getCellLocation();
     }
 
+    /**
+     * @return all available cell information or null if none.
+     */
+    @Override
+    public List<CellInfo> getAllCellInfo() {
+        return mActivePhone.getAllCellInfo();
+    }
+
     public PhoneConstants.DataState getDataConnectionState() {
         return mActivePhone.getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
     }
@@ -457,11 +477,11 @@ public class PhoneProxy extends Handler implements Phone {
     }
 
     public boolean getIccRecordsLoaded() {
-        return mActivePhone.getIccRecordsLoaded();
+        return mIccCardProxy.getIccRecordsLoaded();
     }
 
     public IccCard getIccCard() {
-        return mActivePhone.getIccCard();
+        return mIccCardProxy;
     }
 
     public void acceptCall() throws CallStateException {
index 89084ac..40f0c34 100644 (file)
@@ -25,7 +25,7 @@ import android.os.Message;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
-import android.util.Log;
+import android.telephony.Rlog;
 
 /**
  *
@@ -174,7 +174,7 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
                     mTarget.sendMessage(message);
                 }
             } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
-                if (DBG) Log.d(LOG_TAG, "onReceiveIntent: ACTION_PHONE_STATE_CHANGED, state="
+                if (DBG) Rlog.d(LOG_TAG, "onReceiveIntent: ACTION_PHONE_STATE_CHANGED, state="
                                + intent.getStringExtra(PhoneConstants.STATE_KEY));
                 String phoneState = intent.getStringExtra(PhoneConstants.STATE_KEY);
                 mPhoneState = (PhoneConstants.State) Enum.valueOf(
@@ -195,7 +195,7 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
                 }
             }
         } catch (Exception ex) {
-            Log.e(LOG_TAG, "[PhoneStateIntentRecv] caught " + ex);
+            Rlog.e(LOG_TAG, "[PhoneStateIntentRecv] caught " + ex);
             ex.printStackTrace();
         }
     }
index e8449ce..cbab817 100755 (executable)
@@ -22,9 +22,9 @@ import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.telephony.PhoneNumberUtils;
-import android.util.Log;
+import android.telephony.Rlog;
 
-import com.android.internal.telephony.ims.IsimRecords;
+import com.android.internal.telephony.uicc.IsimRecords;
 
 public class PhoneSubInfo extends IPhoneSubInfo.Stub {
     static final String LOG_TAG = "PHONE";
@@ -50,9 +50,9 @@ public class PhoneSubInfo extends IPhoneSubInfo.Stub {
         try {
             super.finalize();
         } catch (Throwable throwable) {
-            Log.e(LOG_TAG, "Error while finalizing:", throwable);
+            Rlog.e(LOG_TAG, "Error while finalizing:", throwable);
         }
-        Log.d(LOG_TAG, "PhoneSubInfo finalized");
+        Rlog.d(LOG_TAG, "PhoneSubInfo finalized");
     }
 
     /**
@@ -118,7 +118,7 @@ public class PhoneSubInfo extends IPhoneSubInfo.Stub {
     public String getVoiceMailNumber() {
         mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
         String number = PhoneNumberUtils.extractNetworkPortion(mPhone.getVoiceMailNumber());
-        Log.d(LOG_TAG, "VM: PhoneSubInfo.getVoiceMailNUmber: "); // + number);
+        Rlog.d(LOG_TAG, "VM: PhoneSubInfo.getVoiceMailNUmber: "); // + number);
         return number;
     }
 
@@ -131,7 +131,7 @@ public class PhoneSubInfo extends IPhoneSubInfo.Stub {
         mContext.enforceCallingOrSelfPermission(CALL_PRIVILEGED,
                 "Requires CALL_PRIVILEGED");
         String number = mPhone.getVoiceMailNumber();
-        Log.d(LOG_TAG, "VM: PhoneSubInfo.getCompleteVoiceMailNUmber: "); // + number);
+        Rlog.d(LOG_TAG, "VM: PhoneSubInfo.getCompleteVoiceMailNUmber: "); // + number);
         return number;
     }
 
index b14f6c8..c3256df 100644 (file)
@@ -43,16 +43,21 @@ import android.os.SystemProperties;
 import android.os.PowerManager.WakeLock;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.PhoneNumberUtils;
+import android.telephony.SignalStrength;
 import android.telephony.SmsManager;
 import android.telephony.SmsMessage;
 import android.text.TextUtils;
-import android.util.Log;
+import android.telephony.Rlog;
 
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus;
+import com.android.internal.telephony.uicc.IccCardStatus;
+import com.android.internal.telephony.uicc.IccIoResult;
+import com.android.internal.telephony.uicc.IccRefreshResponse;
+import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
 import com.android.internal.telephony.cdma.CdmaInformationRecords;
-import com.android.internal.telephony.IccRefreshResponse;
 
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
@@ -177,7 +182,7 @@ class RILRequest {
 
         ex = CommandException.fromRilErrno(error);
 
-        if (RIL.RILJ_LOGD) Log.d(LOG_TAG, serialString() + "< "
+        if (RIL.RILJ_LOGD) Rlog.d(LOG_TAG, serialString() + "< "
             + RIL.requestToString(mRequest)
             + " error: " + ex);
 
@@ -196,7 +201,6 @@ class RILRequest {
 
 /**
  * RIL implementation of the CommandsInterface.
- * FIXME public only for testing
  *
  * {@hide}
  */
@@ -268,7 +272,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
             } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                 sendScreenState(false);
             } else {
-                Log.w(LOG_TAG, "RIL received unexpected Intent: " + intent.getAction());
+                Rlog.w(LOG_TAG, "RIL received unexpected Intent: " + intent.getAction());
             }
         }
     };
@@ -342,12 +346,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                         dataLength[2] = (byte)((data.length >> 8) & 0xff);
                         dataLength[3] = (byte)((data.length) & 0xff);
 
-                        //Log.v(LOG_TAG, "writing packet: " + data.length + " bytes");
+                        //Rlog.v(LOG_TAG, "writing packet: " + data.length + " bytes");
 
                         s.getOutputStream().write(dataLength);
                         s.getOutputStream().write(data);
                     } catch (IOException ex) {
-                        Log.e(LOG_TAG, "IOException", ex);
+                        Rlog.e(LOG_TAG, "IOException", ex);
                         req = findAndRemoveRequestFromList(rr.mSerial);
                         // make sure this request has not already been handled,
                         // eg, if RILReceiver cleared the list.
@@ -356,7 +360,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                             rr.release();
                         }
                     } catch (RuntimeException exc) {
-                        Log.e(LOG_TAG, "Uncaught exception ", exc);
+                        Rlog.e(LOG_TAG, "Uncaught exception ", exc);
                         req = findAndRemoveRequestFromList(rr.mSerial);
                         // make sure this request has not already been handled,
                         // eg, if RILReceiver cleared the list.
@@ -392,7 +396,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                             // Note: Keep mRequestList so that delayed response
                             // can still be handled when response finally comes.
                             if (mRequestMessagesWaiting != 0) {
-                                Log.d(LOG_TAG, "NOTE: mReqWaiting is NOT 0 but"
+                                Rlog.d(LOG_TAG, "NOTE: mReqWaiting is NOT 0 but"
                                         + mRequestMessagesWaiting + " at TIMEOUT, reset!"
                                         + " There still msg waitng for response");
 
@@ -401,12 +405,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                                 if (RILJ_LOGD) {
                                     synchronized (mRequestsList) {
                                         int count = mRequestsList.size();
-                                        Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
+                                        Rlog.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
                                                 " mRequestList=" + count);
 
                                         for (int i = 0; i < count; i++) {
                                             rr = mRequestsList.get(i);
-                                            Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] "
+                                            Rlog.d(LOG_TAG, i + ": [" + rr.mSerial + "] "
                                                     + requestToString(rr.mRequest));
                                         }
                                     }
@@ -420,7 +424,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                             // should already sent out (i.e.
                             // mRequestMessagesPending is 0 )while TIMEOUT occurs.
                             if (mRequestMessagesPending != 0) {
-                                Log.e(LOG_TAG, "ERROR: mReqPending is NOT 0 but"
+                                Rlog.e(LOG_TAG, "ERROR: mReqPending is NOT 0 but"
                                         + mRequestMessagesPending + " at TIMEOUT, reset!");
                                 mRequestMessagesPending = 0;
 
@@ -460,7 +464,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
             countRead = is.read(buffer, offset, remaining);
 
             if (countRead < 0 ) {
-                Log.e(LOG_TAG, "Hit EOS reading message length");
+                Rlog.e(LOG_TAG, "Hit EOS reading message length");
                 return -1;
             }
 
@@ -480,7 +484,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
             countRead = is.read(buffer, offset, remaining);
 
             if (countRead < 0 ) {
-                Log.e(LOG_TAG, "Hit EOS reading message.  messageLength=" + messageLength
+                Rlog.e(LOG_TAG, "Hit EOS reading message.  messageLength=" + messageLength
                         + " remaining=" + remaining);
                 return -1;
             }
@@ -525,12 +529,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                     // or after the 8th time
 
                     if (retryCount == 8) {
-                        Log.e (LOG_TAG,
+                        Rlog.e (LOG_TAG,
                             "Couldn't find '" + SOCKET_NAME_RIL
                             + "' socket after " + retryCount
                             + " times, continuing to retry silently");
                     } else if (retryCount > 0 && retryCount < 8) {
-                        Log.i (LOG_TAG,
+                        Rlog.i (LOG_TAG,
                             "Couldn't find '" + SOCKET_NAME_RIL
                             + "' socket; retrying after timeout");
                     }
@@ -547,7 +551,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                 retryCount = 0;
 
                 mSocket = s;
-                Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");
+                Rlog.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");
 
                 int length = 0;
                 try {
@@ -567,20 +571,20 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                         p.unmarshall(buffer, 0, length);
                         p.setDataPosition(0);
 
-                        //Log.v(LOG_TAG, "Read packet: " + length + " bytes");
+                        //Rlog.v(LOG_TAG, "Read packet: " + length + " bytes");
 
                         processResponse(p);
                         p.recycle();
                     }
                 } catch (java.io.IOException ex) {
-                    Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",
+                    Rlog.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",
                           ex);
                 } catch (Throwable tr) {
-                    Log.e(LOG_TAG, "Uncaught exception read length=" + length +
+                    Rlog.e(LOG_TAG, "Uncaught exception read length=" + length +
                         "Exception:" + tr.toString());
                 }
 
-                Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL
+                Rlog.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL
                       + "' socket");
 
                 setRadioState (RadioState.RADIO_UNAVAILABLE);
@@ -596,7 +600,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                 // Clear request list on close
                 clearRequestsList(RADIO_NOT_AVAILABLE, false);
             }} catch (Throwable tr) {
-                Log.e(LOG_TAG,"Uncaught exception", tr);
+                Rlog.e(LOG_TAG,"Uncaught exception", tr);
             }
 
             /* We're disconnected so we don't know the ril version */
@@ -1657,7 +1661,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                             Message response) {
         RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response);
 
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                                 + " [" + facility + " " + serviceClass
+                                                 + " " + appId + "]");
 
         // count strings
         rr.mp.writeInt(4);
@@ -1686,7 +1692,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
          RILRequest rr
                 = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response);
 
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                                        + " [" + facility + " " + lockState
+                                                        + " " + serviceClass + " " + appId + "]");
 
         // count strings
         rr.mp.writeInt(5);
@@ -1707,8 +1715,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
         RILRequest rr
                 = RILRequest.obtain(RIL_REQUEST_SEND_USSD, response);
 
-        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
-                            + " " + ussdString);
+        if (RILJ_LOGD) {
+            String logUssdString = "*******";
+            if (RILJ_LOGV) logUssdString = ussdString;
+            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                   + " " + logUssdString);
+        }
 
         rr.mp.writeString(ussdString);
 
@@ -2142,7 +2154,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
         synchronized (mRequestsList) {
             int count = mRequestsList.size();
             if (RILJ_LOGD && loggable) {
-                Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
+                Rlog.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
                         " mReqPending=" + mRequestMessagesPending +
                         " mRequestList=" + count);
             }
@@ -2150,7 +2162,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
             for (int i = 0; i < count ; i++) {
                 rr = mRequestsList.get(i);
                 if (RILJ_LOGD && loggable) {
-                    Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
+                    Rlog.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
                             requestToString(rr.mRequest));
                 }
                 rr.onError(error, null);
@@ -2191,7 +2203,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
         rr = findAndRemoveRequestFromList(serial);
 
         if (rr == null) {
-            Log.w(LOG_TAG, "Unexpected solicited response! sn: "
+            Rlog.w(LOG_TAG, "Unexpected solicited response! sn: "
                             + serial + " error: " + error);
             return;
         }
@@ -2329,7 +2341,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
             }} catch (Throwable tr) {
                 // Exceptions here usually mean invalid RIL responses
 
-                Log.w(LOG_TAG, rr.serialString() + "< "
+                Rlog.w(LOG_TAG, rr.serialString() + "< "
                         + requestToString(rr.mRequest)
                         + " exception, possible invalid RIL response", tr);
 
@@ -2342,7 +2354,39 @@ public final class RIL extends BaseCommands implements CommandsInterface {
             }
         }
 
+        // Here and below fake RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, see b/7255789.
+        // This is needed otherwise we don't automatically transition to the main lock
+        // screen when the pin or puk is entered incorrectly.
+        switch (rr.mRequest) {
+            case RIL_REQUEST_ENTER_SIM_PUK:
+            case RIL_REQUEST_ENTER_SIM_PUK2:
+                if (mIccStatusChangedRegistrants != null) {
+                    if (RILJ_LOGD) {
+                        riljLog("ON enter sim puk fakeSimStatusChanged: reg count="
+                                + mIccStatusChangedRegistrants.size());
+                    }
+                    mIccStatusChangedRegistrants.notifyRegistrants();
+                }
+                break;
+        }
+
         if (error != 0) {
+            switch (rr.mRequest) {
+                case RIL_REQUEST_ENTER_SIM_PIN:
+                case RIL_REQUEST_ENTER_SIM_PIN2:
+                case RIL_REQUEST_CHANGE_SIM_PIN:
+                case RIL_REQUEST_CHANGE_SIM_PIN2:
+                case RIL_REQUEST_SET_FACILITY_LOCK:
+                    if (mIccStatusChangedRegistrants != null) {
+                        if (RILJ_LOGD) {
+                            riljLog("ON some errors fakeSimStatusChanged: reg count="
+                                    + mIccStatusChangedRegistrants.size());
+                        }
+                        mIccStatusChangedRegistrants.notifyRegistrants();
+                    }
+                    break;
+            }
+
             rr.onError(error, ret);
             rr.release();
             return;
@@ -2477,7 +2521,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                 throw new RuntimeException("Unrecognized unsol response: " + response);
             //break; (implied)
         }} catch (Throwable tr) {
-            Log.e(LOG_TAG, "Exception processing unsol response: " + response +
+            Rlog.e(LOG_TAG, "Exception processing unsol response: " + response +
                 "Exception:" + tr.toString());
             return;
         }
@@ -2748,7 +2792,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
                 try {
                     listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
                 } catch (ClassCastException e) {
-                    Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
+                    Rlog.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
                     break;
                 }
 
@@ -2985,35 +3029,34 @@ public final class RIL extends BaseCommands implements CommandsInterface {
 
     private Object
     responseIccCardStatus(Parcel p) {
-        IccCardApplication ca;
-
-        IccCardStatus status = new IccCardStatus();
-        status.setCardState(p.readInt());
-        status.setUniversalPinState(p.readInt());
-        status.setGsmUmtsSubscriptionAppIndex(p.readInt());
-        status.setCdmaSubscriptionAppIndex(p.readInt());
-        status.setImsSubscriptionAppIndex(p.readInt());
+        IccCardApplicationStatus appStatus;
+
+        IccCardStatus cardStatus = new IccCardStatus();
+        cardStatus.setCardState(p.readInt());
+        cardStatus.setUniversalPinState(p.readInt());
+        cardStatus.mGsmUmtsSubscriptionAppIndex = p.readInt();
+        cardStatus.mCdmaSubscriptionAppIndex = p.readInt();
+        cardStatus.mImsSubscriptionAppIndex = p.readInt();
         int numApplications = p.readInt();
 
         // limit to maximum allowed applications
         if (numApplications > IccCardStatus.CARD_MAX_APPS) {
             numApplications = IccCardStatus.CARD_MAX_APPS;
         }
-        status.setNumApplications(numApplications);
-
+        cardStatus.mApplications = new IccCardApplicationStatus[numApplications];
         for (int i = 0 ; i < numApplications ; i++) {
-            ca = new IccCardApplication();
-            ca.app_type       = ca.AppTypeFromRILInt(p.readInt());
-            ca.app_state      = ca.AppStateFromRILInt(p.readInt());
-            ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt());
-            ca.aid            = p.readString();
-            ca.app_label      = p.readString();
-            ca.pin1_replaced  = p.readInt();
-            ca.pin1           = ca.PinStateFromRILInt(p.readInt());
-            ca.pin2           = ca.PinStateFromRILInt(p.readInt());
-            status.addApplication(ca);
+            appStatus = new IccCardApplicationStatus();
+            appStatus.app_type       = appStatus.AppTypeFromRILInt(p.readInt());
+            appStatus.app_state      = appStatus.AppStateFromRILInt(p.readInt());
+            appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(p.readInt());
+            appStatus.aid            = p.readString();
+            appStatus.app_label      = p.readString();
+            appStatus.pin1_replaced  = p.readInt();
+            appStatus.pin1           = appStatus.PinStateFromRILInt(p.readInt());
+            appStatus.pin2           = appStatus.PinStateFromRILInt(p.readInt());
+            cardStatus.mApplications[i] = appStatus;
         }
-        return status;
+        return cardStatus;
     }
 
     private Object
@@ -3347,16 +3390,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
 
     private Object
     responseSignalStrength(Parcel p) {
-        int numInts = 12;
-        int response[];
-
-        /* TODO: Add SignalStrength class to match RIL_SignalStrength */
-        response = new int[numInts];
-        for (int i = 0 ; i < numInts ; i++) {
-            response[i] = p.readInt();
-        }
-
-        return response;
+        SignalStrength signalStrength = new SignalStrength(p);
+        return signalStrength;
     }
 
     private ArrayList<CdmaInformationRecords>
@@ -3627,11 +3662,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
     }
 
     private void riljLog(String msg) {
-        Log.d(LOG_TAG, msg);
+        Rlog.d(LOG_TAG, msg);
     }
 
     private void riljLogv(String msg) {
-        Log.v(LOG_TAG, msg);
+        Rlog.v(LOG_TAG, msg);
     }
 
     private void unsljLog(int response) {
@@ -3837,7 +3872,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("RIL:");
+        pw.println("RIL: " + this);
         pw.println(" mSocket=" + mSocket);
         pw.println(" mSenderThread=" + mSenderThread);
         pw.println(" mSender=" + mSender);
index 250d99e..7d9dc9c 100644 (file)
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.util.Log;
+import android.telephony.Rlog;
 import android.util.Pair;
 import android.text.TextUtils;
 
@@ -208,7 +208,7 @@ public class RetryManager {
                             mMaxRetryCount = value.second;
                         }
                     } else {
-                        Log.e(LOG_TAG, "Unrecognized configuration name value pair: "
+                        Rlog.e(LOG_TAG, "Unrecognized configuration name value pair: "
                                         + strArray[i]);
                         return false;
                     }
@@ -365,7 +365,7 @@ public class RetryManager {
             value = Integer.parseInt(stringValue);
             retVal = new Pair<Boolean, Integer>(validateNonNegativeInt(name, value), value);
         } catch (NumberFormatException e) {
-            Log.e(LOG_TAG, name + " bad value: " + stringValue, e);
+            Rlog.e(LOG_TAG, name + " bad value: " + stringValue, e);
             retVal = new Pair<Boolean, Integer>(false, 0);
         }
         if (VDBG) log("parseNonNetativeInt: " + name + ", " + stringValue + ", "
@@ -383,7 +383,7 @@ public class RetryManager {
     private boolean validateNonNegativeInt(String name, int value) {
         boolean retVal;
         if (value < 0) {
-            Log.e(LOG_TAG, name + " bad value: is < 0");
+            Rlog.e(LOG_TAG, name + " bad value: is < 0");
             retVal = false;
         } else {
             retVal = true;
@@ -405,6 +405,6 @@ public class RetryManager {
     }
 
     private void log(String s) {
-        Log.d(LOG_TAG, "[RM] " + s);
+        Rlog.d(LOG_TAG, "[RM] " + s);
     }
 }
index a333c4f..6f4cad5 100644 (file)
@@ -27,9 +27,11 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.Cursor;
+import android.database.ContentObserver;
 import android.database.SQLException;
 import android.net.Uri;
 import android.os.AsyncResult;
@@ -38,6 +40,7 @@ import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.SystemProperties;
+import android.provider.Settings;
 import android.provider.Telephony;
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.PhoneNumberUtils;
@@ -47,17 +50,27 @@ import android.telephony.SmsMessage;
 import android.telephony.TelephonyManager;
 import android.text.Html;
 import android.text.Spanned;
-import android.util.Log;
+import android.util.EventLog;
+import android.telephony.Rlog;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+import android.widget.TextView;
 
 import com.android.internal.R;
+import com.android.internal.telephony.EventLogTags;
 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
-import com.android.internal.telephony.SmsConstants;
 import com.android.internal.util.HexDump;
 
 import java.io.ByteArrayOutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.HashMap;
 import java.util.Random;
 
@@ -99,6 +112,12 @@ public abstract class SMSDispatcher extends Handler {
     private static final int SEQUENCE_COLUMN = 1;
     private static final int DESTINATION_PORT_COLUMN = 2;
 
+    private static final int PREMIUM_RULE_USE_SIM = 1;
+    private static final int PREMIUM_RULE_USE_NETWORK = 2;
+    private static final int PREMIUM_RULE_USE_BOTH = 3;
+    private final AtomicInteger mPremiumSmsRule = new AtomicInteger(PREMIUM_RULE_USE_SIM);
+    private final SettingsObserver mSettingsObserver;
+
     /** New SMS received. */
     protected static final int EVENT_NEW_SMS = 1;
 
@@ -194,6 +213,9 @@ public abstract class SMSDispatcher extends Handler {
         mStorageMonitor = storageMonitor;
         mUsageMonitor = usageMonitor;
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        mSettingsObserver = new SettingsObserver(this, mPremiumSmsRule, mContext);
+        mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.SMS_SHORT_CODE_RULE), false, mSettingsObserver);
 
         createWakelock();
 
@@ -203,11 +225,31 @@ public abstract class SMSDispatcher extends Handler {
                                 TelephonyProperties.PROPERTY_SMS_RECEIVE, mSmsCapable);
         mSmsSendDisabled = !SystemProperties.getBoolean(
                                 TelephonyProperties.PROPERTY_SMS_SEND, mSmsCapable);
-        Log.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat()
+        Rlog.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat()
                 + " mSmsReceiveDisabled=" + mSmsReceiveDisabled
                 + " mSmsSendDisabled=" + mSmsSendDisabled);
     }
 
+    /**
+     * Observe the secure setting for updated premium sms determination rules
+     */
+    private static class SettingsObserver extends ContentObserver {
+        private final AtomicInteger mPremiumSmsRule;
+        private final Context mContext;
+        SettingsObserver(Handler handler, AtomicInteger premiumSmsRule, Context context) {
+            super(handler);
+            mPremiumSmsRule = premiumSmsRule;
+            mContext = context;
+            onChange(false); // load initial value;
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            mPremiumSmsRule.set(Settings.Global.getInt(mContext.getContentResolver(),
+                    Settings.Global.SMS_SHORT_CODE_RULE, PREMIUM_RULE_USE_SIM));
+        }
+    }
+
     /** Unregister for incoming SMS events. */
     public abstract void dispose();
 
@@ -229,7 +271,7 @@ public abstract class SMSDispatcher extends Handler {
 
     @Override
     protected void finalize() {
-        Log.d(TAG, "SMSDispatcher finalized");
+        Rlog.d(TAG, "SMSDispatcher finalized");
     }
 
 
@@ -254,7 +296,7 @@ public abstract class SMSDispatcher extends Handler {
         case EVENT_NEW_SMS:
             // A new SMS has been received by the device
             if (false) {
-                Log.d(TAG, "New SMS Message Received");
+                Rlog.d(TAG, "New SMS Message Received");
             }
 
             SmsMessage sms;
@@ -262,7 +304,7 @@ public abstract class SMSDispatcher extends Handler {
             ar = (AsyncResult) msg.obj;
 
             if (ar.exception != null) {
-                Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception);
+                Rlog.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception);
                 return;
             }
 
@@ -276,7 +318,7 @@ public abstract class SMSDispatcher extends Handler {
                     notifyAndAcknowledgeLastIncomingSms(handled, result, null);
                 }
             } catch (RuntimeException ex) {
-                Log.e(TAG, "Exception dispatching message", ex);
+                Rlog.e(TAG, "Exception dispatching message", ex);
                 notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
             }
 
@@ -322,7 +364,7 @@ public abstract class SMSDispatcher extends Handler {
                 try {
                     tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED);
                 } catch (CanceledException ex) {
-                    Log.e(TAG, "failed to send RESULT_ERROR_LIMIT_EXCEEDED");
+                    Rlog.e(TAG, "failed to send RESULT_ERROR_LIMIT_EXCEEDED");
                 }
             }
             mPendingTrackerCount--;
@@ -354,6 +396,22 @@ public abstract class SMSDispatcher extends Handler {
     }
 
     /**
+     * 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
      * the failure in the result code.
@@ -368,7 +426,7 @@ public abstract class SMSDispatcher extends Handler {
 
         if (ar.exception == null) {
             if (false) {
-                Log.d(TAG, "SMS send complete. Broadcasting "
+                Rlog.d(TAG, "SMS send complete. Broadcasting "
                         + "intent: " + sentIntent);
             }
 
@@ -396,7 +454,7 @@ public abstract class SMSDispatcher extends Handler {
             }
         } else {
             if (false) {
-                Log.d(TAG, "SMS send failed");
+                Rlog.d(TAG, "SMS send failed");
             }
 
             int ss = mPhone.getServiceState().getState();
@@ -551,12 +609,12 @@ public abstract class SMSDispatcher extends Handler {
 
             // moveToNext() returns false if no duplicates were found
             if (cursor.moveToNext()) {
-                Log.w(TAG, "Discarding duplicate message segment from address=" + address
+                Rlog.w(TAG, "Discarding duplicate message segment from address=" + address
                         + " refNumber=" + refNumber + " seqNumber=" + seqNumber);
                 String oldPduString = cursor.getString(PDU_COLUMN);
                 byte[] oldPdu = HexDump.hexStringToByteArray(oldPduString);
                 if (!Arrays.equals(oldPdu, pdu)) {
-                    Log.e(TAG, "Warning: dup message segment PDU of length " + pdu.length
+                    Rlog.e(TAG, "Warning: dup message segment PDU of length " + pdu.length
                             + " is different from existing PDU of length " + oldPdu.length);
                 }
                 return Intents.RESULT_SMS_HANDLED;
@@ -614,7 +672,7 @@ public abstract class SMSDispatcher extends Handler {
             // Remove the parts from the database
             mResolver.delete(mRawUri, where, whereArgs);
         } catch (SQLException e) {
-            Log.e(TAG, "Can't access multipart SMS database", e);
+            Rlog.e(TAG, "Can't access multipart SMS database", e);
             return Intents.RESULT_SMS_GENERIC_ERROR;
         } finally {
             if (cursor != null) cursor.close();
@@ -880,7 +938,7 @@ public abstract class SMSDispatcher extends Handler {
                     sentIntent.send(RESULT_ERROR_NO_SERVICE);
                 } catch (CanceledException ex) {}
             }
-            Log.d(TAG, "Device does not support sending sms.");
+            Rlog.d(TAG, "Device does not support sending sms.");
             return;
         }
 
@@ -903,22 +961,37 @@ public abstract class SMSDispatcher extends Handler {
 
         if (packageNames == null || packageNames.length == 0) {
             // Refuse to send SMS if we can't get the calling package name.
-            Log.e(TAG, "Can't get calling app package name: refusing to send SMS");
+            Rlog.e(TAG, "Can't get calling app package name: refusing to send SMS");
             if (sentIntent != null) {
                 try {
                     sentIntent.send(RESULT_ERROR_GENERIC_FAILURE);
                 } catch (CanceledException ex) {
-                    Log.e(TAG, "failed to send error result");
+                    Rlog.e(TAG, "failed to send error result");
                 }
             }
             return;
         }
 
-        String appPackage = packageNames[0];
+        // Get package info via packagemanager
+        PackageInfo appInfo = null;
+        try {
+            // XXX this is lossy- apps can share a UID
+            appInfo = pm.getPackageInfo(packageNames[0], PackageManager.GET_SIGNATURES);
+        } catch (PackageManager.NameNotFoundException e) {
+            Rlog.e(TAG, "Can't get calling app package info: refusing to send SMS");
+            if (sentIntent != null) {
+                try {
+                    sentIntent.send(RESULT_ERROR_GENERIC_FAILURE);
+                } catch (CanceledException ex) {
+                    Rlog.e(TAG, "failed to send error result");
+                }
+            }
+            return;
+        }
 
         // Strip non-digits from destination phone number before checking for short codes
         // and before displaying the number to the user if confirmation is required.
-        SmsTracker tracker = new SmsTracker(map, sentIntent, deliveryIntent, appPackage,
+        SmsTracker tracker = new SmsTracker(map, sentIntent, deliveryIntent, appInfo,
                 PhoneNumberUtils.extractNetworkPortion(destAddr));
 
         // checkDestination() returns true if the destination is not a premium short code or the
@@ -926,7 +999,7 @@ public abstract class SMSDispatcher extends Handler {
         // handler with the SmsTracker to request user confirmation before sending.
         if (checkDestination(tracker)) {
             // check for excessive outgoing SMS usage by this app
-            if (!mUsageMonitor.check(appPackage, SINGLE_PART_SMS)) {
+            if (!mUsageMonitor.check(appInfo.packageName, SINGLE_PART_SMS)) {
                 sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, tracker));
                 return;
             }
@@ -953,28 +1026,62 @@ public abstract class SMSDispatcher extends Handler {
                 == PackageManager.PERMISSION_GRANTED) {
             return true;            // app is pre-approved to send to short codes
         } else {
-            String countryIso = mTelephonyManager.getSimCountryIso();
-            if (countryIso == null || countryIso.length() != 2) {
-                Log.e(TAG, "Can't get SIM country code: trying network country code");
-                countryIso = mTelephonyManager.getNetworkCountryIso();
+            int rule = mPremiumSmsRule.get();
+            int smsCategory = SmsUsageMonitor.CATEGORY_NOT_SHORT_CODE;
+            if (rule == PREMIUM_RULE_USE_SIM || rule == PREMIUM_RULE_USE_BOTH) {
+                String simCountryIso = mTelephonyManager.getSimCountryIso();
+                if (simCountryIso == null || simCountryIso.length() != 2) {
+                    Rlog.e(TAG, "Can't get SIM country Iso: trying network country Iso");
+                    simCountryIso = mTelephonyManager.getNetworkCountryIso();
+                }
+
+                smsCategory = mUsageMonitor.checkDestination(tracker.mDestAddress, simCountryIso);
+            }
+            if (rule == PREMIUM_RULE_USE_NETWORK || rule == PREMIUM_RULE_USE_BOTH) {
+                String networkCountryIso = mTelephonyManager.getNetworkCountryIso();
+                if (networkCountryIso == null || networkCountryIso.length() != 2) {
+                    Rlog.e(TAG, "Can't get Network country Iso: trying SIM country Iso");
+                    networkCountryIso = mTelephonyManager.getSimCountryIso();
+                }
+
+                smsCategory = mUsageMonitor.mergeShortCodeCategories(smsCategory,
+                        mUsageMonitor.checkDestination(tracker.mDestAddress, networkCountryIso));
             }
 
-            switch (mUsageMonitor.checkDestination(tracker.mDestAddress, countryIso)) {
-                case SmsUsageMonitor.CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE:
-                    sendMessage(obtainMessage(EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE,
-                            tracker));
-                    return false;   // wait for user confirmation before sending
+            if (smsCategory == SmsUsageMonitor.CATEGORY_NOT_SHORT_CODE
+                    || smsCategory == SmsUsageMonitor.CATEGORY_FREE_SHORT_CODE
+                    || smsCategory == SmsUsageMonitor.CATEGORY_STANDARD_SHORT_CODE) {
+                return true;    // not a premium short code
+            }
+
+            // Wait for user confirmation unless the user has set permission to always allow/deny
+            int premiumSmsPermission = mUsageMonitor.getPremiumSmsPermission(
+                    tracker.mAppInfo.packageName);
+            if (premiumSmsPermission == SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) {
+                // First time trying to send to premium SMS.
+                premiumSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER;
+            }
 
-                case SmsUsageMonitor.CATEGORY_PREMIUM_SHORT_CODE:
-                    sendMessage(obtainMessage(EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE,
-                            tracker));
-                    return false;   // wait for user confirmation before sending
+            switch (premiumSmsPermission) {
+                case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW:
+                    Rlog.d(TAG, "User approved this app to send to premium SMS");
+                    return true;
 
-                case SmsUsageMonitor.CATEGORY_NOT_SHORT_CODE:
-                case SmsUsageMonitor.CATEGORY_FREE_SHORT_CODE:
-                case SmsUsageMonitor.CATEGORY_STANDARD_SHORT_CODE:
+                case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW:
+                    Rlog.w(TAG, "User denied this app from sending to premium SMS");
+                    sendMessage(obtainMessage(EVENT_STOP_SENDING, tracker));
+                    return false;   // reject this message
+
+                case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER:
                 default:
-                    return true;    // destination is not a premium short code
+                    int event;
+                    if (smsCategory == SmsUsageMonitor.CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE) {
+                        event = EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE;
+                    } else {
+                        event = EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE;
+                    }
+                    sendMessage(obtainMessage(event, tracker));
+                    return false;   // wait for user confirmation
             }
         }
     }
@@ -993,7 +1100,7 @@ public abstract class SMSDispatcher extends Handler {
                     tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED);
                 }
             } catch (CanceledException ex) {
-                Log.e(TAG, "failed to send back RESULT_ERROR_LIMIT_EXCEEDED");
+                Rlog.e(TAG, "failed to send back RESULT_ERROR_LIMIT_EXCEEDED");
             }
             return true;
         }
@@ -1012,7 +1119,7 @@ public abstract class SMSDispatcher extends Handler {
             ApplicationInfo appInfo = pm.getApplicationInfo(appPackage, 0);
             return appInfo.loadLabel(pm);
         } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "PackageManager Name Not Found for package " + appPackage);
+            Rlog.e(TAG, "PackageManager Name Not Found for package " + appPackage);
             return appPackage;  // fall back to package name if we can't get app label
         }
     }
@@ -1026,11 +1133,11 @@ public abstract class SMSDispatcher extends Handler {
             return;     // queue limit reached; error was returned to caller
         }
 
-        CharSequence appLabel = getAppLabel(tracker.mAppPackage);
+        CharSequence appLabel = getAppLabel(tracker.mAppInfo.packageName);
         Resources r = Resources.getSystem();
         Spanned messageText = Html.fromHtml(r.getString(R.string.sms_control_message, appLabel));
 
-        ConfirmDialogListener listener = new ConfirmDialogListener(tracker);
+        ConfirmDialogListener listener = new ConfirmDialogListener(tracker, null);
 
         AlertDialog d = new AlertDialog.Builder(mContext)
                 .setTitle(R.string.sms_control_title)
@@ -1055,35 +1162,77 @@ public abstract class SMSDispatcher extends Handler {
             return;     // queue limit reached; error was returned to caller
         }
 
-        int messageId;
-        int titleId;
+        int detailsId;
         if (isPremium) {
-            messageId = R.string.sms_premium_short_code_confirm_message;
-            titleId = R.string.sms_premium_short_code_confirm_title;
+            detailsId = R.string.sms_premium_short_code_details;
         } else {
-            messageId = R.string.sms_short_code_confirm_message;
-            titleId = R.string.sms_short_code_confirm_title;
+            detailsId = R.string.sms_short_code_details;
         }
 
-        CharSequence appLabel = getAppLabel(tracker.mAppPackage);
+        CharSequence appLabel = getAppLabel(tracker.mAppInfo.packageName);
         Resources r = Resources.getSystem();
-        Spanned messageText = Html.fromHtml(r.getString(messageId, appLabel, tracker.mDestAddress));
+        Spanned messageText = Html.fromHtml(r.getString(R.string.sms_short_code_confirm_message,
+                appLabel, tracker.mDestAddress));
+
+        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        View layout = inflater.inflate(R.layout.sms_short_code_confirmation_dialog, null);
+
+        ConfirmDialogListener listener = new ConfirmDialogListener(tracker,
+                (TextView)layout.findViewById(R.id.sms_short_code_remember_undo_instruction));
+
 
-        ConfirmDialogListener listener = new ConfirmDialogListener(tracker);
+        TextView messageView = (TextView) layout.findViewById(R.id.sms_short_code_confirm_message);
+        messageView.setText(messageText);
+
+        ViewGroup detailsLayout = (ViewGroup) layout.findViewById(
+                R.id.sms_short_code_detail_layout);
+        TextView detailsView = (TextView) detailsLayout.findViewById(
+                R.id.sms_short_code_detail_message);
+        detailsView.setText(detailsId);
+
+        CheckBox rememberChoice = (CheckBox) layout.findViewById(
+                R.id.sms_short_code_remember_choice_checkbox);
+        rememberChoice.setOnCheckedChangeListener(listener);
 
         AlertDialog d = new AlertDialog.Builder(mContext)
-                .setTitle(titleId)
-                .setIcon(R.drawable.stat_sys_warning)
-                .setMessage(messageText)
+                .setView(layout)
                 .setPositiveButton(r.getString(R.string.sms_short_code_confirm_allow), listener)
                 .setNegativeButton(r.getString(R.string.sms_short_code_confirm_deny), listener)
-// TODO: add third button for "Report malicious app" feature
-//                .setNeutralButton(r.getString(R.string.sms_short_code_confirm_report), listener)
                 .setOnCancelListener(listener)
                 .create();
 
         d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
         d.show();
+
+        listener.setPositiveButton(d.getButton(DialogInterface.BUTTON_POSITIVE));
+        listener.setNegativeButton(d.getButton(DialogInterface.BUTTON_NEGATIVE));
+    }
+
+    /**
+     * Returns the premium SMS permission for the specified package. If the package has never
+     * been seen before, the default {@link SmsUsageMonitor#PREMIUM_SMS_PERMISSION_ASK_USER}
+     * will be returned.
+     * @param packageName the name of the package to query permission
+     * @return one of {@link SmsUsageMonitor#PREMIUM_SMS_PERMISSION_UNKNOWN},
+     *  {@link SmsUsageMonitor#PREMIUM_SMS_PERMISSION_ASK_USER},
+     *  {@link SmsUsageMonitor#PREMIUM_SMS_PERMISSION_NEVER_ALLOW}, or
+     *  {@link SmsUsageMonitor#PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW}
+     */
+    public int getPremiumSmsPermission(String packageName) {
+        return mUsageMonitor.getPremiumSmsPermission(packageName);
+    }
+
+    /**
+     * Sets the premium SMS permission for the specified package and save the value asynchronously
+     * to persistent storage.
+     * @param packageName the name of the package to set permission
+     * @param permission one of {@link SmsUsageMonitor#PREMIUM_SMS_PERMISSION_ASK_USER},
+     *  {@link SmsUsageMonitor#PREMIUM_SMS_PERMISSION_NEVER_ALLOW}, or
+     *  {@link SmsUsageMonitor#PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW}
+     */
+    public void setPremiumSmsPermission(String packageName, int permission) {
+        mUsageMonitor.setPremiumSmsPermission(packageName, permission);
     }
 
     /**
@@ -1170,16 +1319,16 @@ public abstract class SMSDispatcher extends Handler {
         public final PendingIntent mSentIntent;
         public final PendingIntent mDeliveryIntent;
 
-        public final String mAppPackage;
+        public final PackageInfo mAppInfo;
         public final String mDestAddress;
 
         public SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
-                PendingIntent deliveryIntent, String appPackage, String destAddr) {
+                PendingIntent deliveryIntent, PackageInfo appInfo, String destAddr) {
             mData = data;
             mSentIntent = sentIntent;
             mDeliveryIntent = deliveryIntent;
             mRetryCount = 0;
-            mAppPackage = appPackage;
+            mAppInfo = appInfo;
             mDestAddress = destAddr;
         }
 
@@ -1197,30 +1346,83 @@ public abstract class SMSDispatcher extends Handler {
      * Dialog listener for SMS confirmation dialog.
      */
     private final class ConfirmDialogListener
-            implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
+            implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener,
+            CompoundButton.OnCheckedChangeListener {
 
         private final SmsTracker mTracker;
+        private Button mPositiveButton;
+        private Button mNegativeButton;
+        private boolean mRememberChoice;    // default is unchecked
+        private final TextView mRememberUndoInstruction;
 
-        ConfirmDialogListener(SmsTracker tracker) {
+        ConfirmDialogListener(SmsTracker tracker, TextView textView) {
             mTracker = tracker;
+            mRememberUndoInstruction = textView;
+        }
+
+        void setPositiveButton(Button button) {
+            mPositiveButton = button;
+        }
+
+        void setNegativeButton(Button button) {
+            mNegativeButton = button;
         }
 
         @Override
         public void onClick(DialogInterface dialog, int which) {
+            // Always set the SMS permission so that Settings will show a permission setting
+            // for the app (it won't be shown until after the app tries to send to a short code).
+            int newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER;
+
             if (which == DialogInterface.BUTTON_POSITIVE) {
-                Log.d(TAG, "CONFIRM sending SMS");
+                Rlog.d(TAG, "CONFIRM sending SMS");
+                // XXX this is lossy- apps can have more than one signature
+                EventLog.writeEvent(EventLogTags.SMS_SENT_BY_USER,
+                                    mTracker.mAppInfo.signatures[0].toCharsString());
                 sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS, mTracker));
+                if (mRememberChoice) {
+                    newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW;
+                }
             } else if (which == DialogInterface.BUTTON_NEGATIVE) {
-                Log.d(TAG, "DENY sending SMS");
+                Rlog.d(TAG, "DENY sending SMS");
+                // XXX this is lossy- apps can have more than one signature
+                EventLog.writeEvent(EventLogTags.SMS_DENIED_BY_USER,
+                                    mTracker.mAppInfo.signatures[0].toCharsString());
                 sendMessage(obtainMessage(EVENT_STOP_SENDING, mTracker));
+                if (mRememberChoice) {
+                    newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW;
+                }
             }
+            setPremiumSmsPermission(mTracker.mAppInfo.packageName, newSmsPermission);
         }
 
         @Override
         public void onCancel(DialogInterface dialog) {
-            Log.d(TAG, "dialog dismissed: don't send SMS");
+            Rlog.d(TAG, "dialog dismissed: don't send SMS");
             sendMessage(obtainMessage(EVENT_STOP_SENDING, mTracker));
         }
+
+        @Override
+        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+            Rlog.d(TAG, "remember this choice: " + isChecked);
+            mRememberChoice = isChecked;
+            if (isChecked) {
+                mPositiveButton.setText(R.string.sms_short_code_confirm_always_allow);
+                mNegativeButton.setText(R.string.sms_short_code_confirm_never_allow);
+                if (mRememberUndoInstruction != null) {
+                    mRememberUndoInstruction.
+                            setText(R.string.sms_short_code_remember_undo_instruction);
+                    mRememberUndoInstruction.setPadding(0,0,0,32);
+                }
+            } else {
+                mPositiveButton.setText(R.string.sms_short_code_confirm_allow);
+                mNegativeButton.setText(R.string.sms_short_code_confirm_deny);
+                if (mRememberUndoInstruction != null) {
+                    mRememberUndoInstruction.setText("");
+                    mRememberUndoInstruction.setPadding(0,0,0,0);
+                }
+            }
+        }
     }
 
     private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
@@ -1242,12 +1444,12 @@ public abstract class SMSDispatcher extends Handler {
         if (message.isEmergencyMessage()) {
             Intent intent = new Intent(Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION);
             intent.putExtra("message", message);
-            Log.d(TAG, "Dispatching emergency SMS CB");
+            Rlog.d(TAG, "Dispatching emergency SMS CB");
             dispatch(intent, RECEIVE_EMERGENCY_BROADCAST_PERMISSION);
         } else {
             Intent intent = new Intent(Intents.SMS_CB_RECEIVED_ACTION);
             intent.putExtra("message", message);
-            Log.d(TAG, "Dispatching SMS CB");
+            Rlog.d(TAG, "Dispatching SMS CB");
             dispatch(intent, RECEIVE_SMS_PERMISSION);
         }
     }
index e4cfb23..988dc6e 100644 (file)
 
 package com.android.internal.telephony;
 
+import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.os.Registrant;
 import android.os.RegistrantList;
+import android.os.SystemClock;
+import android.telephony.CellInfo;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.util.TimeUtils;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.List;
+
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
+import com.android.internal.telephony.uicc.IccRecords;
+import com.android.internal.telephony.uicc.UiccCardApplication;
+import com.android.internal.telephony.uicc.UiccController;
 
 /**
  * {@hide}
@@ -34,13 +44,24 @@ import java.io.PrintWriter;
 public abstract class ServiceStateTracker extends Handler {
 
     protected CommandsInterface cm;
+    protected UiccController mUiccController = null;
+    protected UiccCardApplication mUiccApplcation = null;
+    protected IccRecords mIccRecords = null;
+
+    protected PhoneBase mPhoneBase;
+
+    public ServiceState ss = new ServiceState();
+    protected ServiceState newSS = new ServiceState();
 
-    public ServiceState ss;
-    protected ServiceState newSS;
+    protected CellInfo mLastCellInfo = null;
 
-    public SignalStrength mSignalStrength;
+    // This is final as subclasses alias to a more specific type
+    // so we don't want the reference to change.
+    protected final CellInfo mCellInfo;
 
-    // TODO - this should not be public
+    protected SignalStrength mSignalStrength = new SignalStrength();
+
+    // TODO - this should not be public, right now used externally GsmConnetion.
     public RestrictedState mRestrictedState = new RestrictedState();
 
     /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
@@ -121,7 +142,7 @@ public abstract class ServiceStateTracker extends Handler {
     protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA          = 29;
     protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA        = 30;
     protected static final int EVENT_GET_LOC_DONE_CDMA                 = 31;
-    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA       = 32;
+    //protected static final int EVENT_UNUSED                            = 32;
     protected static final int EVENT_NV_LOADED                         = 33;
     protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION      = 34;
     protected static final int EVENT_NV_READY                          = 35;
@@ -131,7 +152,7 @@ public abstract class ServiceStateTracker extends Handler {
     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED  = 39;
     protected static final int EVENT_CDMA_PRL_VERSION_CHANGED          = 40;
     protected static final int EVENT_RADIO_ON                          = 41;
-
+    protected static final int EVENT_ICC_CHANGED                       = 42;
 
     protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
 
@@ -168,13 +189,40 @@ public abstract class ServiceStateTracker extends Handler {
     protected static final String REGISTRATION_DENIED_GEN  = "General";
     protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
 
-    public ServiceStateTracker() {
+    protected ServiceStateTracker(PhoneBase phoneBase, CommandsInterface ci, CellInfo cellInfo) {
+        mPhoneBase = phoneBase;
+        mCellInfo = cellInfo;
+        cm = ci;
+        mUiccController = UiccController.getInstance();
+        mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
+        cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
+    }
+
+    public void dispose() {
+        cm.unSetOnSignalStrengthUpdate(this);
     }
 
     public boolean getDesiredPowerState() {
         return mDesiredPowerState;
     }
 
+    private SignalStrength mLastSignalStrength = null;
+    protected boolean notifySignalStrength() {
+        boolean notified = false;
+        synchronized(mCellInfo) {
+            if (!mSignalStrength.equals(mLastSignalStrength)) {
+                try {
+                    mPhoneBase.notifySignalStrength();
+                    notified = true;
+                } catch (NullPointerException ex) {
+                    loge("updateSignalStrength() Phone already destroyed: " + ex
+                            + "SignalStrength not notified");
+                }
+            }
+        }
+        return notified;
+    }
+
     /**
      * Registration point for combined roaming on
      * combined roaming is true when roaming is true and ONS differs SPN
@@ -295,6 +343,10 @@ public abstract class ServiceStateTracker extends Handler {
                 }
                 break;
 
+            case EVENT_ICC_CHANGED:
+                onUpdateIccAvailability();
+                break;
+
             default:
                 log("Unhandled message with number: " + msg.what);
                 break;
@@ -305,6 +357,7 @@ public abstract class ServiceStateTracker extends Handler {
     protected abstract void handlePollStateResult(int what, AsyncResult ar);
     protected abstract void updateSpnDisplay();
     protected abstract void setPowerStateToDesired();
+    protected abstract void onUpdateIccAvailability();
     protected abstract void log(String s);
     protected abstract void loge(String s);
 
@@ -454,6 +507,30 @@ public abstract class ServiceStateTracker extends Handler {
     }
 
     /**
+     * send signal-strength-changed notification if changed Called both for
+     * solicited and unsolicited signal strength updates
+     *
+     * @return true if the signal strength changed and a notification was sent.
+     */
+    protected boolean onSignalStrengthResult(AsyncResult ar, boolean isGsm) {
+        SignalStrength oldSignalStrength = mSignalStrength;
+
+        // This signal is used for both voice and data radio signal so parse
+        // all fields
+
+        if ((ar.exception == null) && (ar.result != null)) {
+            mSignalStrength = (SignalStrength) ar.result;
+            mSignalStrength.validateInput();
+            mSignalStrength.setGsm(isGsm);
+        } else {
+            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
+            mSignalStrength = new SignalStrength(isGsm);
+        }
+
+        return notifySignalStrength();
+    }
+
+    /**
      * Hang up all voice call and turn off radio. Implemented by derived class.
      */
     protected abstract void hangupAndPowerOff();
@@ -502,16 +579,16 @@ public abstract class ServiceStateTracker extends Handler {
         }
 
         // Determine if the Icc card exists
-        IccCard iccCard = phoneBase.getIccCard();
-        boolean iccCardExist = (iccCard != null) && iccCard.getState().iccCardExist();
+        boolean iccCardExist = false;
+        if (mUiccApplcation != null) {
+            iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN;
+        }
 
         // Determine retVal
         boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
         if (DBG) {
             long ctm = System.currentTimeMillis();
             log("shouldFixTimeZoneNow: retVal=" + retVal +
-                    " iccCard=" + iccCard +
-                    " iccCard.state=" + (iccCard == null ? "null" : iccCard.getState().toString()) +
                     " iccCardExist=" + iccCardExist +
                     " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
                     " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
@@ -521,11 +598,27 @@ public abstract class ServiceStateTracker extends Handler {
         return retVal;
     }
 
+    /**
+     * @return all available cell information or null if none.
+     */
+    public List<CellInfo> getAllCellInfo() {
+        return null;
+    }
+
+    /**
+     * @return signal strength
+     */
+    public SignalStrength getSignalStrength() {
+        synchronized(mCellInfo) {
+            return mSignalStrength;
+        }
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("ServiceStateTracker:");
         pw.println(" ss=" + ss);
         pw.println(" newSS=" + newSS);
-        pw.println(" mSignalStrength=" + mSignalStrength);
+        pw.println(" mCellInfo=" + mCellInfo);
         pw.println(" mRestrictedState=" + mRestrictedState);
         pw.println(" pollingContext=" + pollingContext);
         pw.println(" mDesiredPowerState=" + mDesiredPowerState);
@@ -535,4 +628,19 @@ public abstract class ServiceStateTracker extends Handler {
         pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
         pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
     }
+
+    /**
+     * Verifies the current thread is the same as the thread originally
+     * used in the initialization of this instance. Throws RuntimeException
+     * if not.
+     *
+     * @exception RuntimeException if the current thread is not
+     * the thread that originally obtained this PhoneBase instance.
+     */
+    protected void checkCorrectThread() {
+        if (Thread.currentThread() != getLooper().getThread()) {
+            throw new RuntimeException(
+                    "ServiceStateTracker must be used from within one thread");
+        }
+    }
 }
index 0c06ffc..6a9283f 100644 (file)
@@ -25,7 +25,7 @@ import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
 import android.provider.Telephony.Sms.Intents;
-import android.util.Log;
+import android.telephony.Rlog;
 
 /**
  * Monitors the device and ICC storage, and sends the appropriate events.
@@ -107,7 +107,7 @@ public final class SmsStorageMonitor extends Handler {
                 ar = (AsyncResult) msg.obj;
                 if (ar.exception != null) {
                     mReportMemoryStatusPending = true;
-                    Log.v(TAG, "Memory status report to modem pending : mStorageAvailable = "
+                    Rlog.v(TAG, "Memory status report to modem pending : mStorageAvailable = "
                             + mStorageAvailable);
                 } else {
                     mReportMemoryStatusPending = false;
@@ -116,7 +116,7 @@ public final class SmsStorageMonitor extends Handler {
 
             case EVENT_RADIO_ON:
                 if (mReportMemoryStatusPending) {
-                    Log.v(TAG, "Sending pending memory status report : mStorageAvailable = "
+                    Rlog.v(TAG, "Sending pending memory status report : mStorageAvailable = "
                             + mStorageAvailable);
                     mCm.reportSmsMemoryStatus(mStorageAvailable,
                             obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
index 1804d97..98155fd 100644 (file)
 
 package com.android.internal.telephony;
 
+import android.app.AppGlobals;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.res.XmlResourceParser;
 import android.database.ContentObserver;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.PhoneNumberUtils;
-import android.util.Log;
+import android.util.AtomicFile;
+import android.telephony.Rlog;
+import android.util.Xml;
 
+import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.regex.Pattern;
@@ -51,9 +66,11 @@ import java.util.regex.Pattern;
  */
 public class SmsUsageMonitor {
     private static final String TAG = "SmsUsageMonitor";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false;
 
+    private static final String SHORT_CODE_PATH = "/data/misc/sms/codes";
+
     /** Default checking period for SMS sent without user permission. */
     private static final int DEFAULT_SMS_CHECK_PERIOD = 1800000;    // 30 minutes
 
@@ -75,6 +92,24 @@ public class SmsUsageMonitor {
     /** Return value from {@link #checkDestination} for premium short codes. */
     static final int CATEGORY_PREMIUM_SHORT_CODE = 4;
 
+    /** @hide */
+    public static int mergeShortCodeCategories(int type1, int type2) {
+        if (type1 > type2) return type1;
+        return type2;
+    }
+
+    /** Premium SMS permission for a new package (ask user when first premium SMS sent). */
+    public static final int PREMIUM_SMS_PERMISSION_UNKNOWN = 0;
+
+    /** Default premium SMS permission (ask user for each premium SMS sent). */
+    public static final int PREMIUM_SMS_PERMISSION_ASK_USER = 1;
+
+    /** Premium SMS permission when the owner has denied the app from sending premium SMS. */
+    public static final int PREMIUM_SMS_PERMISSION_NEVER_ALLOW = 2;
+
+    /** Premium SMS permission when the owner has allowed the app to send premium SMS. */
+    public static final int PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW = 3;
+
     private final int mCheckPeriod;
     private final int mMaxAllowed;
 
@@ -90,12 +125,27 @@ public class SmsUsageMonitor {
     /** Cached short code pattern matcher for {@link #mCurrentCountry}. */
     private ShortCodePatternMatcher mCurrentPatternMatcher;
 
+    /** Notice when the enabled setting changes - can be changed through gservices */
+    private final AtomicBoolean mCheckEnabled = new AtomicBoolean(true);
+
     /** Cached short code regex patterns from secure settings for {@link #mCurrentCountry}. */
     private String mSettingsShortCodePatterns;
 
     /** Handler for responding to content observer updates. */
     private final SettingsObserverHandler mSettingsObserverHandler;
 
+    /** File holding the patterns */
+    private final File mPatternFile = new File(SHORT_CODE_PATH);
+
+    /** Last modified time for pattern file */
+    private long mPatternFileLastModified = 0;
+
+    /** Directory for per-app SMS permission XML file. */
+    private static final String SMS_POLICY_FILE_DIRECTORY = "/data/misc/sms";
+
+    /** Per-app SMS permission XML filename. */
+    private static final String SMS_POLICY_FILE_NAME = "premium_sms_policy.xml";
+
     /** XML tag for root element. */
     private static final String TAG_SHORTCODES = "shortcodes";
 
@@ -117,6 +167,24 @@ public class SmsUsageMonitor {
     /** XML attribute for the standard rate short code regex pattern. */
     private static final String ATTR_STANDARD = "standard";
 
+    /** Stored copy of premium SMS package permissions. */
+    private AtomicFile mPolicyFile;
+
+    /** Loaded copy of premium SMS package permissions. */
+    private final HashMap<String, Integer> mPremiumSmsPolicy = new HashMap<String, Integer>();
+
+    /** XML tag for root element of premium SMS permissions. */
+    private static final String TAG_SMS_POLICY_BODY = "premium-sms-policy";
+
+    /** XML tag for a package. */
+    private static final String TAG_PACKAGE = "package";
+
+    /** XML attribute for the package name. */
+    private static final String ATTR_PACKAGE_NAME = "name";
+
+    /** XML attribute for the package's premium SMS permission (integer type). */
+    private static final String ATTR_PACKAGE_SMS_POLICY = "sms-policy";
+
     /**
      * SMS short code regex pattern matcher for a specific country.
      */