AI 144245: Fix merge conflict for megering in the CDMA changes in to master from donutburger.

Automated import of CL 144245
This commit is contained in:
Wink Saville
2009-04-02 11:00:54 -07:00
committed by The Android Open Source Project
parent 3afdd56470
commit 04e71b3db8
189 changed files with 24484 additions and 8162 deletions

View File

@@ -122,8 +122,8 @@ LOCAL_SRC_FILES += \
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
telephony/java/com/android/internal/telephony/ITelephony.aidl \
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
telephony/java/com/android/internal/telephony/gsm/ISimPhoneBook.aidl \
telephony/java/com/android/internal/telephony/gsm/ISms.aidl \
telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
telephony/java/com/android/internal/telephony/ISms.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
@@ -438,3 +438,5 @@ include $(BUILD_JAVA_LIBRARY)
ifeq (,$(ONE_SHOT_MAKEFILE))
include $(call first-makefiles-under,$(LOCAL_PATH))
endif

View File

@@ -10263,6 +10263,28 @@
visibility="public"
>
</field>
<field name="stat_sys_vp_phone_call"
type="int"
transient="false"
volatile="false"
value="17302061"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="stat_sys_vp_phone_call_on_hold"
type="int"
transient="false"
volatile="false"
value="17302062"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="stat_sys_warning"
type="int"
transient="false"
@@ -97845,7 +97867,7 @@
abstract="false"
static="false"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<method name="divideMessage"
@@ -97854,8 +97876,8 @@
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
final="true"
deprecated="deprecated"
visibility="public"
>
<parameter name="text" type="java.lang.String">
@@ -97867,8 +97889,8 @@
native="false"
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
final="true"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -97878,8 +97900,8 @@
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
final="true"
deprecated="deprecated"
visibility="public"
>
<parameter name="destinationAddress" type="java.lang.String">
@@ -97901,8 +97923,8 @@
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
final="true"
deprecated="deprecated"
visibility="public"
>
<parameter name="destinationAddress" type="java.lang.String">
@@ -97922,8 +97944,8 @@
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
final="true"
deprecated="deprecated"
visibility="public"
>
<parameter name="destinationAddress" type="java.lang.String">
@@ -97944,7 +97966,7 @@
value="1"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -97955,7 +97977,7 @@
value="4"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -97966,7 +97988,7 @@
value="3"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -97977,7 +97999,7 @@
value="2"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -97988,7 +98010,7 @@
value="0"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -97999,7 +98021,7 @@
value="1"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98010,7 +98032,7 @@
value="5"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98021,7 +98043,7 @@
value="3"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98032,7 +98054,7 @@
value="7"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98042,14 +98064,14 @@
abstract="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<constructor name="SmsMessage"
type="android.telephony.gsm.SmsMessage"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</constructor>
@@ -98060,7 +98082,7 @@
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="messageBody" type="java.lang.CharSequence">
@@ -98075,7 +98097,7 @@
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="messageBody" type="java.lang.String">
@@ -98090,7 +98112,7 @@
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="pdu" type="byte[]">
@@ -98103,7 +98125,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98114,7 +98136,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98125,7 +98147,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98136,7 +98158,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98147,7 +98169,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98158,7 +98180,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98169,7 +98191,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98180,7 +98202,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98191,7 +98213,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98202,7 +98224,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98213,7 +98235,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98224,7 +98246,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98235,7 +98257,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98246,7 +98268,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98257,7 +98279,7 @@
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="scAddress" type="java.lang.String">
@@ -98276,7 +98298,7 @@
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="scAddress" type="java.lang.String">
@@ -98297,7 +98319,7 @@
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="pdu" type="java.lang.String">
@@ -98310,7 +98332,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98321,7 +98343,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98332,7 +98354,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98343,7 +98365,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98354,7 +98376,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98365,7 +98387,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98376,7 +98398,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98387,7 +98409,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98398,7 +98420,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98409,7 +98431,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</method>
@@ -98420,7 +98442,7 @@
value="3"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98431,7 +98453,7 @@
value="1"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98442,7 +98464,7 @@
value="2"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98453,7 +98475,7 @@
value="0"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98464,7 +98486,7 @@
value="140"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98475,7 +98497,7 @@
value="160"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98486,7 +98508,7 @@
value="153"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98496,7 +98518,7 @@
abstract="false"
static="true"
final="true"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<method name="valueOf"
@@ -98529,14 +98551,14 @@
abstract="false"
static="true"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<constructor name="SmsMessage.SubmitPdu"
type="android.telephony.gsm.SmsMessage.SubmitPdu"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</constructor>
@@ -98547,7 +98569,7 @@
value="null"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>
@@ -98558,7 +98580,7 @@
value="null"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
</field>

View File

@@ -117,28 +117,28 @@ public class MobileDataStateTracker extends NetworkStateTracker {
mMobileDataState = state;
switch (state) {
case DISCONNECTED:
setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
if (mInterfaceName != null) {
NetworkUtils.resetConnections(mInterfaceName);
}
mInterfaceName = null;
mDefaultGatewayAddr = 0;
break;
case CONNECTING:
setDetailedState(DetailedState.CONNECTING, reason, apnName);
break;
case SUSPENDED:
setDetailedState(DetailedState.SUSPENDED, reason, apnName);
break;
case CONNECTED:
mInterfaceName = intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY);
if (mInterfaceName == null) {
Log.d(TAG, "CONNECTED event did not supply interface name.");
}
setupDnsProperties();
setDetailedState(DetailedState.CONNECTED, reason, apnName);
break;
case DISCONNECTED:
setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
if (mInterfaceName != null) {
NetworkUtils.resetConnections(mInterfaceName);
}
mInterfaceName = null;
mDefaultGatewayAddr = 0;
break;
case CONNECTING:
setDetailedState(DetailedState.CONNECTING, reason, apnName);
break;
case SUSPENDED:
setDetailedState(DetailedState.SUSPENDED, reason, apnName);
break;
case CONNECTED:
mInterfaceName = intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY);
if (mInterfaceName == null) {
Log.d(TAG, "CONNECTED event did not supply interface name.");
}
setupDnsProperties();
setDetailedState(DetailedState.CONNECTED, reason, apnName);
break;
}
}
} else if (intent.getAction().equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
@@ -199,7 +199,7 @@ public class MobileDataStateTracker extends NetworkStateTracker {
*/
public boolean isAvailable() {
getPhoneService(false);
/*
* If the phone process has crashed in the past, we'll get a
* RemoteException and need to re-reference the service.
@@ -214,7 +214,7 @@ public class MobileDataStateTracker extends NetworkStateTracker {
if (retry == 0) getPhoneService(true);
}
}
return false;
}
@@ -241,18 +241,28 @@ public class MobileDataStateTracker extends NetworkStateTracker {
* for this network.
*/
public String getTcpBufferSizesPropName() {
String networkTypeStr = "unknown";
String networkTypeStr = "unknown";
TelephonyManager tm = new TelephonyManager(mContext);
//TODO We have to edit the parameter for getNetworkType regarding CDMA
switch(tm.getNetworkType()) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_GPRS:
networkTypeStr = "gprs";
break;
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_EDGE:
networkTypeStr = "edge";
break;
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_UMTS:
networkTypeStr = "umts";
break;
case TelephonyManager.NETWORK_TYPE_CDMA:
networkTypeStr = "cdma";
break;
case TelephonyManager.NETWORK_TYPE_EVDO_0:
networkTypeStr = "evdo";
break;
case TelephonyManager.NETWORK_TYPE_EVDO_A:
networkTypeStr = "evdo";
break;
}
return "net.tcp.buffersize." + networkTypeStr;
}
@@ -281,7 +291,7 @@ public class MobileDataStateTracker extends NetworkStateTracker {
if (retry == 0) getPhoneService(true);
}
}
Log.w(TAG, "Failed to tear down mobile data connectivity");
return false;
}
@@ -330,7 +340,7 @@ public class MobileDataStateTracker extends NetworkStateTracker {
"Ignoring mobile radio request because could not acquire PhoneService");
break;
}
try {
return mPhoneService.setRadio(turnOn);
} catch (RemoteException e) {

View File

@@ -132,6 +132,7 @@ public final class Checkin {
BROWSER_SNAP_CENTER,
BROWSER_TEXT_SIZE_CHANGE,
BROWSER_ZOOM_OVERVIEW,
CRASHES_REPORTED,
CRASHES_TRUNCATED,
ELAPSED_REALTIME_SEC,
@@ -181,6 +182,9 @@ public final class Checkin {
MARKET_REASON_PARSE_MANIFEST_EMPTY,
MARKET_REASON_UNKNOWN,
MARKET_STALE_INSTALL_ATTEMPT,
PHONE_CDMA_REGISTERED,
PHONE_CDMA_DATA_ATTEMPTED,
PHONE_CDMA_DATA_CONNECTED,
}
}
@@ -347,3 +351,6 @@ public final class Checkin {
}
}
}

View File

@@ -2049,6 +2049,70 @@ public final class Settings {
* @hide pending API council
*/
public static final String BACKGROUND_DATA = "background_data";
/**
* The CDMA roaming mode 0 = Home Networks, CDMA default
* 1 = Roaming on Affiliated networks
* 2 = Roaming on any networks
* @hide
*/
public static final String CDMA_ROAMING_MODE = "roaming_settings";
/**
* The CDMA subscription mode 0 = RUIM/SIM (default)
* 1 = NV
* @hide
*/
public static final String CDMA_SUBSCRIPTION_MODE = "subscription_mode";
/**
* represents current active phone class
* 1 = GSM-Phone, 0 = CDMA-Phone
* @hide
*/
public static final String CURRENT_ACTIVE_PHONE = "current_active_phone";
/**
* The preferred network mode 7 = Global, CDMA default
* 4 = CDMA only
* 3 = GSM/UMTS only
* @hide
*/
public static final String PREFERRED_NETWORK_MODE =
"preferred_network_mode";
/**
* CDMA Cell Broadcast SMS
* 0 = CDMA Cell Broadcast SMS disabled
* 1 = CDMA Cell Broadcast SMS enabled
* @hide
*/
public static final String CDMA_CELL_BROADCAST_SMS =
"cdma_cell_broadcast_sms";
/**
* The cdma subscription 0 = Subscription from RUIM, when available
* 1 = Subscription from NV
* @hide
*/
public static final String PREFERRED_CDMA_SUBSCRIPTION =
"preferred_cdma_subscription";
/**
* Whether the enhanced voice privacy mode is enabled.
* 0 = normal voice privacy
* 1 = enhanced voice privacy
* @hide
*/
public static final String ENHANCED_VOICE_PRIVACY_ENABLED = "enhanced_voice_privacy_enabled";
/**
* Whether the TTY mode mode is enabled.
* 0 = disabled
* 1 = enabled
* @hide
*/
public static final String TTY_MODE_ENABLED = "tty_mode_enabled";
}
/**
@@ -3127,13 +3191,13 @@ public final class Settings {
throw new RuntimeException("this should never happen");
}
String imei = TelephonyManager.getDefault().getDeviceId();
if (TextUtils.isEmpty(imei)) {
String deviceId = TelephonyManager.getDefault().getDeviceId();
if (TextUtils.isEmpty(deviceId)) {
return "";
}
byte[] hashedImei = digest.digest(imei.getBytes());
String id = new String(Base64.encodeBase64(hashedImei), 0, 12);
byte[] hashedDeviceId = digest.digest(deviceId.getBytes());
String id = new String(Base64.encodeBase64(hashedDeviceId), 0, 12);
id = id.replaceAll("/", "_");
sJidResource = JID_RESOURCE_PREFIX + id;
return sJidResource;
@@ -3152,3 +3216,4 @@ public final class Settings {
return "android-" + Long.toHexString(androidId);
}
}

View File

@@ -26,7 +26,7 @@ import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.telephony.gsm.SmsMessage;
import android.telephony.SmsMessage;
import android.text.TextUtils;
import android.text.util.Regex;
import android.util.Config;
@@ -47,6 +47,10 @@ public final class Telephony {
private static final boolean DEBUG = false;
private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
// Constructor
public Telephony() {
}
/**
* Base columns for tables that contain text based SMSs.
*/
@@ -1601,3 +1605,5 @@ public final class Telephony {
}

View File

@@ -46,6 +46,9 @@ public final class AndroidRadioDataProvider extends PhoneStateListener {
private static final int RADIO_TYPE_UNKNOWN = 0;
private static final int RADIO_TYPE_GSM = 1;
private static final int RADIO_TYPE_WCDMA = 2;
private static final int RADIO_TYPE_CDMA = 3;
private static final int RADIO_TYPE_EVDO = 4;
private static final int RADIO_TYPE_1xRTT = 5;
/** Simple container for radio data */
public static final class RadioData {
@@ -102,12 +105,21 @@ public final class AndroidRadioDataProvider extends PhoneStateListener {
}
// Finally get the radio type.
//TODO We have to edit the parameter for getNetworkType regarding CDMA
int type = telephonyManager.getNetworkType();
if (type == TelephonyManager.NETWORK_TYPE_UMTS) {
radioData.radioType = RADIO_TYPE_WCDMA;
} else if (type == TelephonyManager.NETWORK_TYPE_GPRS
|| type == TelephonyManager.NETWORK_TYPE_EDGE) {
radioData.radioType = RADIO_TYPE_GSM;
} else if (type == TelephonyManager.NETWORK_TYPE_CDMA) {
radioData.radioType = RADIO_TYPE_CDMA;
} else if (type == TelephonyManager.NETWORK_TYPE_EVDO_0) {
radioData.radioType = RADIO_TYPE_EVDO;
} else if (type == TelephonyManager.NETWORK_TYPE_EVDO_A) {
radioData.radioType = RADIO_TYPE_EVDO;
} else if (type == TelephonyManager.NETWORK_TYPE_1xRTT) {
radioData.radioType = RADIO_TYPE_1xRTT;
}
// Print out what we got.

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1099,6 +1099,9 @@
<public type="anim" name="anticipate_overshoot_interpolator" id="0x010a0009" />
<public type="anim" name="bounce_interpolator" id="0x010a000a" />
<public type="drawable" name="stat_sys_vp_phone_call" id="0x0108022d" />
<public type="drawable" name="stat_sys_vp_phone_call_on_hold" id="0x0108022e" />
<!-- ===============================================================
Resources added in version 5 of the platform.
=============================================================== -->
@@ -1106,3 +1109,8 @@
<public type="attr" name="accountType" id="0x0101026c" />
</resources>

View File

@@ -97,6 +97,12 @@
<string name="PwdMmi">Password change</string>
<!-- Displayed as the title for a success/failure report changing the SIM PIN. -->
<string name="PinMmi">PIN change</string>
<string name="CnipMmi">Calling number present</string>
<string name="CnirMmi">Calling number restricted</string>
<string name="ThreeWCMmi">Three way calling</string>
<string name="RuacMmi">Rejection of undesired annoying calls</string>
<string name="CndMmi">Calling number delivery</string>
<string name="DndMmi">Do not disturb</string>
<!-- Displayed to confirm to the user that caller ID will be restricted on the next call as usual. -->
<string name="CLIRDefaultOnNextCallOn">Caller ID defaults to restricted. Next call: Restricted</string>
@@ -2290,6 +2296,7 @@
<!-- Shown in the tutorial for tap twice for zoom control. -->
<string name="tutorial_double_tap_to_zoom_message_short">Tap twice for zoom control</string>
<!-- Shown in gadget hosts (e.g. the home screen) when there was an error inflating
the gadget. -->
<string name="gadget_host_error_inflating">Error inflating widget</string>
@@ -2316,6 +2323,7 @@
ContactsProvider and GoogleContactsProvider -->
<skip />
<!-- This string appears (on two lines) when you type a number into contacts search, to let you dial the phone number you typed. The first line will be in bigger type than the second. -->
<string name="dial_number_using">Dial number\nusing <xliff:g id="number" example="555">%s</xliff:g></string>
@@ -2326,3 +2334,8 @@
<string-array translatable="false" name="carrier_locales">
</string-array>
</resources>

View File

@@ -60,9 +60,11 @@ public class CellState {
}
public CellState(TelephonyManager telephonyManager, CellLocation location, int signalStrength) {
GsmCellLocation loc = (GsmCellLocation)location;
mLac = loc.getLac(); // example: 6032
mCid = loc.getCid(); // example: 31792
if (location instanceof GsmCellLocation) {
GsmCellLocation loc = (GsmCellLocation)location;
mLac = loc.getLac(); // example: 6032
mCid = loc.getCid(); // example: 31792
}
mTime = System.currentTimeMillis();
// Get radio type
@@ -72,6 +74,11 @@ public class CellState {
mRadioType = RADIO_TYPE_GPRS;
} else if (radioType == TelephonyManager.NETWORK_TYPE_UMTS) {
mRadioType = RADIO_TYPE_WCDMA;
} else if (radioType == TelephonyManager.NETWORK_TYPE_CDMA ||
radioType == TelephonyManager.NETWORK_TYPE_EVDO_0 ||
radioType == TelephonyManager.NETWORK_TYPE_EVDO_A ||
radioType == TelephonyManager.NETWORK_TYPE_1xRTT) {
mRadioType = RADIO_TYPE_CDMA;
}
// Get neighboring cells
@@ -290,3 +297,4 @@ public class CellState {
}
}
}

View File

@@ -38,6 +38,7 @@ import android.util.Config;
import android.util.Log;
import android.util.Xml;
import com.android.internal.util.XmlUtils;
import com.android.internal.telephony.RILConstants;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
@@ -175,7 +176,8 @@ class DatabaseHelper extends SQLiteOpenHelper {
// Shortcuts, applications, folders
db.execSQL("UPDATE favorites SET spanX=1, spanY=1 WHERE itemType<=0");
// Photo frames, clocks
db.execSQL("UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002");
db.execSQL(
"UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002");
// Search boxes
db.execSQL("UPDATE favorites SET spanX=4, spanY=1 WHERE itemType=1001");
db.setTransactionSuccessful();
@@ -582,6 +584,8 @@ class DatabaseHelper extends SQLiteOpenHelper {
+ " VALUES(?,?);");
Resources r = mContext.getResources();
loadSetting(stmt, Settings.Secure.CURRENT_ACTIVE_PHONE,
RILConstants.CDMA_PHONE);
loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
R.bool.def_dim_screen);
loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
@@ -655,6 +659,18 @@ class DatabaseHelper extends SQLiteOpenHelper {
loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
}
// Set the preferred network mode to 0 = Global, CDMA default
loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE,
RILConstants.PREFERRED_NETWORK_MODE);
// Enable or disable Cell Broadcast SMS
loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
// Set the preferred cdma subscription to 0 = Subscription from RUIM, when available
loadSetting(stmt, Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
RILConstants.PREFERRED_CDMA_SUBSCRIPTION);
// Don't do this. The SystemServer will initialize ADB_ENABLED from a
// persistent system property instead.
//loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
@@ -691,3 +707,4 @@ class DatabaseHelper extends SQLiteOpenHelper {
Float.toString(mContext.getResources().getFraction(resid, base, base)));
}
}

View File

@@ -298,8 +298,8 @@ android.telephony.PhoneNumberUtils
android.telephony.PhoneStateListener
android.telephony.ServiceState
android.telephony.TelephonyManager
android.telephony.gsm.SmsManager
android.telephony.gsm.SmsMessage
android.telephony.SmsManager
android.telephony.SmsMessage
android.text.AutoText
android.text.BoringLayout
android.text.BoringLayout$Metrics
@@ -451,17 +451,22 @@ android.view.animation.Transformation
android.view.inputmethod.BaseInputConnection
android.view.inputmethod.CompletionInfo
android.view.inputmethod.CompletionInfo$1
android.view.inputmethod.EditorInfo
android.view.inputmethod.EditorInfo$1
android.view.inputmethod.ExtractedText
android.view.inputmethod.ExtractedText$1
android.view.inputmethod.ExtractedTextRequest
android.view.inputmethod.ExtractedTextRequest$1
android.view.inputmethod.InputBinding
android.view.inputmethod.InputBinding$1
android.view.inputmethod.InputConnection
android.view.inputmethod.InputMethod
android.view.inputmethod.InputMethod$SessionCallback
android.view.inputmethod.InputMethodInfo
android.view.inputmethod.InputMethodInfo$1
android.view.inputmethod.InputMethodManager
@@ -469,6 +474,7 @@ android.view.inputmethod.InputMethodManager$1
android.view.inputmethod.InputMethodManager$2
android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
android.view.inputmethod.InputMethodManager$H
android.view.inputmethod.InputMethodSession
android.view.inputmethod.InputMethodSession$EventCallback
android.webkit.BrowserFrame
@@ -627,50 +633,59 @@ com.android.internal.telephony.Phone$State
com.android.internal.telephony.Phone$SuppService
com.android.internal.telephony.PhoneBase
com.android.internal.telephony.PhoneStateIntentReceiver
com.android.internal.telephony.SimCard$State
com.android.internal.telephony.gsm.BaseCommands
com.android.internal.telephony.gsm.CallForwardInfo
com.android.internal.telephony.gsm.CommandsInterface
com.android.internal.telephony.gsm.DriverCall
com.android.internal.telephony.gsm.DriverCall$State
com.android.internal.telephony.gsm.GSMConnection
com.android.internal.telephony.IccCard$State
com.android.internal.telephony.BaseCommands
com.android.internal.telephony.CallForwardInfo
com.android.internal.telephony.CommandsInterface
com.android.internal.telephony.DriverCall
com.android.internal.telephony.DriverCall$State
com.android.internal.telephony.gsm.GsmConnection
com.android.internal.telephony.gsm.GSMPhone
com.android.internal.telephony.gsm.GsmAlphabet
com.android.internal.telephony.GsmAlphabet
com.android.internal.telephony.gsm.GsmMmiCode
com.android.internal.telephony.gsm.GsmSimCard
com.android.internal.telephony.gsm.ISms$Stub
com.android.internal.telephony.gsm.PdpConnection$PdpFailCause
com.android.internal.telephony.gsm.RIL
com.android.internal.telephony.gsm.ServiceStateTracker
com.android.internal.telephony.gsm.SimCard
com.android.internal.telephony.ISms$Stub
com.android.internal.telephony.RIL
com.android.internal.telephony.ServiceStateTracker
com.android.internal.telephony.gsm.stk.ComprehensionTlvTag
com.android.internal.telephony.gsm.stk.ResultCode
com.android.internal.util.FastXmlSerializer
com.android.internal.view.IInputConnectionWrapper
com.android.internal.view.IInputConnectionWrapper$MyHandler
com.android.internal.view.IInputConnectionWrapper$SomeArgs
com.android.internal.view.IInputContext
com.android.internal.view.IInputContext$Stub
com.android.internal.view.IInputContext$Stub$Proxy
com.android.internal.view.IInputContextCallback
com.android.internal.view.IInputContextCallback$Stub
com.android.internal.view.IInputContextCallback$Stub$Proxy
com.android.internal.view.IInputMethod
com.android.internal.view.IInputMethod$Stub
com.android.internal.view.IInputMethod$Stub$Proxy
com.android.internal.view.IInputMethodCallback
com.android.internal.view.IInputMethodCallback$Stub
com.android.internal.view.IInputMethodCallback$Stub$Proxy
com.android.internal.view.IInputMethodClient
com.android.internal.view.IInputMethodClient$Stub
com.android.internal.view.IInputMethodClient$Stub$Proxy
com.android.internal.view.IInputMethodManager
com.android.internal.view.IInputMethodManager$Stub
com.android.internal.view.IInputMethodManager$Stub$Proxy
com.android.internal.view.IInputMethodSession
com.android.internal.view.IInputMethodSession$Stub
com.android.internal.view.IInputMethodSession$Stub$Proxy
com.android.internal.view.InputBindResult
com.android.internal.view.InputBindResult$1
com.android.internal.view.InputConnectionWrapper
com.android.internal.view.InputConnectionWrapper$InputContextCallback
com.android.internal.view.menu.ExpandedMenuView
@@ -1163,3 +1178,4 @@ org.xml.sax.helpers.NewInstance
org.xmlpull.v1.XmlPullParserFactory
org.xmlpull.v1.sax2.Driver
sun.misc.Unsafe

View File

@@ -16,13 +16,6 @@
package com.android.server.status;
import com.android.internal.R;
import com.android.internal.app.IBatteryStats;
import com.android.internal.location.GpsLocationProvider;
import com.android.internal.telephony.SimCard;
import com.android.internal.telephony.TelephonyIntents;
import com.android.server.am.BatteryStatsService;
import android.app.AlertDialog;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
@@ -59,6 +52,14 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.app.IBatteryStats;
import com.android.internal.location.GpsLocationProvider;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.TtyIntent;
import com.android.server.am.BatteryStatsService;
import java.util.Calendar;
import java.util.TimeZone;
@@ -110,7 +111,10 @@ public class StatusBarPolicy {
// phone
private TelephonyManager mPhone;
private IBinder mPhoneIcon;
//***** Signal strength icons
private IconData mPhoneData;
//GSM/UMTS
private static final int[] sSignalImages = new int[] {
com.android.internal.R.drawable.stat_sys_signal_0,
com.android.internal.R.drawable.stat_sys_signal_1,
@@ -125,7 +129,32 @@ public class StatusBarPolicy {
com.android.internal.R.drawable.stat_sys_r_signal_3,
com.android.internal.R.drawable.stat_sys_r_signal_4
};
//CDMA
private static final int[] sSignalImages_cdma = new int[] {
com.android.internal.R.drawable.stat_sys_signal_0_cdma,
com.android.internal.R.drawable.stat_sys_signal_1_cdma,
com.android.internal.R.drawable.stat_sys_signal_2_cdma,
com.android.internal.R.drawable.stat_sys_signal_3_cdma,
com.android.internal.R.drawable.stat_sys_signal_4_cdma
};
private static final int[] sSignalImages_r_cdma = new int[] {
com.android.internal.R.drawable.stat_sys_r_signal_0_cdma,
com.android.internal.R.drawable.stat_sys_r_signal_1_cdma,
com.android.internal.R.drawable.stat_sys_r_signal_2_cdma,
com.android.internal.R.drawable.stat_sys_r_signal_3_cdma,
com.android.internal.R.drawable.stat_sys_r_signal_4_cdma
};
private static final int[] sSignalImages_ra_cdma = new int[] {
com.android.internal.R.drawable.stat_sys_ra_signal_0_cdma,
com.android.internal.R.drawable.stat_sys_ra_signal_1_cdma,
com.android.internal.R.drawable.stat_sys_ra_signal_2_cdma,
com.android.internal.R.drawable.stat_sys_ra_signal_3_cdma,
com.android.internal.R.drawable.stat_sys_ra_signal_4_cdma
};
//***** Data connection icons
private int[] mDataIconList = sDataNetType_g;
//GSM/UMTS
private static final int[] sDataNetType_g = new int[] {
com.android.internal.R.drawable.stat_sys_data_connected_g,
com.android.internal.R.drawable.stat_sys_data_in_g,
@@ -144,12 +173,25 @@ public class StatusBarPolicy {
com.android.internal.R.drawable.stat_sys_data_out_e,
com.android.internal.R.drawable.stat_sys_data_inandout_e,
};
//CDMA
private static final int[] sDataNetType_evdo = new int[] {
com.android.internal.R.drawable.stat_sys_data_connected_evdo,
com.android.internal.R.drawable.stat_sys_data_in_evdo,
com.android.internal.R.drawable.stat_sys_data_out_evdo,
com.android.internal.R.drawable.stat_sys_data_inandout_evdo,
};
private static final int[] sDataNetType_1xrtt = new int[] {
com.android.internal.R.drawable.stat_sys_data_connected_1xrtt,
com.android.internal.R.drawable.stat_sys_data_in_1xrtt,
com.android.internal.R.drawable.stat_sys_data_out_1xrtt,
com.android.internal.R.drawable.stat_sys_data_inandout_1xrtt,
};
// Assume it's all good unless we hear otherwise. We don't always seem
// to get broadcasts that it *is* there.
SimCard.State mSimState = SimCard.State.READY;
IccCard.State mSimState = IccCard.State.READY;
int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
int mDataState = TelephonyManager.DATA_DISCONNECTED;
int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
ServiceState mServiceState;
int mSignalAsu = -1;
@@ -163,7 +205,7 @@ public class StatusBarPolicy {
private IBinder mVolumeIcon;
private IconData mVolumeData;
private boolean mVolumeVisible;
// bluetooth device status
private IBinder mBluetoothIcon;
private IconData mBluetoothData;
@@ -202,6 +244,11 @@ public class StatusBarPolicy {
private IBinder mSyncActiveIcon;
private IBinder mSyncFailingIcon;
// TTY mode
// Icon lit when TTY mode is enabled
private IBinder mTTYModeIcon;
private IconData mTTYModeEnableIconData;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -250,6 +297,9 @@ public class StatusBarPolicy {
else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
updateSimState(intent);
}
else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) {
updateTTY(intent);
}
}
};
@@ -294,7 +344,13 @@ public class StatusBarPolicy {
mWifiIcon = service.addIcon(mWifiData, null);
service.setIconVisibility(mWifiIcon, false);
// wifi will get updated by the sticky intents
// TTY status
mTTYModeEnableIconData = IconData.makeIcon("tty",
null, com.android.internal.R.drawable.stat_sys_tty_mode, 0, 0);
mTTYModeIcon = service.addIcon(mTTYModeEnableIconData, null);
service.setIconVisibility(mTTYModeIcon, false);
// bluetooth status
mBluetoothData = IconData.makeIcon("bluetooth",
null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0);
@@ -362,6 +418,7 @@ public class StatusBarPolicy {
filter.addAction(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION);
filter.addAction(GpsLocationProvider.GPS_FIX_CHANGE_ACTION);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
}
@@ -506,7 +563,7 @@ public class StatusBarPolicy {
com.android.internal.R.styleable.Theme);
lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f);
a.recycle();
lp.setTitle("Battery");
TextView levelTextView = (TextView)v.findViewById(com.android.internal.R.id.level_percent);
@@ -642,26 +699,26 @@ public class StatusBarPolicy {
private final void updateSimState(Intent intent) {
String stateExtra = intent.getStringExtra(SimCard.INTENT_KEY_SIM_STATE);
if (SimCard.INTENT_VALUE_SIM_ABSENT.equals(stateExtra)) {
mSimState = SimCard.State.ABSENT;
String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
mSimState = IccCard.State.ABSENT;
}
else if (SimCard.INTENT_VALUE_SIM_READY.equals(stateExtra)) {
mSimState = SimCard.State.READY;
else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
mSimState = IccCard.State.READY;
}
else if (SimCard.INTENT_VALUE_SIM_LOCKED.equals(stateExtra)) {
final String lockedReason = intent.getStringExtra(SimCard.INTENT_KEY_LOCKED_REASON);
if (SimCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
mSimState = SimCard.State.PIN_REQUIRED;
else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
mSimState = IccCard.State.PIN_REQUIRED;
}
else if (SimCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
mSimState = SimCard.State.PUK_REQUIRED;
else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
mSimState = IccCard.State.PUK_REQUIRED;
}
else {
mSimState = SimCard.State.NETWORK_LOCKED;
mSimState = IccCard.State.NETWORK_LOCKED;
}
} else {
mSimState = SimCard.State.UNKNOWN;
mSimState = IccCard.State.UNKNOWN;
}
updateDataIcon();
}
@@ -707,28 +764,54 @@ public class StatusBarPolicy {
else asu = 1;
int[] iconList;
if (mPhone.isNetworkRoaming()) {
if (mPhone.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
switch(ss.getExtendedCdmaRoaming()) {
case ServiceState.REGISTRATION_STATE_ROAMING:
iconList = this.sSignalImages_r_cdma;
break;
case ServiceState.REGISTRATION_STATE_ROAMING_AFFILIATE:
iconList = this.sSignalImages_ra_cdma;
break;
default:
iconList = this.sSignalImages_cdma;
break;
}
} else if (mPhone.isNetworkRoaming()) {
iconList = sSignalImages_r;
} else {
iconList = sSignalImages;
}
mPhoneData.iconId = iconList[asu];
mService.updateIcon(mPhoneIcon, mPhoneData, null);
}
private final void updateDataNetType() {
mDataNetType = mPhone.getNetworkType();
switch (mDataNetType) {
case TelephonyManager.NETWORK_TYPE_EDGE:
mDataIconList = sDataNetType_e;
break;
case TelephonyManager.NETWORK_TYPE_UMTS:
mDataIconList = sDataNetType_3g;
break;
default:
mDataIconList = sDataNetType_g;
break;
int net = mPhone.getNetworkType();
ServiceState ss = this.mServiceState;
switch (net) {
case TelephonyManager.NETWORK_TYPE_EDGE:
mDataIconList = sDataNetType_e;
break;
case TelephonyManager.NETWORK_TYPE_UMTS:
mDataIconList = sDataNetType_3g;
break;
case TelephonyManager.NETWORK_TYPE_CDMA:
// display 1xRTT for IS95A/B
mDataIconList = this.sDataNetType_1xrtt;
break;
case TelephonyManager.NETWORK_TYPE_1xRTT:
mDataIconList = this.sDataNetType_1xrtt;
break;
case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
case TelephonyManager.NETWORK_TYPE_EVDO_A:
mDataIconList = sDataNetType_evdo;
break;
default:
mDataIconList = sDataNetType_g;
break;
}
}
@@ -736,9 +819,9 @@ public class StatusBarPolicy {
int iconId;
boolean visible = true;
if (mSimState == SimCard.State.READY || mSimState == SimCard.State.UNKNOWN) {
if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
int data = mDataState;
int[] list = mDataIconList;
ServiceState ss = mServiceState;
@@ -775,7 +858,7 @@ public class StatusBarPolicy {
}
long ident = Binder.clearCallingIdentity();
try {
mBatteryStats.notePhoneDataConnectionState(mDataNetType, visible);
mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(ident);
@@ -865,10 +948,10 @@ public class StatusBarPolicy {
} else {
iconId = sWifiSignalImages[mLastWifiSignalLevel];
}
// Show the icon since wi-fi is connected
mService.setIconVisibility(mWifiIcon, true);
} else {
mLastWifiSignalLevel = -1;
mIsWifiConnected = false;
@@ -914,6 +997,24 @@ public class StatusBarPolicy {
}
}
private final void updateTTY(Intent intent) {
final String action = intent.getAction();
final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
Log.i(TAG, "updateTTY: enabled: " + enabled);
if (enabled) {
// TTY is on
Log.i(TAG, "updateTTY: set TTY on");
mService.updateIcon(mTTYModeIcon, mTTYModeEnableIconData, null);
mService.setIconVisibility(mTTYModeIcon, true);
} else {
// TTY is off
Log.i(TAG, "updateTTY: set TTY off");
mService.setIconVisibility(mTTYModeIcon, false);
}
}
private class StatusBarHandler extends Handler {
@Override
public void handleMessage(Message msg) {
@@ -927,3 +1028,6 @@ public class StatusBarPolicy {
}
}
}

View File

@@ -19,8 +19,14 @@ package android.telephony;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.RILConstants;
/**
* Abstract class that represents the location of the device. Currently the only
@@ -56,7 +62,17 @@ public abstract class CellLocation {
* @hide
*/
public static CellLocation newFromBundle(Bundle bundle) {
return new GsmCellLocation(bundle);
// TODO: My need to be use: Settings.Secure.getInt(mContext, Settings.Secure.CURRENT_ACTIVE_PHONE, 0))
// instead of SystemProperties???
// NOTE here TelephonyManager.getDefault().getPhoneType() cannot be used since at startup
// ITelephony have not been created
if (RILConstants.CDMA_PHONE ==
SystemProperties.getInt(Settings.Secure.CURRENT_ACTIVE_PHONE, 0)) {
return new CdmaCellLocation(bundle);
} else {
return new GsmCellLocation(bundle);
}
}
/**
@@ -66,8 +82,20 @@ public abstract class CellLocation {
/**
* Return a new CellLocation object representing an unknown location.
*
*/
public static CellLocation getEmpty() {
return new GsmCellLocation();
// TODO: My need to be use: Settings.Secure.getInt(mContext, Settings.Secure.CURRENT_ACTIVE_PHONE, 0))
// instead of SystemProperties???
// NOTE here TelephonyManager.getDefault().getPhoneType() cannot be used since at startup
// ITelephony have not been created
if (RILConstants.CDMA_PHONE ==
SystemProperties.getInt(Settings.Secure.CURRENT_ACTIVE_PHONE, 0)) {
return new CdmaCellLocation();
} else {
return new GsmCellLocation();
}
}
}

View File

@@ -25,7 +25,7 @@ import java.util.Locale;
/**
* Watches a {@link TextView} and if a phone number is entered will format it using
* {@link PhoneNumberUtils#formatNumber(Editable, int)}. The formatting is based on
* {@link PhoneNumberUtils#formatNumber(Editable, int)}. The formatting is based on
* the current system locale when this object is created and future locale changes
* may not take effect on this instance.
*/
@@ -35,7 +35,7 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
static private Locale sCachedLocale;
private boolean mFormatting;
private boolean mDeletingHyphen;
private int mHyphenStart;
private int mHyphenStart;
private boolean mDeletingBackward;
public PhoneNumberFormattingTextWatcher() {
@@ -60,7 +60,7 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
text.delete(mHyphenStart, mHyphenStart + 1);
}
}
PhoneNumberUtils.formatNumber(text, sFormatType);
mFormatting = false;
@@ -73,8 +73,8 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
// Make sure user is deleting one char, without a selection
final int selStart = Selection.getSelectionStart(s);
final int selEnd = Selection.getSelectionEnd(s);
if (s.length() > 1 // Can delete another character
&& count == 1 // Deleting only one character
if (s.length() > 1 // Can delete another character
&& count == 1 // Deleting only one character
&& after == 0 // Deleting
&& s.charAt(start) == '-' // a hyphen
&& selStart == selEnd) { // no selection
@@ -89,7 +89,7 @@ public class PhoneNumberFormattingTextWatcher implements TextWatcher {
} else {
mDeletingHyphen = false;
}
}
}
}
public void onTextChanged(CharSequence s, int start, int before, int count) {

View File

@@ -11,18 +11,18 @@ import com.android.internal.telephony.IPhoneStateListener;
/**
* A listener class for monitoring changes in specific telephony states
* on the device, including service state, signal strength, message
* on the device, including service state, signal strength, message
* waiting indicator (voicemail), and others.
* <p>
* Override the methods for the state that you wish to receive updates for, and
* Override the methods for the state that you wish to receive updates for, and
* pass your PhoneStateListener object, along with bitwise-or of the LISTEN_
* flags to {@link TelephonyManager#listen TelephonyManager.listen()}.
* <p>
* Note that access to some telephony information is
* permission-protected. Your application won't receive updates for protected
* information unless it has the appropriate permissions declared in
* permission-protected. Your application won't receive updates for protected
* information unless it has the appropriate permissions declared in
* its manifest file. Where permissions apply, they are noted in the
* appropriate LISTEN_ flags.
* appropriate LISTEN_ flags.
*/
public class PhoneStateListener {
@@ -67,17 +67,17 @@ public class PhoneStateListener {
public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008;
/**
* Listen for changes to the device's cell location. Note that
* Listen for changes to the device's cell location. Note that
* this will result in frequent callbacks to the listener.
* {@more}
* Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
* ACCESS_COARSE_LOCATION}
* <p>
* If you need regular location updates but want more control over
* the update interval or location precision, you can set up a listener
* through the {@link android.location.LocationManager location manager}
* instead.
*
* If you need regular location updates but want more control over
* the update interval or location precision, you can set up a listener
* through the {@link android.location.LocationManager location manager}
* instead.
*
* @see #onCellLocationChanged
*/
public static final int LISTEN_CELL_LOCATION = 0x00000010;
@@ -100,7 +100,7 @@ public class PhoneStateListener {
* Listen for changes to the direction of data traffic on the data
* connection (cellular).
*
* Example: The status bar uses this to display the appropriate
* Example: The status bar uses this to display the appropriate
* data-traffic icon.
*
* @see #onDataActivity
@@ -111,7 +111,7 @@ public class PhoneStateListener {
}
/**
* Callback invoked when device service state changes.
* Callback invoked when device service state changes.
*
* @see ServiceState#STATE_EMERGENCY_ONLY
* @see ServiceState#STATE_IN_SERVICE
@@ -135,28 +135,28 @@ public class PhoneStateListener {
}
/**
* Callback invoked when the message-waiting indicator changes.
* Callback invoked when the message-waiting indicator changes.
*/
public void onMessageWaitingIndicatorChanged(boolean mwi) {
// default implementation empty
}
/**
* Callback invoked when the call-forwarding indicator changes.
* Callback invoked when the call-forwarding indicator changes.
*/
public void onCallForwardingIndicatorChanged(boolean cfi) {
// default implementation empty
}
/**
* Callback invoked when device cell location changes.
* Callback invoked when device cell location changes.
*/
public void onCellLocationChanged(CellLocation location) {
// default implementation empty
}
/**
* Callback invoked when device call state changes.
* Callback invoked when device call state changes.
*
* @see TelephonyManager#CALL_STATE_IDLE
* @see TelephonyManager#CALL_STATE_RINGING
@@ -167,7 +167,7 @@ public class PhoneStateListener {
}
/**
* Callback invoked when connection state changes.
* Callback invoked when connection state changes.
*
* @see TelephonyManager#DATA_DISCONNECTED
* @see TelephonyManager#DATA_CONNECTING
@@ -179,7 +179,7 @@ public class PhoneStateListener {
}
/**
* Callback invoked when data activity state changes.
* Callback invoked when data activity state changes.
*
* @see TelephonyManager#DATA_ACTIVITY_NONE
* @see TelephonyManager#DATA_ACTIVITY_IN

View File

@@ -2,16 +2,16 @@
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

View File

@@ -19,7 +19,7 @@ package android.telephony;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.telephony.Phone;
import android.util.Log;
/**
* Contains phone state and service related information.
@@ -35,6 +35,8 @@ import com.android.internal.telephony.Phone;
*/
public class ServiceState implements Parcelable {
static final String LOG_TAG = "PHONE";
/**
* Normal operation condition, the phone is registered
* with an operator either in home network or in roaming.
@@ -59,13 +61,61 @@ public class ServiceState implements Parcelable {
*/
public static final int STATE_POWER_OFF = 3;
/**
* Available radio technologies for GSM, UMTS and CDMA.
*/
/** @hide */
public static final int RADIO_TECHNOLOGY_UNKNOWN = 0;
/** @hide */
public static final int RADIO_TECHNOLOGY_GPRS = 1;
/** @hide */
public static final int RADIO_TECHNOLOGY_EDGE = 2;
/** @hide */
public static final int RADIO_TECHNOLOGY_UMTS = 3;
/** @hide */
public static final int RADIO_TECHNOLOGY_IS95A = 4;
/** @hide */
public static final int RADIO_TECHNOLOGY_IS95B = 5;
/** @hide */
public static final int RADIO_TECHNOLOGY_1xRTT = 6;
/** @hide */
public static final int RADIO_TECHNOLOGY_EVDO_0 = 7;
/** @hide */
public static final int RADIO_TECHNOLOGY_EVDO_A = 8;
/**
* Available registration states for GSM, UMTS and CDMA.
*/
/** @hide */
public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_NOT_SEARCHING = 0;
/** @hide */
public static final int REGISTRATION_STATE_HOME_NETWORK = 1;
/** @hide */
public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_SEARCHING = 2;
/** @hide */
public static final int REGISTRATION_STATE_REGISTRATION_DENIED = 3;
/** @hide */
public static final int REGISTRATION_STATE_UNKNOWN = 4;
/** @hide */
public static final int REGISTRATION_STATE_ROAMING = 5;
/** @hide */
public static final int REGISTRATION_STATE_ROAMING_AFFILIATE = 6;
private int mState = STATE_OUT_OF_SERVICE;
private boolean mRoaming;
private int mExtendedCdmaRoaming;
private String mOperatorAlphaLong;
private String mOperatorAlphaShort;
private String mOperatorNumeric;
private boolean mIsManualNetworkSelection;
//***** CDMA
private int mRadioTechnology;
private boolean mCssIndicator;
private int mNetworkId;
private int mSystemId;
/**
* Create a new ServiceState from a intent notifier Bundle
*
@@ -105,6 +155,11 @@ public class ServiceState implements Parcelable {
mOperatorAlphaShort = s.mOperatorAlphaShort;
mOperatorNumeric = s.mOperatorNumeric;
mIsManualNetworkSelection = s.mIsManualNetworkSelection;
mRadioTechnology = s.mRadioTechnology;
mCssIndicator = s.mCssIndicator;
mNetworkId = s.mNetworkId;
mSystemId = s.mSystemId;
mExtendedCdmaRoaming = s.mExtendedCdmaRoaming;
}
/**
@@ -117,6 +172,11 @@ public class ServiceState implements Parcelable {
mOperatorAlphaShort = in.readString();
mOperatorNumeric = in.readString();
mIsManualNetworkSelection = in.readInt() != 0;
mRadioTechnology = in.readInt();
mCssIndicator = (in.readInt() != 0);
mNetworkId = in.readInt();
mSystemId = in.readInt();
mExtendedCdmaRoaming = in.readInt();
}
public void writeToParcel(Parcel out, int flags) {
@@ -126,6 +186,11 @@ public class ServiceState implements Parcelable {
out.writeString(mOperatorAlphaShort);
out.writeString(mOperatorNumeric);
out.writeInt(mIsManualNetworkSelection ? 1 : 0);
out.writeInt(mRadioTechnology);
out.writeInt(mCssIndicator ? 1 : 0);
out.writeInt(mNetworkId);
out.writeInt(mSystemId);
out.writeInt(mExtendedCdmaRoaming);
}
public int describeContents() {
@@ -166,6 +231,11 @@ public class ServiceState implements Parcelable {
return mRoaming;
}
/** @hide */
public int getExtendedCdmaRoaming(){
return this.mExtendedCdmaRoaming;
}
/**
* Get current registered operator name in long alphanumeric format
*
@@ -213,18 +283,19 @@ public class ServiceState implements Parcelable {
@Override
public int hashCode() {
return (mState * 0x1234)
return ((mState * 0x1234)
+ (mRoaming ? 1 : 0)
+ (mIsManualNetworkSelection ? 1 : 0)
+ ((null == mOperatorAlphaLong) ? 0 : mOperatorAlphaLong.hashCode())
+ ((null == mOperatorAlphaShort) ? 0 : mOperatorAlphaShort.hashCode())
+ ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode());
+ ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode())
+ (mExtendedCdmaRoaming));
}
@Override
public boolean equals (Object o) {
ServiceState s;
try {
s = (ServiceState) o;
} catch (ClassCastException ex) {
@@ -235,21 +306,66 @@ public class ServiceState implements Parcelable {
return false;
}
return mState == s.mState
return (mState == s.mState
&& mRoaming == s.mRoaming
&& mIsManualNetworkSelection == s.mIsManualNetworkSelection
&& equalsHandlesNulls(mOperatorAlphaLong, s.mOperatorAlphaLong)
&& equalsHandlesNulls(mOperatorAlphaShort, s.mOperatorAlphaShort)
&& equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric);
&& equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric)
&& equalsHandlesNulls(mRadioTechnology, s.mRadioTechnology)
&& equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
&& equalsHandlesNulls(mNetworkId, s.mNetworkId)
&& equalsHandlesNulls(mSystemId, s.mSystemId)
&& equalsHandlesNulls(mExtendedCdmaRoaming, s.mExtendedCdmaRoaming));
}
@Override
public String toString() {
return mState + " " + (mRoaming ? "roaming" : "home")
String radioTechnology = new String("Error in radioTechnology");
switch(this.mRadioTechnology) {
case 0:
radioTechnology = "Unknown";
break;
case 1:
radioTechnology = "GPRS";
break;
case 2:
radioTechnology = "EDGE";
break;
case 3:
radioTechnology = "UMTS";
break;
case 4:
radioTechnology = "IS95A";
break;
case 5:
radioTechnology = "IS95B";
break;
case 6:
radioTechnology = "1xRTT";
break;
case 7:
radioTechnology = "EvDo rev. 0";
break;
case 8:
radioTechnology = "EvDo rev. A";
break;
default:
Log.w(LOG_TAG, "mRadioTechnology variable out of range.");
break;
}
return (mState + " " + (mRoaming ? "roaming" : "home")
+ " " + mOperatorAlphaLong
+ " " + mOperatorAlphaShort
+ " " + mOperatorNumeric
+ " " + (mIsManualNetworkSelection ? "(manual)" : "");
+ " " + (mIsManualNetworkSelection ? "(manual)" : "")
+ " " + radioTechnology
+ " " + (mCssIndicator ? "CSS supported" : "CSS not supported")
+ "NetworkId: " + mNetworkId
+ "SystemId: " + mSystemId
+ "ExtendedCdmaRoaming: " + mExtendedCdmaRoaming);
}
public void setStateOutOfService() {
@@ -259,6 +375,11 @@ public class ServiceState implements Parcelable {
mOperatorAlphaShort = null;
mOperatorNumeric = null;
mIsManualNetworkSelection = false;
mRadioTechnology = 0;
mCssIndicator = false;
mNetworkId = -1;
mSystemId = -1;
mExtendedCdmaRoaming = -1;
}
public void setStateOff() {
@@ -268,6 +389,11 @@ public class ServiceState implements Parcelable {
mOperatorAlphaShort = null;
mOperatorNumeric = null;
mIsManualNetworkSelection = false;
mRadioTechnology = 0;
mCssIndicator = false;
mNetworkId = -1;
mSystemId = -1;
mExtendedCdmaRoaming = -1;
}
public void setState(int state) {
@@ -278,6 +404,11 @@ public class ServiceState implements Parcelable {
mRoaming = roaming;
}
/** @hide */
public void setExtendedCdmaRoaming (int roaming) {
this.mExtendedCdmaRoaming = roaming;
}
public void setOperatorName(String longName, String shortName, String numeric) {
mOperatorAlphaLong = longName;
mOperatorAlphaShort = shortName;
@@ -287,7 +418,7 @@ public class ServiceState implements Parcelable {
public void setIsManualSelection(boolean isManual) {
mIsManualNetworkSelection = isManual;
}
/**
* Test whether two objects hold the same data values or both are null
*
@@ -312,6 +443,11 @@ public class ServiceState implements Parcelable {
mOperatorAlphaShort = m.getString("operator-alpha-short");
mOperatorNumeric = m.getString("operator-numeric");
mIsManualNetworkSelection = m.getBoolean("manual");
mRadioTechnology = m.getInt("radioTechnology");
mCssIndicator = m.getBoolean("cssIndicator");
mNetworkId = m.getInt("networkId");
mSystemId = m.getInt("systemId");
mExtendedCdmaRoaming = m.getInt("extendedCdmaRoaming");
}
/**
@@ -327,5 +463,47 @@ public class ServiceState implements Parcelable {
m.putString("operator-alpha-short", mOperatorAlphaShort);
m.putString("operator-numeric", mOperatorNumeric);
m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection));
m.putInt("radioTechnology", mRadioTechnology);
m.putBoolean("cssIndicator", mCssIndicator);
m.putInt("networkId", mNetworkId);
m.putInt("systemId", mSystemId);
m.putInt("extendedCdmaRoaming", mExtendedCdmaRoaming);
}
//***** CDMA
/** @hide */
public void setRadioTechnology(int state) {
this.mRadioTechnology = state;
}
/** @hide */
public void setCssIndicator(int css) {
this.mCssIndicator = (css != 0);
}
/** @hide */
public void setSystemAndNetworkId(int systemId, int networkId) {
this.mSystemId = systemId;
this.mNetworkId = networkId;
}
/** @hide */
public int getRadioTechnology() {
return this.mRadioTechnology;
}
/** @hide */
public int getCssIndicator() {
return this.mCssIndicator ? 1 : 0;
}
/** @hide */
public int getNetworkId() {
return this.mNetworkId;
}
/** @hide */
public int getSystemId() {
return this.mSystemId;
}
}

View File

@@ -0,0 +1,441 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.telephony;
import android.app.PendingIntent;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.ISms;
import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.SmsRawData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static android.telephony.SmsMessage.ENCODING_7BIT;
import static android.telephony.SmsMessage.ENCODING_8BIT;
import static android.telephony.SmsMessage.ENCODING_16BIT;
import static android.telephony.SmsMessage.ENCODING_UNKNOWN;
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
/**
* Manages SMS operations such as sending data, text, and pdu SMS messages.
* Get this object by calling the static method SmsManager.getDefault().
* @hide
*/
public final class SmsManager {
private static SmsManager sInstance;
/**
* Send a text based SMS.
*
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
* @param text the body of the message to send
* @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is sucessfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* The per-application based SMS control checks sentIntent. If sentIntent
* is NULL the caller will be checked against all unknown applications,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or text are empty
*/
public void sendTextMessage(
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
if (TextUtils.isEmpty(text)) {
throw new IllegalArgumentException("Invalid message body");
}
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
scAddress, destinationAddress, text, (deliveryIntent != null));
sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
}
/**
* Divide a text message into several messages, none bigger than
* the maximum SMS message size.
*
* @param text the original message. Must not be null.
* @return an <code>ArrayList</code> of strings that, in order,
* comprise the original message
*/
public ArrayList<String> divideMessage(String text) {
int size = text.length();
int[] params = SmsMessage.calculateLength(text, false);
/* SmsMessage.calculateLength returns an int[4] with:
* int[0] being the number of SMS's required,
* int[1] the number of code units used,
* int[2] is the number of code units remaining until the next message.
* int[3] is the encoding type that should be used for the message.
*/
int messageCount = params[0];
int encodingType = params[3];
ArrayList<String> result = new ArrayList<String>(messageCount);
int start = 0;
int limit;
if (messageCount > 1) {
limit = (encodingType == ENCODING_7BIT)?
MAX_USER_DATA_SEPTETS_WITH_HEADER: MAX_USER_DATA_BYTES_WITH_HEADER;
} else {
limit = (encodingType == ENCODING_7BIT)?
MAX_USER_DATA_SEPTETS: MAX_USER_DATA_BYTES;
}
try {
while (start < size) {
int end = GsmAlphabet.findLimitIndex(text, start, limit, encodingType);
result.add(text.substring(start, end));
start = end;
}
}
catch (EncodeException e) {
// ignore it.
}
return result;
}
/**
* Send a multi-part text based SMS. The callee should have already
* divided the message into correctly sized parts by calling
* <code>divideMessage</code>.
*
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message
* @param sentIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been sent.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* The per-application based SMS control checks sentIntent. If sentIntent
* is NULL the caller will be checked against all unknown applicaitons,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been delivered
* to the recipient. The raw pdu of the status report is in the
* extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or data are empty
*/
public void sendMultipartTextMessage(
String destinationAddress, String scAddress, ArrayList<String> parts,
ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
if (parts == null || parts.size() < 1) {
throw new IllegalArgumentException("Invalid message body");
}
if (parts.size() > 1) {
try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (iccISms != null) {
iccISms.sendMultipartText(destinationAddress, scAddress, parts,
sentIntents, deliveryIntents);
}
} catch (RemoteException ex) {
// ignore it
}
} else {
PendingIntent sentIntent = null;
PendingIntent deliveryIntent = null;
if (sentIntents != null && sentIntents.size() > 0) {
sentIntent = sentIntents.get(0);
}
if (deliveryIntents != null && deliveryIntents.size() > 0) {
deliveryIntent = deliveryIntents.get(0);
}
sendTextMessage(destinationAddress, scAddress, parts.get(0),
sentIntent, deliveryIntent);
}
}
/**
* Send a data based SMS to a specific application port.
*
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
* @param destinationPort the port to deliver the message to
* @param data the body of the message to send
* @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is sucessfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* The per-application based SMS control checks sentIntent. If sentIntent
* is NULL the caller will be checked against all unknown applicaitons,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or data are empty
*/
public void sendDataMessage(
String destinationAddress, String scAddress, short destinationPort,
byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
if (data == null || data.length == 0) {
throw new IllegalArgumentException("Invalid message data");
}
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
scAddress, destinationAddress,
destinationPort, data, (deliveryIntent != null));
sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
}
/**
* Send a raw SMS PDU.
*
* @param smsc the SMSC to send the message through, or NULL for the
* default SMSC
* @param pdu the raw PDU to send
* @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is successfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* The per-application based SMS control checks sentIntent. If sentIntent
* is NULL the caller will be checked against all unknown applications,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*
* @hide
*/
private void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (iccISms != null) {
iccISms.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
}
} catch (RemoteException ex) {
// ignore it
}
}
/**
* Get the default instance of the SmsManager
*
* @return the default instance of the SmsManager
*/
public static SmsManager getDefault() {
if (sInstance == null) {
sInstance = new SmsManager();
}
return sInstance;
}
private SmsManager() {
//nothing
}
/**
* Copy a raw SMS PDU to the ICC.
*
* @param smsc the SMSC for this message, or NULL for the default SMSC
* @param pdu the raw PDU to store
* @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
* STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
* @return true for success
*
* {@hide}
*/
public boolean copyMessageToIcc(byte[] smsc, byte[] pdu, int status) {
boolean success = false;
try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (iccISms != null) {
success = iccISms.copyMessageToIccEf(status, pdu, smsc);
}
} catch (RemoteException ex) {
// ignore it
}
return success;
}
/**
* Delete the specified message from the ICC.
*
* @param messageIndex is the record index of the message on ICC
* @return true for success
*
* {@hide}
*/
public boolean
deleteMessageFromIcc(int messageIndex) {
boolean success = false;
byte[] pdu = new byte[IccConstants.SMS_RECORD_LENGTH-1];
Arrays.fill(pdu, (byte)0xff);
try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (iccISms != null) {
success = iccISms.updateMessageOnIccEf(messageIndex, STATUS_ON_ICC_FREE, pdu);
}
} catch (RemoteException ex) {
// ignore it
}
return success;
}
/**
* Update the specified message on the ICC.
*
* @param messageIndex record index of message to update
* @param newStatus new message status (STATUS_ON_ICC_READ,
* STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
* STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
* @param pdu the raw PDU to store
* @return true for success
*
* {@hide}
*/
public boolean updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu) {
boolean success = false;
try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (iccISms != null) {
success = iccISms.updateMessageOnIccEf(messageIndex, newStatus, pdu);
}
} catch (RemoteException ex) {
// ignore it
}
return success;
}
/**
* Retrieves all messages currently stored on ICC.
*
* @return <code>ArrayList</code> of <code>SmsMessage</code> objects
*
* {@hide}
*/
public ArrayList<SmsMessage> getAllMessagesFromIcc() {
List<SmsRawData> records = null;
try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (iccISms != null) {
records = iccISms.getAllMessagesFromIccEf();
}
} catch (RemoteException ex) {
// ignore it
}
return createMessageListFromRawRecords(records);
}
/**
* Create a list of <code>SmsMessage</code>s from a list of RawSmsData
* records returned by <code>getAllMessagesFromIcc()</code>
*
* @param records SMS EF records, returned by
* <code>getAllMessagesFromIcc</code>
* @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
*/
private ArrayList<SmsMessage> createMessageListFromRawRecords(List records) {
ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
if (records != null) {
int count = records.size();
for (int i = 0; i < count; i++) {
SmsRawData data = (SmsRawData)records.get(i);
// List contains all records, including "free" records (null)
if (data != null) {
SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes());
messages.add(sms);
}
}
}
return messages;
}
// see SmsMessage.getStatusOnIcc
/** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
static public final int STATUS_ON_ICC_FREE = 0;
/** Received and read (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
static public final int STATUS_ON_ICC_READ = 1;
/** Received and unread (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
static public final int STATUS_ON_ICC_UNREAD = 3;
/** Stored and sent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
static public final int STATUS_ON_ICC_SENT = 5;
/** Stored and unsent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
static public final int STATUS_ON_ICC_UNSENT = 7;
// SMS send failure result codes
/** Generic failure cause */
static public final int RESULT_ERROR_GENERIC_FAILURE = 1;
/** Failed because radio was explicitly turned off */
static public final int RESULT_ERROR_RADIO_OFF = 2;
/** Failed because no pdu provided */
static public final int RESULT_ERROR_NULL_PDU = 3;
/** Failed because service is currently unavailable */
static public final int RESULT_ERROR_NO_SERVICE = 4;
}

View File

@@ -0,0 +1,628 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.telephony;
import android.os.Parcel;
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
/**
* A Short Message Service message.
* @hide
*/
public class SmsMessage {
private static final boolean LOCAL_DEBUG = true;
private static final String LOG_TAG = "SMS";
/**
* SMS Class enumeration.
* See TS 23.038.
*
*/
public enum MessageClass{
UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
}
/** Unknown encoding scheme (see TS 23.038) */
public static final int ENCODING_UNKNOWN = 0;
/** 7-bit encoding scheme (see TS 23.038) */
public static final int ENCODING_7BIT = 1;
/** 8-bit encoding scheme (see TS 23.038) */
public static final int ENCODING_8BIT = 2;
/** 16-bit encoding scheme (see TS 23.038) */
public static final int ENCODING_16BIT = 3;
/** The maximum number of payload bytes per message */
public static final int MAX_USER_DATA_BYTES = 140;
/**
* The maximum number of payload bytes per message if a user data header
* is present. This assumes the header only contains the
* CONCATENATED_8_BIT_REFERENCE element.
*
* @hide pending API Council approval to extend the public API
*/
public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
/** The maximum number of payload septets per message */
public static final int MAX_USER_DATA_SEPTETS = 160;
/**
* The maximum number of payload septets per message if a user data header
* is present. This assumes the header only contains the
* CONCATENATED_8_BIT_REFERENCE element.
*/
public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
/** Contains actual SmsMessage. Only public for debugging and for framework layer.
* {@hide}
*/
public SmsMessageBase mWrappedSmsMessage;
public static class SubmitPdu extends SubmitPduBase {
//Constructor
public SubmitPdu() {
}
/* {@hide} */
protected SubmitPdu(SubmitPduBase spb) {
this.encodedMessage = spb.encodedMessage;
this.encodedScAddress = spb.encodedScAddress;
}
}
// Constructor
public SmsMessage() {
this(getSmsFacility());
}
private SmsMessage(SmsMessageBase smb) {
mWrappedSmsMessage = smb;
}
/**
* Create an SmsMessage from a raw PDU.
*/
public static SmsMessage createFromPdu(byte[] pdu) {
SmsMessageBase wrappedMessage;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
}
return new SmsMessage(wrappedMessage);
}
/**
* TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
* +CMT unsolicited response (PDU mode, of course)
* +CMT: [&lt;alpha>],<length><CR><LF><pdu>
*
* Only public for debugging and for RIL
*
* {@hide}
*/
public static SmsMessage newFromCMT(String[] lines){
SmsMessageBase wrappedMessage;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMT(lines);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);
}
return new SmsMessage(wrappedMessage);
}
/** @hide */
protected static SmsMessage newFromCMTI(String line) {
SmsMessageBase wrappedMessage;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMTI(line);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMTI(line);
}
return new SmsMessage(wrappedMessage);
}
/** @hide */
public static SmsMessage newFromCDS(String line) {
SmsMessageBase wrappedMessage;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCDS(line);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCDS(line);
}
return new SmsMessage(wrappedMessage);
}
/** @hide */
public static SmsMessage newFromParcel(Parcel p) {
SmsMessageBase wrappedMessage;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromParcel(p);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromParcel(p);
}
return new SmsMessage(wrappedMessage);
}
/**
* Create an SmsMessage from an SMS EF record.
*
* @param index Index of SMS record. This should be index in ArrayList
* returned by SmsManager.getAllMessagesFromSim + 1.
* @param data Record data.
* @return An SmsMessage representing the record.
*
* @hide
*/
public static SmsMessage createFromEfRecord(int index, byte[] data) {
SmsMessageBase wrappedMessage;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord(
index, data);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromEfRecord(
index, data);
}
return new SmsMessage(wrappedMessage);
}
/**
* Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
* length in bytes (not hex chars) less the SMSC header
*/
public static int getTPLayerLengthForPDU(String pdu) {
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
return com.android.internal.telephony.cdma.SmsMessage.getTPLayerLengthForPDU(pdu);
} else {
return com.android.internal.telephony.gsm.SmsMessage.getTPLayerLengthForPDU(pdu);
}
}
/**
* Calculates the number of SMS's required to encode the message body and
* the number of characters remaining until the next message, given the
* current encoding.
*
* @param messageBody the message to encode
* @param use7bitOnly if true, characters that are not part of the GSM
* alphabet are counted as a single space char. If false, a
* messageBody containing non-GSM alphabet characters is calculated
* for 16-bit encoding.
* @return an int[4] with int[0] being the number of SMS's required, int[1]
* the number of code units used, and int[2] is the number of code
* units remaining until the next message. int[3] is the encoding
* type that should be used for the message.
*/
public static int[] calculateLength(CharSequence messageBody, boolean use7bitOnly) {
int ret[] = new int[4];
try {
// Try GSM alphabet
int septets = GsmAlphabet.countGsmSeptets(messageBody, !use7bitOnly);
ret[1] = septets;
if (septets > MAX_USER_DATA_SEPTETS) {
ret[0] = (septets / MAX_USER_DATA_SEPTETS_WITH_HEADER) + 1;
ret[2] = MAX_USER_DATA_SEPTETS_WITH_HEADER
- (septets % MAX_USER_DATA_SEPTETS_WITH_HEADER);
} else {
ret[0] = 1;
ret[2] = MAX_USER_DATA_SEPTETS - septets;
}
ret[3] = ENCODING_7BIT;
} catch (EncodeException ex) {
// fall back to UCS-2
int octets = messageBody.length() * 2;
ret[1] = messageBody.length();
if (octets > MAX_USER_DATA_BYTES) {
// 6 is the size of the user data header
ret[0] = (octets / MAX_USER_DATA_BYTES_WITH_HEADER) + 1;
ret[2] = (MAX_USER_DATA_BYTES_WITH_HEADER
- (octets % MAX_USER_DATA_BYTES_WITH_HEADER))/2;
} else {
ret[0] = 1;
ret[2] = (MAX_USER_DATA_BYTES - octets)/2;
}
ret[3] = ENCODING_16BIT;
}
return ret;
}
/**
* Calculates the number of SMS's required to encode the message body and
* the number of characters remaining until the next message, given the
* current encoding.
*
* @param messageBody the message to encode
* @param use7bitOnly if true, characters that are not part of the GSM
* alphabet are counted as a single space char. If false, a
* messageBody containing non-GSM alphabet characters is calculated
* for 16-bit encoding.
* @return an int[4] with int[0] being the number of SMS's required, int[1]
* the number of code units used, and int[2] is the number of code
* units remaining until the next message. int[3] is the encoding
* type that should be used for the message.
*/
public static int[] calculateLength(String messageBody, boolean use7bitOnly) {
return calculateLength((CharSequence)messageBody, use7bitOnly);
}
/**
* Get an SMS-SUBMIT PDU for a destination address and a message
*
* @param scAddress Service Centre address. Null means use default.
* @return a <code>SubmitPdu</code> containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
* @hide
*/
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, String message,
boolean statusReportRequested, byte[] header) {
SubmitPduBase spb;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested, header);
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested, header);
}
return new SubmitPdu(spb);
}
/**
* Get an SMS-SUBMIT PDU for a destination address and a message
*
* @param scAddress Service Centre address. Null means use default.
* @return a <code>SubmitPdu</code> containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
*/
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, String message, boolean statusReportRequested) {
SubmitPduBase spb;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested);
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, message, statusReportRequested);
}
return new SubmitPdu(spb);
}
/**
* Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
*
* @param scAddress Service Centre address. null == use default
* @param destinationAddress the address of the destination for the message
* @param destinationPort the port to deliver the message to at the
* destination
* @param data the dat for the message
* @return a <code>SubmitPdu</code> containing the encoded SC
* address, if applicable, and the encoded message.
* Returns null on encode error.
*/
public static SubmitPdu getSubmitPdu(String scAddress,
String destinationAddress, short destinationPort, byte[] data,
boolean statusReportRequested) {
SubmitPduBase spb;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, destinationPort, data, statusReportRequested);
} else {
spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
destinationAddress, destinationPort, data, statusReportRequested);
}
return new SubmitPdu(spb);
}
/**
* Returns the address of the SMS service center that relayed this message
* or null if there is none.
*/
public String getServiceCenterAddress() {
return mWrappedSmsMessage.getServiceCenterAddress();
}
/**
* Returns the originating address (sender) of this SMS message in String
* form or null if unavailable
*/
public String getOriginatingAddress() {
return mWrappedSmsMessage.getOriginatingAddress();
}
/**
* Returns the originating address, or email from address if this message
* was from an email gateway. Returns null if originating address
* unavailable.
*/
public String getDisplayOriginatingAddress() {
return mWrappedSmsMessage.getDisplayOriginatingAddress();
}
/**
* Returns the message body as a String, if it exists and is text based.
* @return message body is there is one, otherwise null
*/
public String getMessageBody() {
return mWrappedSmsMessage.getMessageBody();
}
/**
* Returns the class of this message.
*/
public MessageClass getMessageClass() {
return mWrappedSmsMessage.getMessageClass();
}
/**
* Returns the message body, or email message body if this message was from
* an email gateway. Returns null if message body unavailable.
*/
public String getDisplayMessageBody() {
return mWrappedSmsMessage.getDisplayMessageBody();
}
/**
* Unofficial convention of a subject line enclosed in parens empty string
* if not present
*/
public String getPseudoSubject() {
return mWrappedSmsMessage.getPseudoSubject();
}
/**
* Returns the service centre timestamp in currentTimeMillis() format
*/
public long getTimestampMillis() {
return mWrappedSmsMessage.getTimestampMillis();
}
/**
* Returns true if message is an email.
*
* @return true if this message came through an email gateway and email
* sender / subject / parsed body are available
*/
public boolean isEmail() {
return mWrappedSmsMessage.isEmail();
}
/**
* @return if isEmail() is true, body of the email sent through the gateway.
* null otherwise
*/
public String getEmailBody() {
return mWrappedSmsMessage.getEmailBody();
}
/**
* @return if isEmail() is true, email from address of email sent through
* the gateway. null otherwise
*/
public String getEmailFrom() {
return mWrappedSmsMessage.getEmailFrom();
}
/**
* Get protocol identifier.
*/
public int getProtocolIdentifier() {
return mWrappedSmsMessage.getProtocolIdentifier();
}
/**
* See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
* SMS
*/
public boolean isReplace() {
return mWrappedSmsMessage.isReplace();
}
/**
* Returns true for CPHS MWI toggle message.
*
* @return true if this is a CPHS MWI toggle message See CPHS 4.2 section
* B.4.2
*/
public boolean isCphsMwiMessage() {
return mWrappedSmsMessage.isCphsMwiMessage();
}
/**
* returns true if this message is a CPHS voicemail / message waiting
* indicator (MWI) clear message
*/
public boolean isMWIClearMessage() {
return mWrappedSmsMessage.isMWIClearMessage();
}
/**
* returns true if this message is a CPHS voicemail / message waiting
* indicator (MWI) set message
*/
public boolean isMWISetMessage() {
return mWrappedSmsMessage.isMWISetMessage();
}
/**
* returns true if this message is a "Message Waiting Indication Group:
* Discard Message" notification and should not be stored.
*/
public boolean isMwiDontStore() {
return mWrappedSmsMessage.isMwiDontStore();
}
/**
* returns the user data section minus the user data header if one was
* present.
*/
public byte[] getUserData() {
return mWrappedSmsMessage.getUserData();
}
/* Not part of the SDK interface and only needed by specific classes:
protected SmsHeader getUserDataHeader()
*/
/**
* Returns the raw PDU for the message.
*
* @return the raw PDU for the message.
*/
public byte[] getPdu() {
return mWrappedSmsMessage.getPdu();
}
/**
* Returns the status of the message on the SIM (read, unread, sent, unsent).
*
* @return the status of the message on the SIM. These are:
* SmsManager.STATUS_ON_SIM_FREE
* SmsManager.STATUS_ON_SIM_READ
* SmsManager.STATUS_ON_SIM_UNREAD
* SmsManager.STATUS_ON_SIM_SEND
* SmsManager.STATUS_ON_SIM_UNSENT
* @deprecated Use getStatusOnIcc instead.
*/
@Deprecated public int getStatusOnSim() {
return mWrappedSmsMessage.getStatusOnIcc();
}
/**
* Returns the status of the message on the ICC (read, unread, sent, unsent).
*
* @return the status of the message on the ICC. These are:
* SmsManager.STATUS_ON_ICC_FREE
* SmsManager.STATUS_ON_ICC_READ
* SmsManager.STATUS_ON_ICC_UNREAD
* SmsManager.STATUS_ON_ICC_SEND
* SmsManager.STATUS_ON_ICC_UNSENT
*/
public int getStatusOnIcc() {
return mWrappedSmsMessage.getStatusOnIcc();
}
/**
* Returns the record index of the message on the SIM (1-based index).
* @return the record index of the message on the SIM, or -1 if this
* SmsMessage was not created from a SIM SMS EF record.
* @deprecated Use getIndexOnIcc instead.
*/
@Deprecated public int getIndexOnSim() {
return mWrappedSmsMessage.getIndexOnIcc();
}
/**
* Returns the record index of the message on the ICC (1-based index).
* @return the record index of the message on the ICC, or -1 if this
* SmsMessage was not created from a ICC SMS EF record.
*/
public int getIndexOnIcc() {
return mWrappedSmsMessage.getIndexOnIcc();
}
/**
* GSM:
* For an SMS-STATUS-REPORT message, this returns the status field from
* the status report. This field indicates the status of a previously
* submitted SMS, if requested. See TS 23.040, 9.2.3.15 TP-Status for a
* description of values.
* CDMA:
* For not interfering with status codes from GSM, the value is
* shifted to the bits 31-16.
* The value is composed of an error class (bits 25-24) and a status code (bits 23-16).
* Possible codes are described in C.S0015-B, v2.0, 4.5.21.
*
* @return 0 indicates the previously sent message was received.
* See TS 23.040, 9.9.2.3.15 and C.S0015-B, v2.0, 4.5.21
* for a description of other possible values.
*/
public int getStatus() {
return mWrappedSmsMessage.getStatus();
}
/**
* Return true iff the message is a SMS-STATUS-REPORT message.
*/
public boolean isStatusReportMessage() {
return mWrappedSmsMessage.isStatusReportMessage();
}
/**
* Returns true iff the <code>TP-Reply-Path</code> bit is set in
* this message.
*/
public boolean isReplyPathPresent() {
return mWrappedSmsMessage.isReplyPathPresent();
}
/** This method returns the reference to a specific
* SmsMessage object, which is used for accessing its static methods.
* @return Specific SmsMessage.
*/
private static final SmsMessageBase getSmsFacility(){
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
return new com.android.internal.telephony.cdma.SmsMessage();
} else {
return new com.android.internal.telephony.gsm.SmsMessage();
}
}
}

View File

@@ -28,25 +28,31 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.telephony.CellLocation;
import com.android.internal.telephony.IPhoneSubInfo;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.TelephonyProperties;
/**
* Provides access to information about the telephony services on
* the device. Applications can use the methods in this class to
* determine telephony services and states, as well as to access some
* types of subscriber information. Applications can also register
* a listener to receive notification of telephony state changes.
* types of subscriber information. Applications can also register
* a listener to receive notification of telephony state changes.
* <p>
* You do not instantiate this class directly; instead, you retrieve
* a reference to an instance through
* a reference to an instance through
* {@link android.content.Context#getSystemService
* Context.getSystemService(Context.TELEPHONY_SERVICE)}.
* <p>
* Note that acess to some telephony information is
* permission-protected. Your application cannot access the protected
* information unless it has the appropriate permissions declared in
* its manifest file. Where permissions apply, they are noted in the
* the methods through which you access the protected information.
* permission-protected. Your application cannot access the protected
* information unless it has the appropriate permissions declared in
* its manifest file. Where permissions apply, they are noted in the
* the methods through which you access the protected information.
*/
public class TelephonyManager {
private static final String TAG = "TelephonyManager";
@@ -166,10 +172,10 @@ public class TelephonyManager {
//
/**
* Returns the software version number for the device, for example,
* Returns the software version number for the device, for example,
* the IMEI/SV for GSM phones.
*
* <p>Requires Permission:
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getDeviceSoftwareVersion() {
@@ -181,10 +187,10 @@ public class TelephonyManager {
}
/**
* Returns the unique device ID, for example,the IMEI for GSM
* Returns the unique device ID, for example, the IMEI for GSM and the MEID for CDMA
* phones.
*
* <p>Requires Permission:
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getDeviceId() {
@@ -214,7 +220,7 @@ public class TelephonyManager {
* Enables location update notifications. {@link PhoneStateListener#onCellLocationChanged
* PhoneStateListener.onCellLocationChanged} will be called on location updates.
*
* <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
* <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
* CONTROL_LOCATION_UPDATES}
*
* @hide
@@ -270,23 +276,37 @@ public class TelephonyManager {
public static final int PHONE_TYPE_GSM = 1;
/**
* Returns a constant indicating the device phone type.
*
* CDMA phone
* @hide
*/
public static final int PHONE_TYPE_CDMA = 2;
/**
* Returns a constant indicating the device phone type.
*
* @see #PHONE_TYPE_NONE
* @see #PHONE_TYPE_GSM
* @see #PHONE_TYPE_CDMA
*/
public int getPhoneType() {
// in the future, we should really check this
return PHONE_TYPE_GSM;
try{
if(getITelephony().getActivePhoneType() == RILConstants.CDMA_PHONE) {
return PHONE_TYPE_CDMA;
} else {
return PHONE_TYPE_GSM;
}
}catch(RemoteException ex){
return PHONE_TYPE_NONE;
}
}
//
//
//
// Current Network
//
//
/**
/**
* Returns the alphabetic name of current registered operator.
* <p>
* Availability: Only when user is registered to a network
@@ -295,7 +315,7 @@ public class TelephonyManager {
return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA);
}
/**
/**
* Returns the numeric name (MCC+MNC) of current registered operator.
* <p>
* Availability: Only when user is registered to a network
@@ -304,7 +324,7 @@ public class TelephonyManager {
return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
}
/**
/**
* Returns true if the device is considered roaming on the current
* network, for GSM purposes.
* <p>
@@ -314,7 +334,7 @@ public class TelephonyManager {
return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
}
/**
/**
* Returns the ISO country code equivilent of the current registered
* operator's MCC (Mobile Country Code).
* <p>
@@ -332,9 +352,20 @@ public class TelephonyManager {
public static final int NETWORK_TYPE_EDGE = 2;
/** Current network is UMTS */
public static final int NETWORK_TYPE_UMTS = 3;
/** Current network is CDMA: Either IS95A or IS95B*/
/** @hide */
public static final int NETWORK_TYPE_CDMA = 4;
/** Current network is EVDO revision 0 or revision A*/
/** @hide */
public static final int NETWORK_TYPE_EVDO_0 = 5;
/** @hide */
public static final int NETWORK_TYPE_EVDO_A = 6;
/** Current network is 1xRTT*/
/** @hide */
public static final int NETWORK_TYPE_1xRTT = 7;
/**
* Returns a constant indicating the radio technology (network type)
* Returns a constant indicating the radio technology (network type)
* currently in use on the device.
* @return the network type
*
@@ -342,6 +373,10 @@ public class TelephonyManager {
* @see #NETWORK_TYPE_GPRS
* @see #NETWORK_TYPE_EDGE
* @see #NETWORK_TYPE_UMTS
* @see #NETWORK_TYPE_CDMA
* @see #NETWORK_TYPE_EVDO_0
* @see #NETWORK_TYPE_EVDO_A
* @see #NETWORK_TYPE_1xRTT
*/
public int getNetworkType() {
String prop = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE);
@@ -354,6 +389,18 @@ public class TelephonyManager {
else if ("UMTS".equals(prop)) {
return NETWORK_TYPE_UMTS;
}
else if ("CDMA".equals(prop)) {
return NETWORK_TYPE_CDMA;
}
else if ("CDMA - EvDo rev. 0".equals(prop)) {
return NETWORK_TYPE_EVDO_0;
}
else if ("CDMA - EvDo rev. A".equals(prop)) {
return NETWORK_TYPE_EVDO_A;
}
else if ("CDMA - 1xRTT".equals(prop)) {
return NETWORK_TYPE_1xRTT;
}
else {
return NETWORK_TYPE_UNKNOWN;
}
@@ -374,6 +421,14 @@ public class TelephonyManager {
return "EDGE";
case NETWORK_TYPE_UMTS:
return "UMTS";
case NETWORK_TYPE_CDMA:
return "CDMA";
case NETWORK_TYPE_EVDO_0:
return "CDMA - EvDo rev. 0";
case NETWORK_TYPE_EVDO_A:
return "CDMA - EvDo rev. A";
case NETWORK_TYPE_1xRTT:
return "CDMA - 1xRTT";
default:
return "UNKNOWN";
}
@@ -387,7 +442,7 @@ public class TelephonyManager {
/** SIM card state: Unknown. Signifies that the SIM is in transition
* between states. For example, when the user inputs the SIM pin
* under PIN_REQUIRED state, a query for sim status returns
* under PIN_REQUIRED state, a query for sim status returns
* this state before turning to SIM_STATE_READY. */
public static final int SIM_STATE_UNKNOWN = 0;
/** SIM card state: no SIM card is available in the device */
@@ -400,11 +455,11 @@ public class TelephonyManager {
public static final int SIM_STATE_NETWORK_LOCKED = 4;
/** SIM card state: Ready */
public static final int SIM_STATE_READY = 5;
/**
* Returns a constant indicating the state of the
/**
* Returns a constant indicating the state of the
* device SIM card.
*
*
* @see #SIM_STATE_UNKNOWN
* @see #SIM_STATE_ABSENT
* @see #SIM_STATE_PIN_REQUIRED
@@ -434,7 +489,7 @@ public class TelephonyManager {
}
}
/**
/**
* Returns the MCC+MNC (mobile country code + mobile network code) of the
* provider of the SIM. 5 or 6 decimal digits.
* <p>
@@ -443,36 +498,36 @@ public class TelephonyManager {
* @see #getSimState
*/
public String getSimOperator() {
return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC);
return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC);
}
/**
* Returns the Service Provider Name (SPN).
/**
* Returns the Service Provider Name (SPN).
* <p>
* Availability: SIM state must be {@link #SIM_STATE_READY}
*
* @see #getSimState
*/
public String getSimOperatorName() {
return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ALPHA);
return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA);
}
/**
/**
* Returns the ISO country code equivalent for the SIM provider's country code.
*/
public String getSimCountryIso() {
return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ISO_COUNTRY);
return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY);
}
/**
* Returns the serial number of the SIM, if applicable.
* <p>
* Requires Permission:
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getSimSerialNumber() {
try {
return getSubscriberInfo().getSimSerialNumber();
return getSubscriberInfo().getIccSerialNumber();
} catch (RemoteException ex) {
}
return null;
@@ -487,7 +542,7 @@ public class TelephonyManager {
/**
* Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
* <p>
* Requires Permission:
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getSubscriberId() {
@@ -499,10 +554,10 @@ public class TelephonyManager {
}
/**
* Returns the phone number string for line 1, for example, the MSISDN
* Returns the phone number string for line 1, for example, the MSISDN
* for a GSM phone.
* <p>
* Requires Permission:
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getLine1Number() {
@@ -514,9 +569,9 @@ public class TelephonyManager {
}
/**
* Returns the alphabetic identifier associated with the line 1 number.
* Returns the alphabetic identifier associated with the line 1 number.
* <p>
* Requires Permission:
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
* @hide
* nobody seems to call this.
@@ -532,7 +587,7 @@ public class TelephonyManager {
/**
* Returns the voice mail number.
* <p>
* Requires Permission:
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getVoiceMailNumber() {
@@ -547,7 +602,7 @@ public class TelephonyManager {
* Retrieves the alphabetic identifier associated with the voice
* mail number.
* <p>
* Requires Permission:
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getVoiceMailAlphaTag() {
@@ -567,10 +622,10 @@ public class TelephonyManager {
/** Device call state: No activity. */
public static final int CALL_STATE_IDLE = 0;
/** Device call state: Ringing. A new call arrived and is
* ringing or waiting. In the latter case, another call is
* ringing or waiting. In the latter case, another call is
* already active. */
public static final int CALL_STATE_RINGING = 1;
/** Device call state: Off-hook. At least one call exists
/** Device call state: Off-hook. At least one call exists
* that is dialing, active, or on hold, and no calls are ringing
* or waiting. */
public static final int CALL_STATE_OFFHOOK = 2;
@@ -621,13 +676,13 @@ public class TelephonyManager {
public static final int DATA_CONNECTING = 1;
/** Data connection state: Connected. IP traffic should be available. */
public static final int DATA_CONNECTED = 2;
/** Data connection state: Suspended. The connection is up, but IP
* traffic is temporarily unavailable. For example, in a 2G network,
/** Data connection state: Suspended. The connection is up, but IP
* traffic is temporarily unavailable. For example, in a 2G network,
* data activity may be suspended when a voice call arrives. */
public static final int DATA_SUSPENDED = 3;
/**
* Returns a constant indicating the current data connection state
* Returns a constant indicating the current data connection state
* (cellular).
*
* @see #DATA_DISCONNECTED
@@ -655,26 +710,26 @@ public class TelephonyManager {
//
/**
* Registers a listener object to receive notification of changes
* in specified telephony states.
* Registers a listener object to receive notification of changes
* in specified telephony states.
* <p>
* To register a listener, pass a {@link PhoneStateListener}
* and specify at least one telephony state of interest in
* the events argument.
*
* and specify at least one telephony state of interest in
* the events argument.
*
* At registration, and when a specified telephony state
* changes, the telephony manager invokes the appropriate
* callback method on the listener object and passes the
* changes, the telephony manager invokes the appropriate
* callback method on the listener object and passes the
* current (udpated) values.
* <p>
* To unregister a listener, pass the listener object and set the
* events argument to
* events argument to
* {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
*
*
* @param listener The {@link PhoneStateListener} object to register
* (or unregister)
* @param events The telephony state(s) of interest to the listener,
* as a bitwise-OR combination of {@link PhoneStateListener}
* as a bitwise-OR combination of {@link PhoneStateListener}
* LISTEN_ flags.
*/
public void listen(PhoneStateListener listener, int events) {

View File

@@ -0,0 +1,146 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.telephony.cdma;
import android.os.Bundle;
import android.telephony.CellLocation;
/**
* Represents the cell location on a GSM phone.
* @hide
*/
public class CdmaCellLocation extends CellLocation {
private int mBaseStationId = -1;
private int mBaseStationLatitude = -1;
private int mBaseStationLongitude = -1;
/**
* Empty constructor. Initializes the LAC and CID to -1.
*/
public CdmaCellLocation() {
this.mBaseStationId = -1;
this.mBaseStationLatitude = -1;
this.mBaseStationLongitude = -1;
}
/**
* Initialize the object from a bundle.
*/
public CdmaCellLocation(Bundle bundleWithValues) {
this.mBaseStationId = bundleWithValues.getInt("baseStationId");
this.mBaseStationLatitude = bundleWithValues.getInt("baseStationLatitude");
this.mBaseStationLongitude = bundleWithValues.getInt("baseStationLongitude");
}
/**
* @return cdma base station identification number, -1 if unknown
*/
public int getBaseStationId() {
return this.mBaseStationId;
}
/**
* @return cdma base station latitude, -1 if unknown
*/
public int getBaseStationLatitude() {
return this.mBaseStationLatitude;
}
/**
* @return cdma base station longitude, -1 if unknown
*/
public int getBaseStationLongitude() {
return this.mBaseStationLongitude;
}
/**
* Invalidate this object. The cell location data is set to -1.
*/
public void setStateInvalid() {
this.mBaseStationId = -1;
this.mBaseStationLatitude = -1;
this.mBaseStationLongitude = -1;
}
/**
* Set the cell location data.
*/
public void setCellLocationData(int baseStationId, int baseStationLatitude,
int baseStationLongitude) {
// The following values have to be written in the correct sequence
this.mBaseStationId = baseStationId;
this.mBaseStationLatitude = baseStationLatitude; //values[2];
this.mBaseStationLongitude = baseStationLongitude; //values[3];
}
@Override
public int hashCode() {
return this.mBaseStationId ^ this.mBaseStationLatitude ^ this.mBaseStationLongitude;
}
@Override
public boolean equals(Object o) {
CdmaCellLocation s;
try {
s = (CdmaCellLocation)o;
} catch (ClassCastException ex) {
return false;
}
if (o == null) {
return false;
}
return (equalsHandlesNulls(this.mBaseStationId, s.mBaseStationId) &&
equalsHandlesNulls(this.mBaseStationLatitude, s.mBaseStationLatitude) &&
equalsHandlesNulls(this.mBaseStationLongitude, s.mBaseStationLongitude)
);
}
@Override
public String toString() {
return "[" + this.mBaseStationId + ","
+ this.mBaseStationLatitude + ","
+ this.mBaseStationLongitude + "]";
}
/**
* Test whether two objects hold the same data values or both are null
*
* @param a first obj
* @param b second obj
* @return true if two objects equal or both are null
*/
private static boolean equalsHandlesNulls(Object a, Object b) {
return (a == null) ? (b == null) : a.equals (b);
}
/**
* Fill the cell location data into the intent notifier Bundle based on service state
*
* @param bundleToFill intent notifier Bundle
*/
public void fillInNotifierBundle(Bundle bundleToFill) {
bundleToFill.putInt("baseStationId", this.mBaseStationId);
bundleToFill.putInt("baseStationLatitude", this.mBaseStationLatitude);
bundleToFill.putInt("baseStationLongitude", this.mBaseStationLongitude);
}
}

View File

@@ -0,0 +1,5 @@
<HTML>
<BODY>
Provides APIs for utilizing CDMA-specific telephony features.
</BODY>
</HTML>

View File

@@ -17,14 +17,12 @@
package android.telephony.gsm;
import android.os.Bundle;
import com.android.internal.telephony.Phone;
import android.telephony.CellLocation;
/**
* Represents the cell location on a GSM phone.
*/
public class GsmCellLocation extends CellLocation
{
public class GsmCellLocation extends CellLocation {
private int mLac;
private int mCid;
@@ -82,7 +80,7 @@ public class GsmCellLocation extends CellLocation
@Override
public boolean equals(Object o) {
GsmCellLocation s;
try {
s = (GsmCellLocation)o;
} catch (ClassCastException ex) {
@@ -100,7 +98,7 @@ public class GsmCellLocation extends CellLocation
public String toString() {
return "["+ mLac + "," + mCid + "]";
}
/**
* Test whether two objects hold the same data values or both are null
*

View File

@@ -17,28 +17,35 @@
package android.telephony.gsm;
import android.app.PendingIntent;
import android.os.RemoteException;
import android.os.IServiceManager;
import android.os.ServiceManager;
import android.os.ServiceManagerNative;
import android.text.TextUtils;
import com.android.internal.telephony.gsm.EncodeException;
import com.android.internal.telephony.gsm.GsmAlphabet;
import com.android.internal.telephony.gsm.ISms;
import com.android.internal.telephony.gsm.SimConstants;
import com.android.internal.telephony.gsm.SmsRawData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Manages SMS operations such as sending data, text, and pdu SMS messages.
* Get this object by calling the static method SmsManager.getDefault().
* @deprecated Replaced by android.telephony.SmsManager that supports both GSM and CDMA.
*/
public final class SmsManager {
@Deprecated public final class SmsManager {
private static SmsManager sInstance;
private android.telephony.SmsManager mSmsMgrProxy;
/** Get the default instance of the SmsManager
*
* @return the default instance of the SmsManager
* @deprecated Use android.telephony.SmsManager.
*/
@Deprecated
public static final SmsManager getDefault() {
if (sInstance == null) {
sInstance = new SmsManager();
}
return sInstance;
}
private SmsManager() {
mSmsMgrProxy = android.telephony.SmsManager.getDefault();
}
/**
* Send a text based SMS.
@@ -55,28 +62,21 @@ public final class SmsManager {
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* The per-application based SMS control checks sentIntent. If sentIntent
* is NULL the caller will be checked against all unknown applicaitons,
* is NULL the caller will be checked against all unknown applications,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or text are empty
* @deprecated Use android.telephony.SmsManager.
*/
public void sendTextMessage(
@Deprecated
public final void sendTextMessage(
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
if (TextUtils.isEmpty(text)) {
throw new IllegalArgumentException("Invalid message body");
}
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
scAddress, destinationAddress, text, (deliveryIntent != null));
sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
mSmsMgrProxy.sendTextMessage(destinationAddress, scAddress, text,
sentIntent, deliveryIntent);
}
/**
@@ -86,55 +86,24 @@ 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
* @deprecated Use android.telephony.SmsManager.
*/
public ArrayList<String> divideMessage(String text) {
int size = text.length();
int[] params = SmsMessage.calculateLength(text, false);
/* SmsMessage.calculateLength returns an int[4] with:
* int[0] being the number of SMS's required,
* int[1] the number of code units used,
* int[2] is the number of code units remaining until the next message.
* int[3] is the encoding type that should be used for the message.
*/
int messageCount = params[0];
int encodingType = params[3];
ArrayList<String> result = new ArrayList<String>(messageCount);
int start = 0;
int limit;
if (messageCount > 1) {
limit = (encodingType == SmsMessage.ENCODING_7BIT) ?
SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER :
SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
} else {
limit = (encodingType == SmsMessage.ENCODING_7BIT) ?
SmsMessage.MAX_USER_DATA_SEPTETS : SmsMessage.MAX_USER_DATA_BYTES;
}
try {
while (start < size) {
int end = GsmAlphabet.findLimitIndex(text, start, limit, encodingType);
result.add(text.substring(start, end));
start = end;
}
} catch (EncodeException e) {
// ignore it.
}
return result;
@Deprecated
public final ArrayList<String> divideMessage(String text) {
return mSmsMgrProxy.divideMessage(text);
}
/**
* Send a multi-part text based SMS. The callee should have already
* divided the message into correctly sized parts by calling
* <code>divideMessage</code>.
*
*
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message
* @param sentIntents if not null, an <code>ArrayList</code> of
* @param sentIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been sent.
* The result code will be <code>Activity.RESULT_OK<code> for success,
@@ -145,44 +114,21 @@ public final class SmsManager {
* The per-application based SMS control checks sentIntent. If sentIntent
* is NULL the caller will be checked against all unknown applicaitons,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntents if not null, an <code>ArrayList</code> of
* @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been delivered
* to the recipient. The raw pdu of the status report is in the
* extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or data are empty
* @deprecated Use android.telephony.SmsManager.
*/
public void sendMultipartTextMessage(
@Deprecated
public final void sendMultipartTextMessage(
String destinationAddress, String scAddress, ArrayList<String> parts,
ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
if (parts == null || parts.size() < 1) {
throw new IllegalArgumentException("Invalid message body");
}
if (parts.size() > 1) {
try {
ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (simISms != null) {
simISms.sendMultipartText(destinationAddress, scAddress, parts,
sentIntents, deliveryIntents);
}
} catch (RemoteException ex) {
// ignore it
}
} else {
PendingIntent sentIntent = null;
PendingIntent deliveryIntent = null;
if (sentIntents != null && sentIntents.size() > 0) {
sentIntent = sentIntents.get(0);
}
if (deliveryIntents != null && deliveryIntents.size() > 0) {
deliveryIntent = deliveryIntents.get(0);
}
sendTextMessage(destinationAddress, scAddress, parts.get(0),
sentIntent, deliveryIntent);
}
mSmsMgrProxy.sendMultipartTextMessage(destinationAddress, scAddress, parts,
sentIntents, deliveryIntents);
}
/**
@@ -208,70 +154,14 @@ public final class SmsManager {
* raw pdu of the status report is in the extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or data are empty
* @deprecated Use android.telephony.SmsManager.
*/
public void sendDataMessage(
@Deprecated
public final void sendDataMessage(
String destinationAddress, String scAddress, short destinationPort,
byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
if (data == null || data.length == 0) {
throw new IllegalArgumentException("Invalid message data");
}
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
destinationPort, data, (deliveryIntent != null));
sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
}
/**
* Send a raw SMS PDU.
*
* @param smsc the SMSC to send the message through, or NULL for the
* default SMSC
* @param pdu the raw PDU to send
* @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is sucessfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* The per-application based SMS control checks sentIntent. If sentIntent
* is NULL the caller will be checked against all unknown applicaitons,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*
*/
private void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
try {
ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (simISms != null) {
simISms.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
}
} catch (RemoteException ex) {
// ignore it
}
}
/**
* Get the default instance of the SmsManager
*
* @return the default instance of the SmsManager
*/
public static SmsManager getDefault() {
if (sInstance == null) {
sInstance = new SmsManager();
}
return sInstance;
}
private SmsManager() {
// nothing to see here
mSmsMgrProxy.sendDataMessage(destinationAddress, scAddress, destinationPort,
data, sentIntent, deliveryIntent);
}
/**
@@ -282,22 +172,12 @@ public final class SmsManager {
* @param status message status (STATUS_ON_SIM_READ, STATUS_ON_SIM_UNREAD,
* STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT)
* @return true for success
*
* @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
public boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) {
boolean success = false;
try {
ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (simISms != null) {
success = simISms.copyMessageToSimEf(status, pdu, smsc);
}
} catch (RemoteException ex) {
// ignore it
}
return success;
@Deprecated
public final boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) {
return mSmsMgrProxy.copyMessageToIcc(smsc, pdu, status);
}
/**
@@ -305,26 +185,12 @@ public final class SmsManager {
*
* @param messageIndex is the record index of the message on SIM
* @return true for success
*
* @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
public boolean
deleteMessageFromSim(int messageIndex) {
boolean success = false;
byte[] pdu = new byte[SimConstants.SMS_RECORD_LENGTH-1];
Arrays.fill(pdu, (byte)0xff);
try {
ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (simISms != null) {
success = simISms.updateMessageOnSimEf(messageIndex,
STATUS_ON_SIM_FREE, pdu);
}
} catch (RemoteException ex) {
// ignore it
}
return success;
@Deprecated
public final boolean deleteMessageFromSim(int messageIndex) {
return mSmsMgrProxy.deleteMessageFromIcc(messageIndex);
}
/**
@@ -336,97 +202,59 @@ public final class SmsManager {
* STATUS_ON_SIM_UNSENT, STATUS_ON_SIM_FREE)
* @param pdu the raw PDU to store
* @return true for success
*
* @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
public boolean updateMessageOnSim(int messageIndex, int newStatus,
byte[] pdu) {
boolean success = false;
try {
ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (simISms != null) {
success = simISms.updateMessageOnSimEf(messageIndex, newStatus, pdu);
}
} catch (RemoteException ex) {
// ignore it
}
return success;
@Deprecated
public final boolean updateMessageOnSim(int messageIndex, int newStatus, byte[] pdu) {
return mSmsMgrProxy.updateMessageOnIcc(messageIndex, newStatus, pdu);
}
/**
* Retrieves all messages currently stored on SIM.
*
* @return <code>ArrayList</code> of <code>SmsMessage</code> objects
*
* @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
public ArrayList<SmsMessage> getAllMessagesFromSim() {
List<SmsRawData> records = null;
try {
ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (simISms != null) {
records = simISms.getAllMessagesFromSimEf();
}
} catch (RemoteException ex) {
// ignore it
}
return createMessageListFromRawRecords(records);
}
/**
* Create a list of <code>SmsMessage</code>s from a list of RawSmsData
* records returned by <code>getAllMessagesFromSim()</code>
*
* @param records SMS EF records, returned by
* <code>getAllMessagesFromSim</code>
* @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
*/
private ArrayList<SmsMessage> createMessageListFromRawRecords(List records) {
ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
if (records != null) {
int count = records.size();
for (int i = 0; i < count; i++) {
SmsRawData data = (SmsRawData)records.get(i);
// List contains all records, including "free" records (null)
if (data != null) {
SmsMessage sms =
SmsMessage.createFromEfRecord(i+1, data.getBytes());
messages.add(sms);
}
}
}
return messages;
@Deprecated
public final ArrayList<android.telephony.SmsMessage> getAllMessagesFromSim() {
return mSmsMgrProxy.getAllMessagesFromIcc();
}
/** Free space (TS 51.011 10.5.3). */
static public final int STATUS_ON_SIM_FREE = 0;
/** Free space (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_FREE = 0;
/** Received and read (TS 51.011 10.5.3). */
static public final int STATUS_ON_SIM_READ = 1;
/** Received and read (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_READ = 1;
/** Received and unread (TS 51.011 10.5.3). */
static public final int STATUS_ON_SIM_UNREAD = 3;
/** Received and unread (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_UNREAD = 3;
/** Stored and sent (TS 51.011 10.5.3). */
static public final int STATUS_ON_SIM_SENT = 5;
/** Stored and sent (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_SENT = 5;
/** Stored and unsent (TS 51.011 10.5.3). */
static public final int STATUS_ON_SIM_UNSENT = 7;
/** Stored and unsent (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_UNSENT = 7;
/** Generic failure cause
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int RESULT_ERROR_GENERIC_FAILURE = 1;
// SMS send failure result codes
/** Failed because radio was explicitly turned off
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int RESULT_ERROR_RADIO_OFF = 2;
/** Failed because no pdu provided
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int RESULT_ERROR_NULL_PDU = 3;
/** Failed because service is currently unavailable
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int RESULT_ERROR_NO_SERVICE = 4;
/** Generic failure cause */
static public final int RESULT_ERROR_GENERIC_FAILURE = 1;
/** Failed because radio was explicitly turned off */
static public final int RESULT_ERROR_RADIO_OFF = 2;
/** Failed because no pdu provided */
static public final int RESULT_ERROR_NULL_PDU = 3;
/** Failed because service is currently unavailable */
static public final int RESULT_ERROR_NO_SERVICE = 4;
}

File diff suppressed because it is too large Load Diff

View File

@@ -34,7 +34,7 @@ public class ATResponseParser
{
this.line = line;
}
public boolean
nextBoolean()
{
@@ -147,7 +147,7 @@ public class ATResponseParser
}
}
/** Throws ATParseEx if whitespace extends to the end of string */
private char
skipWhiteSpace (char c)

View File

@@ -14,6 +14,7 @@
** limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
parcelable AdnRecord;

View File

@@ -0,0 +1,283 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import com.android.internal.telephony.GsmAlphabet;
/**
*
* Used to load or store ADNs (Abbreviated Dialing Numbers).
*
* {@hide}
*
*/
public class AdnRecord implements Parcelable {
static final String LOG_TAG = "GSM";
//***** Instance Variables
String alphaTag = "";
String number = "";
int extRecord = 0xff;
int efid; // or 0 if none
int recordNumber; // or 0 if none
//***** Constants
// In an ADN record, everything but the alpha identifier
// is in a footer that's 14 bytes
static final int FOOTER_SIZE_BYTES = 14;
// Maximum size of the un-extended number field
static final int MAX_NUMBER_SIZE_BYTES = 11;
static final int EXT_RECORD_LENGTH_BYTES = 13;
static final int EXT_RECORD_TYPE_ADDITIONAL_DATA = 2;
static final int EXT_RECORD_TYPE_MASK = 3;
static final int MAX_EXT_CALLED_PARTY_LENGTH = 0xa;
// ADN offset
static final int ADN_BCD_NUMBER_LENGTH = 0;
static final int ADN_TON_AND_NPI = 1;
static final int ADN_DAILING_NUMBER_START = 2;
static final int ADN_DAILING_NUMBER_END = 11;
static final int ADN_CAPABILITY_ID = 12;
static final int ADN_EXTENSION_ID = 13;
//***** Static Methods
public static final Parcelable.Creator<AdnRecord> CREATOR
= new Parcelable.Creator<AdnRecord>() {
public AdnRecord createFromParcel(Parcel source) {
int efid;
int recordNumber;
String alphaTag;
String number;
efid = source.readInt();
recordNumber = source.readInt();
alphaTag = source.readString();
number = source.readString();
return new AdnRecord(efid, recordNumber, alphaTag, number);
}
public AdnRecord[] newArray(int size) {
return new AdnRecord[size];
}
};
//***** Constructor
public
AdnRecord (byte[] record) {
this(0, 0, record);
}
public
AdnRecord (int efid, int recordNumber, byte[] record) {
this.efid = efid;
this.recordNumber = recordNumber;
parseRecord(record);
}
public
AdnRecord (String alphaTag, String number) {
this(0, 0, alphaTag, number);
}
public
AdnRecord (int efid, int recordNumber, String alphaTag, String number) {
this.efid = efid;
this.recordNumber = recordNumber;
this.alphaTag = alphaTag;
this.number = number;
}
//***** Instance Methods
public String getAlphaTag() {
return alphaTag;
}
public String getNumber() {
return number;
}
public String toString() {
return "ADN Record '" + alphaTag + "' '" + number + "'";
}
public boolean isEmpty() {
return alphaTag.equals("") && number.equals("");
}
public boolean hasExtendedRecord() {
return extRecord != 0 && extRecord != 0xff;
}
public boolean isEqual(AdnRecord adn) {
return ( alphaTag.equals(adn.getAlphaTag()) &&
number.equals(adn.getNumber()) );
}
//***** Parcelable Implementation
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(efid);
dest.writeInt(recordNumber);
dest.writeString(alphaTag);
dest.writeString(number);
}
/**
* Build adn hex byte array based on record size
* The format of byte array is defined in 51.011 10.5.1
*
* @param recordSize is the size X of EF record
* @return hex byte[recordSize] to be written to EF record
* return nulll for wrong format of dialing nubmer or tag
*/
public byte[] buildAdnString(int recordSize) {
byte[] bcdNumber;
byte[] byteTag;
byte[] adnString = null;
int footerOffset = recordSize - FOOTER_SIZE_BYTES;
if (number == null || number.equals("") ||
alphaTag == null || alphaTag.equals("")) {
Log.w(LOG_TAG, "[buildAdnString] Empty alpha tag or number");
adnString = new byte[recordSize];
for (int i = 0; i < recordSize; i++) {
adnString[i] = (byte) 0xFF;
}
} else if (number.length()
> (ADN_DAILING_NUMBER_END - ADN_DAILING_NUMBER_START + 1) * 2) {
Log.w(LOG_TAG,
"[buildAdnString] Max length of dailing number is 20");
} else if (alphaTag.length() > footerOffset) {
Log.w(LOG_TAG,
"[buildAdnString] Max length of tag is " + footerOffset);
} else {
adnString = new byte[recordSize];
for (int i = 0; i < recordSize; i++) {
adnString[i] = (byte) 0xFF;
}
bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(number);
System.arraycopy(bcdNumber, 0, adnString,
footerOffset + ADN_TON_AND_NPI, bcdNumber.length);
adnString[footerOffset + ADN_BCD_NUMBER_LENGTH]
= (byte) (bcdNumber.length);
adnString[footerOffset + ADN_CAPABILITY_ID]
= (byte) 0xFF; // Capacility Id
adnString[footerOffset + ADN_EXTENSION_ID]
= (byte) 0xFF; // Extension Record Id
byteTag = GsmAlphabet.stringToGsm8BitPacked(alphaTag);
System.arraycopy(byteTag, 0, adnString, 0, byteTag.length);
}
return adnString;
}
/**
* See TS 51.011 10.5.10
*/
public void
appendExtRecord (byte[] extRecord) {
try {
if (extRecord.length != EXT_RECORD_LENGTH_BYTES) {
return;
}
if ((extRecord[0] & EXT_RECORD_TYPE_MASK)
!= EXT_RECORD_TYPE_ADDITIONAL_DATA) {
return;
}
if ((0xff & extRecord[1]) > MAX_EXT_CALLED_PARTY_LENGTH) {
// invalid or empty record
return;
}
number += PhoneNumberUtils.calledPartyBCDFragmentToString(
extRecord, 2, 0xff & extRecord[1]);
// We don't support ext record chaining.
} catch (RuntimeException ex) {
Log.w(LOG_TAG, "Error parsing AdnRecord ext record", ex);
}
}
//***** Private Methods
/**
* alphaTag and number are set to null on invalid format
*/
private void
parseRecord(byte[] record) {
try {
alphaTag = IccUtils.adnStringFieldToString(
record, 0, record.length - FOOTER_SIZE_BYTES);
int footerOffset = record.length - FOOTER_SIZE_BYTES;
int numberLength = 0xff & record[footerOffset];
if (numberLength > MAX_NUMBER_SIZE_BYTES) {
// Invalid number length
number = "";
return;
}
// Please note 51.011 10.5.1:
//
// "If the Dialling Number/SSC String does not contain
// a dialling number, e.g. a control string deactivating
// a service, the TON/NPI byte shall be set to 'FF' by
// the ME (see note 2)."
number = PhoneNumberUtils.calledPartyBCDToString(
record, footerOffset + 1, numberLength);
extRecord = 0xff & record[record.length - 1];
} catch (RuntimeException ex) {
Log.w(LOG_TAG, "Error parsing AdnRecord", ex);
number = "";
alphaTag = "";
}
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import android.util.SparseArray;
import android.util.Log;
@@ -23,18 +23,18 @@ import android.os.Handler;
import android.os.AsyncResult;
import java.util.ArrayList;
import java.util.Iterator;
import com.android.internal.telephony.IccConstants;
/**
* {@hide}
*/
public final class AdnRecordCache extends Handler implements SimConstants
{
public final class AdnRecordCache extends Handler implements IccConstants {
//***** Instance Variables
GSMPhone phone;
PhoneBase phone;
// Indexed by EF ID
SparseArray<ArrayList<AdnRecord>> adnLikeFiles
SparseArray<ArrayList<AdnRecord>> adnLikeFiles
= new SparseArray<ArrayList<AdnRecord>>();
// People waiting for ADN-like files to be loaded
@@ -52,9 +52,8 @@ public final class AdnRecordCache extends Handler implements SimConstants
//***** Constructor
/*package*/
AdnRecordCache(GSMPhone phone)
{
public AdnRecordCache(PhoneBase phone) {
this.phone = phone;
}
@@ -63,14 +62,12 @@ public final class AdnRecordCache extends Handler implements SimConstants
/**
* Called from SIMRecords.onRadioNotAvailable and SIMRecords.handleSimRefresh.
*/
/*package*/ void
reset()
{
public void reset() {
adnLikeFiles.clear();
clearWaiters();
clearUserWriters();
}
private void clearWaiters() {
@@ -95,29 +92,27 @@ public final class AdnRecordCache extends Handler implements SimConstants
* @return List of AdnRecords for efid if we've already loaded them this
* radio session, or null if we haven't
*/
/*package*/ ArrayList<AdnRecord>
getRecordsIfLoaded(int efid)
{
public ArrayList<AdnRecord>
getRecordsIfLoaded(int efid) {
return adnLikeFiles.get(efid);
}
/**
* Returns extension ef associated with ADN-like EF or -1 if
* Returns extension ef associated with ADN-like EF or -1 if
* we don't know.
*
* See 3GPP TS 51.011 for this mapping
*/
private int
extensionEfForEf(int efid)
{
extensionEfForEf(int efid) {
switch (efid) {
case EF_MBDN: return EF_EXT6;
case EF_ADN: return EF_EXT1;
case EF_SDN: return EF_EXT3;
case EF_FDN: return EF_EXT2;
case EF_MSISDN: return EF_EXT1;
case EF_MSISDN: return EF_EXT1;
default: return -1;
}
}
}
private void sendErrorResponse(Message response, String errString) {
@@ -138,7 +133,7 @@ public final class AdnRecordCache extends Handler implements SimConstants
* @param response message to be posted when done
* response.exception hold the exception in error
*/
void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2,
public void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2,
Message response) {
int extensionEF = extensionEfForEf(efid);
@@ -174,7 +169,7 @@ public final class AdnRecordCache extends Handler implements SimConstants
* @param response message to be posted when done
* response.exception hold the exception in error
*/
void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn,
public void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn,
String pin2, Message response) {
int extensionEF;
@@ -227,9 +222,8 @@ public final class AdnRecordCache extends Handler implements SimConstants
* Responds with exception (in response) if efid is not a known ADN-like
* record
*/
/*package*/ void
requestLoadAllAdnLike (int efid, Message response)
{
public void
requestLoadAllAdnLike (int efid, Message response) {
ArrayList<Message> waiters;
ArrayList<AdnRecord> result;
@@ -256,25 +250,25 @@ public final class AdnRecordCache extends Handler implements SimConstants
waiters.add(response);
return;
}
// Start loading efid
waiters = new ArrayList<Message>();
waiters.add(response);
adnLikeWaiters.put(efid, waiters);
int extensionEF = extensionEfForEf(efid);
if (extensionEF < 0) {
// respond with error if not known ADN-like record
if (response != null) {
AsyncResult.forMessage(response).exception
AsyncResult.forMessage(response).exception
= new RuntimeException("EF is not known ADN-like EF:" + efid);
response.sendToTarget();
}
return;
}
@@ -285,8 +279,7 @@ public final class AdnRecordCache extends Handler implements SimConstants
//***** Private methods
private void
notifyWaiters(ArrayList<Message> waiters, AsyncResult ar)
{
notifyWaiters(ArrayList<Message> waiters, AsyncResult ar) {
if (waiters == null) {
return;

View File

@@ -0,0 +1,285 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import java.util.ArrayList;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class AdnRecordLoader extends Handler {
static String LOG_TAG;
//***** Instance Variables
PhoneBase phone;
int ef;
int extensionEF;
int pendingExtLoads;
Message userResponse;
String pin2;
// For "load one"
int recordNumber;
// for "load all"
ArrayList<AdnRecord> adns; // only valid after EVENT_ADN_LOAD_ALL_DONE
// Either an AdnRecord or a reference to adns depending
// if this is a load one or load all operation
Object result;
//***** Event Constants
static final int EVENT_ADN_LOAD_DONE = 1;
static final int EVENT_EXT_RECORD_LOAD_DONE = 2;
static final int EVENT_ADN_LOAD_ALL_DONE = 3;
static final int EVENT_EF_LINEAR_RECORD_SIZE_DONE = 4;
static final int EVENT_UPDATE_RECORD_DONE = 5;
//***** Constructor
public AdnRecordLoader(PhoneBase phone) {
// The telephony unit-test cases may create AdnRecords
// in secondary threads
super(phone.getHandler().getLooper());
this.phone = phone;
LOG_TAG = phone.getPhoneName();
}
/**
* Resulting AdnRecord is placed in response.obj.result
* or response.obj.exception is set
*/
public void
loadFromEF(int ef, int extensionEF, int recordNumber,
Message response) {
this.ef = ef;
this.extensionEF = extensionEF;
this.recordNumber = recordNumber;
this.userResponse = response;
phone.mIccFileHandler.loadEFLinearFixed(
ef, recordNumber,
obtainMessage(EVENT_ADN_LOAD_DONE));
}
/**
* Resulting ArrayList&lt;adnRecord> is placed in response.obj.result
* or response.obj.exception is set
*/
public void
loadAllFromEF(int ef, int extensionEF,
Message response) {
this.ef = ef;
this.extensionEF = extensionEF;
this.userResponse = response;
phone.mIccFileHandler.loadEFLinearFixedAll(
ef,
obtainMessage(EVENT_ADN_LOAD_ALL_DONE));
}
/**
* Write adn to a EF SIM record
* It will get the record size of EF record and compose hex adn array
* then write the hex array to EF record
*
* @param adn is set with alphaTag and phoneNubmer
* @param ef EF fileid
* @param extensionEF extension EF fileid
* @param recordNumber 1-based record index
* @param pin2 for CHV2 operations, must be null if pin2 is not needed
* @param response will be sent to its handler when completed
*/
public void
updateEF(AdnRecord adn, int ef, int extensionEF, int recordNumber,
String pin2, Message response) {
this.ef = ef;
this.extensionEF = extensionEF;
this.recordNumber = recordNumber;
this.userResponse = response;
this.pin2 = pin2;
phone.mIccFileHandler.getEFLinearRecordSize( ef,
obtainMessage(EVENT_EF_LINEAR_RECORD_SIZE_DONE, adn));
}
//***** Overridden from Handler
public void
handleMessage(Message msg) {
AsyncResult ar;
byte data[];
AdnRecord adn;
try {
switch (msg.what) {
case EVENT_EF_LINEAR_RECORD_SIZE_DONE:
ar = (AsyncResult)(msg.obj);
adn = (AdnRecord)(ar.userObj);
if (ar.exception != null) {
throw new RuntimeException("get EF record size failed",
ar.exception);
}
int[] recordSize = (int[])ar.result;
// recordSize is int[3] array
// int[0] is the record length
// int[1] is the total length of the EF file
// int[2] is the number of records in the EF file
// So int[0] * int[2] = int[1]
if (recordSize.length != 3 || recordNumber > recordSize[2]) {
throw new RuntimeException("get wrong EF record size format",
ar.exception);
}
data = adn.buildAdnString(recordSize[0]);
if(data == null) {
throw new RuntimeException("worong ADN format",
ar.exception);
}
phone.mIccFileHandler.updateEFLinearFixed(ef, recordNumber,
data, pin2, obtainMessage(EVENT_UPDATE_RECORD_DONE));
pendingExtLoads = 1;
break;
case EVENT_UPDATE_RECORD_DONE:
ar = (AsyncResult)(msg.obj);
if (ar.exception != null) {
throw new RuntimeException("update EF adn record failed",
ar.exception);
}
pendingExtLoads = 0;
result = null;
break;
case EVENT_ADN_LOAD_DONE:
ar = (AsyncResult)(msg.obj);
data = (byte[])(ar.result);
if (ar.exception != null) {
throw new RuntimeException("load failed", ar.exception);
}
if (false) {
Log.d(LOG_TAG,"ADN EF: 0x"
+ Integer.toHexString(ef)
+ ":" + recordNumber
+ "\n" + IccUtils.bytesToHexString(data));
}
adn = new AdnRecord(ef, recordNumber, data);
result = adn;
if (adn.hasExtendedRecord()) {
// If we have a valid value in the ext record field,
// we're not done yet: we need to read the corresponding
// ext record and append it
pendingExtLoads = 1;
phone.mIccFileHandler.loadEFLinearFixed(
extensionEF, adn.extRecord,
obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
}
break;
case EVENT_EXT_RECORD_LOAD_DONE:
ar = (AsyncResult)(msg.obj);
data = (byte[])(ar.result);
adn = (AdnRecord)(ar.userObj);
if (ar.exception != null) {
throw new RuntimeException("load failed", ar.exception);
}
Log.d(LOG_TAG,"ADN extention EF: 0x"
+ Integer.toHexString(extensionEF)
+ ":" + adn.extRecord
+ "\n" + IccUtils.bytesToHexString(data));
adn.appendExtRecord(data);
pendingExtLoads--;
// result should have been set in
// EVENT_ADN_LOAD_DONE or EVENT_ADN_LOAD_ALL_DONE
break;
case EVENT_ADN_LOAD_ALL_DONE:
ar = (AsyncResult)(msg.obj);
ArrayList<byte[]> datas = (ArrayList<byte[]>)(ar.result);
if (ar.exception != null) {
throw new RuntimeException("load failed", ar.exception);
}
adns = new ArrayList<AdnRecord>(datas.size());
result = adns;
pendingExtLoads = 0;
for(int i = 0, s = datas.size() ; i < s ; i++) {
adn = new AdnRecord(ef, 1 + i, datas.get(i));
adns.add(adn);
if (adn.hasExtendedRecord()) {
// If we have a valid value in the ext record field,
// we're not done yet: we need to read the corresponding
// ext record and append it
pendingExtLoads++;
phone.mIccFileHandler.loadEFLinearFixed(
extensionEF, adn.extRecord,
obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn));
}
}
break;
}
} catch (RuntimeException exc) {
if (userResponse != null) {
AsyncResult.forMessage(userResponse)
.exception = exc;
userResponse.sendToTarget();
// Loading is all or nothing--either every load succeeds
// or we fail the whole thing.
userResponse = null;
}
return;
}
if (userResponse != null && pendingExtLoads == 0) {
AsyncResult.forMessage(userResponse).result
= result;
userResponse.sendToTarget();
userResponse = null;
}
}
}

View File

@@ -0,0 +1,580 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.content.Context;
import android.os.RegistrantList;
import android.os.Registrant;
import android.os.Handler;
import android.os.AsyncResult;
import android.provider.Checkin;
import android.util.Config;
import android.util.Log;
/**
* {@hide}
*/
public abstract class BaseCommands implements CommandsInterface {
static final String LOG_TAG = "RILB";
//***** Instance Variables
protected Context mContext;
protected RadioState mState = RadioState.RADIO_UNAVAILABLE;
protected Object mStateMonitor = new Object();
protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
protected RegistrantList mOnRegistrants = new RegistrantList();
protected RegistrantList mAvailRegistrants = new RegistrantList();
protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList();
protected RegistrantList mNotAvailRegistrants = new RegistrantList();
protected RegistrantList mSIMReadyRegistrants = new RegistrantList();
protected RegistrantList mSIMLockedRegistrants = new RegistrantList();
protected RegistrantList mRUIMReadyRegistrants = new RegistrantList();
protected RegistrantList mRUIMLockedRegistrants = new RegistrantList();
protected RegistrantList mNVReadyRegistrants = new RegistrantList();
protected RegistrantList mCallStateRegistrants = new RegistrantList();
protected RegistrantList mNetworkStateRegistrants = new RegistrantList();
protected RegistrantList mDataConnectionRegistrants = new RegistrantList();
protected RegistrantList mRadioTechnologyChangedRegistrants = new RegistrantList();
protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
protected Registrant mSMSRegistrant;
protected Registrant mNITZTimeRegistrant;
protected Registrant mSignalStrengthRegistrant;
protected Registrant mUSSDRegistrant;
protected Registrant mSmsOnSimRegistrant;
/** Registrant for handling SMS Status Reports */
protected Registrant mSmsStatusRegistrant;
/** Registrant for handling Supplementary Service Notifications */
protected Registrant mSsnRegistrant;
protected Registrant mStkSessionEndRegistrant;
protected Registrant mStkProCmdRegistrant;
protected Registrant mStkEventRegistrant;
protected Registrant mStkCallSetUpRegistrant;
/** Registrant for handling SIM/RUIM SMS storage full messages */
protected Registrant mIccSmsFullRegistrant;
/** Registrant for handling Icc Refresh notifications */
protected Registrant mIccRefreshRegistrant;
/** Registrant for handling RING notifications */
protected Registrant mRingRegistrant;
/** Registrant for handling RESTRICTED STATE changed notification */
protected Registrant mRestrictedStateRegistrant;
//Network Mode received from PhoneFactory
protected int mNetworkMode;
//CDMA subscription received from PhoneFactory
protected int mCdmaSubscription;
//Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
protected int mPhoneType;
public BaseCommands(Context context) {
mContext = context; // May be null (if so we won't log statistics)
}
//***** CommandsInterface implementation
public RadioState getRadioState() {
return mState;
}
public void registerForRadioStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mRadioStateChangedRegistrants.add(r);
r.notifyRegistrant();
}
}
public void unregisterForRadioStateChanged(Handler h) {
synchronized (mStateMonitor) {
mRadioStateChangedRegistrants.remove(h);
}
}
public void registerForOn(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mOnRegistrants.add(r);
if (mState.isOn()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForOn(Handler h) {
synchronized (mStateMonitor) {
mOnRegistrants.remove(h);
}
}
public void registerForAvailable(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mAvailRegistrants.add(r);
if (mState.isAvailable()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForAvailable(Handler h) {
synchronized(mStateMonitor) {
mAvailRegistrants.remove(h);
}
}
public void registerForNotAvailable(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mNotAvailRegistrants.add(r);
if (!mState.isAvailable()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForNotAvailable(Handler h) {
synchronized (mStateMonitor) {
mNotAvailRegistrants.remove(h);
}
}
public void registerForOffOrNotAvailable(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mOffOrNotAvailRegistrants.add(r);
if (mState == RadioState.RADIO_OFF || !mState.isAvailable()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForOffOrNotAvailable(Handler h) {
synchronized(mStateMonitor) {
mOffOrNotAvailRegistrants.remove(h);
}
}
/** Any transition into SIM_READY */
public void registerForSIMReady(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mSIMReadyRegistrants.add(r);
if (mState.isSIMReady()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForSIMReady(Handler h) {
synchronized (mStateMonitor) {
mSIMReadyRegistrants.remove(h);
}
}
/** Any transition into RUIM_READY */
public void registerForRUIMReady(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mRUIMReadyRegistrants.add(r);
if (mState.isRUIMReady()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForRUIMReady(Handler h) {
synchronized(mStateMonitor) {
mRUIMReadyRegistrants.remove(h);
}
}
/** Any transition into NV_READY */
public void registerForNVReady(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mNVReadyRegistrants.add(r);
if (mState.isNVReady()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForNVReady(Handler h) {
synchronized (mStateMonitor) {
mNVReadyRegistrants.remove(h);
}
}
public void registerForSIMLockedOrAbsent(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mSIMLockedRegistrants.add(r);
if (mState == RadioState.SIM_LOCKED_OR_ABSENT) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForSIMLockedOrAbsent(Handler h) {
synchronized (mStateMonitor) {
mSIMLockedRegistrants.remove(h);
}
}
public void registerForRUIMLockedOrAbsent(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
synchronized (mStateMonitor) {
mRUIMLockedRegistrants.add(r);
if (mState == RadioState.RUIM_LOCKED_OR_ABSENT) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
}
public void unregisterForRUIMLockedOrAbsent(Handler h) {
synchronized (mStateMonitor) {
mRUIMLockedRegistrants.remove(h);
}
}
public void registerForCallStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mCallStateRegistrants.add(r);
}
public void unregisterForCallStateChanged(Handler h) {
mCallStateRegistrants.remove(h);
}
public void registerForNetworkStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mNetworkStateRegistrants.add(r);
}
public void unregisterForNetworkStateChanged(Handler h) {
mNetworkStateRegistrants.remove(h);
}
public void registerForDataStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mDataConnectionRegistrants.add(r);
}
public void unregisterForDataStateChanged(Handler h) {
mDataConnectionRegistrants.remove(h);
}
public void registerForRadioTechnologyChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mRadioTechnologyChangedRegistrants.add(r);
}
public void unregisterForRadioTechnologyChanged(Handler h) {
mRadioTechnologyChangedRegistrants.remove(h);
}
public void registerForIccStatusChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mIccStatusChangedRegistrants.add(r);
}
public void unregisterForIccStatusChanged(Handler h) {
mIccStatusChangedRegistrants.remove(h);
}
public void setOnNewSMS(Handler h, int what, Object obj) {
mSMSRegistrant = new Registrant (h, what, obj);
}
public void unSetOnNewSMS(Handler h) {
mSMSRegistrant.clear();
}
public void setOnSmsOnSim(Handler h, int what, Object obj) {
mSmsOnSimRegistrant = new Registrant (h, what, obj);
}
public void unSetOnSmsOnSim(Handler h) {
mSmsOnSimRegistrant.clear();
}
public void setOnSmsStatus(Handler h, int what, Object obj) {
mSmsStatusRegistrant = new Registrant (h, what, obj);
}
public void unSetOnSmsStatus(Handler h) {
mSmsStatusRegistrant.clear();
}
public void setOnSignalStrengthUpdate(Handler h, int what, Object obj) {
mSignalStrengthRegistrant = new Registrant (h, what, obj);
}
public void unSetOnSignalStrengthUpdate(Handler h) {
mSignalStrengthRegistrant.clear();
}
public void setOnNITZTime(Handler h, int what, Object obj) {
mNITZTimeRegistrant = new Registrant (h, what, obj);
}
public void unSetOnNITZTime(Handler h) {
mNITZTimeRegistrant.clear();
}
public void setOnUSSD(Handler h, int what, Object obj) {
mUSSDRegistrant = new Registrant (h, what, obj);
}
public void unSetOnUSSD(Handler h) {
mUSSDRegistrant.clear();
}
public void setOnSuppServiceNotification(Handler h, int what, Object obj) {
mSsnRegistrant = new Registrant (h, what, obj);
}
public void unSetOnSuppServiceNotification(Handler h) {
mSsnRegistrant.clear();
}
public void setOnStkSessionEnd(Handler h, int what, Object obj) {
mStkSessionEndRegistrant = new Registrant (h, what, obj);
}
public void unSetOnStkSessionEnd(Handler h) {
mStkSessionEndRegistrant.clear();
}
public void setOnStkProactiveCmd(Handler h, int what, Object obj) {
mStkProCmdRegistrant = new Registrant (h, what, obj);
}
public void unSetOnStkProactiveCmd(Handler h) {
mStkProCmdRegistrant.clear();
}
public void setOnStkEvent(Handler h, int what, Object obj) {
mStkEventRegistrant = new Registrant (h, what, obj);
}
public void unSetOnStkEvent(Handler h) {
mStkEventRegistrant.clear();
}
public void setOnStkCallSetUp(Handler h, int what, Object obj) {
mStkCallSetUpRegistrant = new Registrant (h, what, obj);
}
public void unSetOnStkCallSetUp(Handler h) {
mStkCallSetUpRegistrant.clear();
}
public void setOnIccSmsFull(Handler h, int what, Object obj) {
mIccSmsFullRegistrant = new Registrant (h, what, obj);
}
public void unSetOnIccSmsFull(Handler h) {
mIccSmsFullRegistrant.clear();
}
public void setOnIccRefresh(Handler h, int what, Object obj) {
mIccRefreshRegistrant = new Registrant (h, what, obj);
}
public void unSetOnIccRefresh(Handler h) {
mIccRefreshRegistrant.clear();
}
public void setOnCallRing(Handler h, int what, Object obj) {
mRingRegistrant = new Registrant (h, what, obj);
}
public void unSetOnCallRing(Handler h) {
mRingRegistrant.clear();
}
public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mVoicePrivacyOnRegistrants.add(r);
}
public void unregisterForInCallVoicePrivacyOn(Handler h){
mVoicePrivacyOnRegistrants.remove(h);
}
public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mVoicePrivacyOffRegistrants.add(r);
}
public void unregisterForInCallVoicePrivacyOff(Handler h){
mVoicePrivacyOffRegistrants.remove(h);
}
public void setOnRestrictedStateChanged(Handler h, int what, Object obj) {
mRestrictedStateRegistrant = new Registrant (h, what, obj);
}
public void unSetOnRestrictedStateChanged(Handler h) {
mRestrictedStateRegistrant.clear();
}
//***** Protected Methods
/**
* Store new RadioState and send notification based on the changes
*
* This function is called only by RIL.java when receiving unsolicited
* RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
*
* RadioState has 5 values : RADIO_OFF, RADIO_UNAVAILABLE, SIM_NOT_READY,
* SIM_LOCKED_OR_ABSENT, and SIM_READY.
*
* @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
*/
protected void setRadioState(RadioState newState) {
RadioState oldState;
synchronized (mStateMonitor) {
if (Config.LOGV) {
Log.v(LOG_TAG, "setRadioState old: " + mState
+ " new " + newState);
}
oldState = mState;
mState = newState;
if (oldState == mState) {
// no state transition
return;
}
if (mContext != null &&
newState == RadioState.RADIO_UNAVAILABLE &&
oldState != RadioState.RADIO_OFF) {
Checkin.updateStats(mContext.getContentResolver(),
Checkin.Stats.Tag.PHONE_RADIO_RESETS, 1, 0.0);
}
mRadioStateChangedRegistrants.notifyRegistrants();
if (mState.isAvailable() && !oldState.isAvailable()) {
Log.d(LOG_TAG,"Notifying: radio available");
mAvailRegistrants.notifyRegistrants();
onRadioAvailable();
}
if (!mState.isAvailable() && oldState.isAvailable()) {
Log.d(LOG_TAG,"Notifying: radio not available");
mNotAvailRegistrants.notifyRegistrants();
}
if (mState.isSIMReady() && !oldState.isSIMReady()) {
Log.d(LOG_TAG,"Notifying: SIM ready");
mSIMReadyRegistrants.notifyRegistrants();
}
if (mState == RadioState.SIM_LOCKED_OR_ABSENT) {
Log.d(LOG_TAG,"Notifying: SIM locked or absent");
mSIMLockedRegistrants.notifyRegistrants();
}
if (mState.isRUIMReady() && !oldState.isRUIMReady()) {
Log.d(LOG_TAG,"Notifying: RUIM ready");
mRUIMReadyRegistrants.notifyRegistrants();
}
if (mState == RadioState.RUIM_LOCKED_OR_ABSENT) {
Log.d(LOG_TAG,"Notifying: RUIM locked or absent");
mRUIMLockedRegistrants.notifyRegistrants();
}
if (mState.isNVReady() && !oldState.isNVReady()) {
Log.d(LOG_TAG,"Notifying: NV ready");
mNVReadyRegistrants.notifyRegistrants();
}
if (mState.isOn() && !oldState.isOn()) {
Log.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");
mOffOrNotAvailRegistrants.notifyRegistrants();
}
/* Radio Technology Change events
* NOTE: isGsm and isCdma have no common states in RADIO_OFF or RADIO_UNAVAILABLE; the
* current phone is determined by mPhoneType
* NOTE: at startup no phone have been created and the RIL determines the mPhoneType
* looking based on the networkMode set by the PhoneFactory in the constructor
*/
if (mState.isGsm() && oldState.isCdma()) {
Log.d(LOG_TAG,"Notifying: radio technology change CDMA to GSM");
mRadioTechnologyChangedRegistrants.notifyRegistrants();
}
if (mState.isGsm() && !oldState.isOn() && (mPhoneType == RILConstants.CDMA_PHONE)) {
Log.d(LOG_TAG,"Notifying: radio technology change CDMA OFF to GSM");
mRadioTechnologyChangedRegistrants.notifyRegistrants();
}
if (mState.isCdma() && oldState.isGsm()) {
Log.d(LOG_TAG,"Notifying: radio technology change GSM to CDMA");
mRadioTechnologyChangedRegistrants.notifyRegistrants();
}
if (mState.isCdma() && !oldState.isOn() && (mPhoneType == RILConstants.GSM_PHONE)) {
Log.d(LOG_TAG,"Notifying: radio technology change GSM OFF to CDMA");
mRadioTechnologyChangedRegistrants.notifyRegistrants();
}
}
}
protected void onRadioAvailable() {
}
}

View File

@@ -17,6 +17,7 @@
package com.android.internal.telephony;
import java.util.List;
/**
* {@hide}
*/
@@ -39,6 +40,13 @@ public abstract class Call {
}
}
/* Instance Variables */
public State state = State.IDLE;
/* Instance Methods */
/** Do not modify the List result!!! This list is not yours to keep
@@ -46,36 +54,46 @@ public abstract class Call {
*/
public abstract List<Connection> getConnections();
public abstract State getState();
public abstract Phone getPhone();
public abstract boolean isMultiparty();
public abstract void hangup() throws CallStateException;
/**
* hasConnection
*
*
* @param c a Connection object
* @return true if the call contains the connection object passed in
*/
public boolean hasConnection(Connection c) {
return c.getCall() == this;
}
/**
* hasConnections
* @return true if the call contains one or more connections
*/
public boolean hasConnections() {
List connections = getConnections();
if (connections == null) {
return false;
}
return connections.size() > 0;
}
/**
* getState
* @return state of class call
*/
public State getState() {
return state;
}
/**
* isIdle
*
*
* FIXME rename
* @return true if the call contains only disconnected connections (if any)
*/
@@ -93,27 +111,27 @@ public abstract class Call {
long time = Long.MAX_VALUE;
Connection c;
Connection earliest = null;
l = getConnections();
if (l.size() == 0) {
return null;
}
for (int i = 0, s = l.size() ; i < s ; i++) {
c = (Connection) l.get(i);
long t;
t = c.getCreateTime();
if (t < time) {
earliest = c;
}
}
return earliest;
}
public long
getEarliestCreateTime() {
List l;
@@ -160,9 +178,6 @@ public abstract class Call {
return time;
}
public abstract boolean isMultiparty();
public abstract void hangup() throws CallStateException;
public boolean
isDialingOrAlerting() {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import android.telephony.PhoneNumberUtils;
@@ -23,8 +23,7 @@ import android.telephony.PhoneNumberUtils;
*
* {@hide}
*/
public class CallForwardInfo
{
public class CallForwardInfo {
public int status; /*1 = active, 0 = not active */
public int reason; /* from TS 27.007 7.11 "reason" */
public int serviceClass; /* Sum of CommandsInterface.SERVICE_CLASS */
@@ -32,8 +31,7 @@ public class CallForwardInfo
public String number; /* "number" from TS 27.007 7.11 */
public int timeSeconds; /* for CF no reply only */
public String toString()
{
public String toString() {
return super.toString() + (status == 0 ? " not active " : " active ")
+ " reason: " + reason
+ " serviceClass: " + serviceClass

View File

@@ -0,0 +1,123 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.android.internal.telephony.CommandException;
/**
* {@hide}
*/
public abstract class CallTracker extends Handler {
private static final boolean DBG_POLL = false;
//***** Constants
static final int POLL_DELAY_MSEC = 250;
protected int pendingOperations;
protected boolean needsPoll;
protected Message lastRelevantPoll;
public CommandsInterface cm;
//***** Events
protected static final int EVENT_POLL_CALLS_RESULT = 1;
protected static final int EVENT_CALL_STATE_CHANGE = 2;
protected static final int EVENT_REPOLL_AFTER_DELAY = 3;
protected static final int EVENT_OPERATION_COMPLETE = 4;
protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5;
protected static final int EVENT_SWITCH_RESULT = 8;
protected static final int EVENT_RADIO_AVAILABLE = 9;
protected static final int EVENT_RADIO_NOT_AVAILABLE = 10;
protected static final int EVENT_CONFERENCE_RESULT = 11;
protected static final int EVENT_SEPARATE_RESULT = 12;
protected static final int EVENT_ECT_RESULT = 13;
protected void pollCallsWhenSafe() {
needsPoll = true;
if (checkNoOperationsPending()) {
lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
cm.getCurrentCalls(lastRelevantPoll);
}
}
protected void
pollCallsAfterDelay() {
Message msg = obtainMessage();
msg.what = EVENT_REPOLL_AFTER_DELAY;
sendMessageDelayed(msg, POLL_DELAY_MSEC);
}
protected boolean
isCommandExceptionRadioNotAvailable(Throwable e) {
return e != null && e instanceof CommandException
&& ((CommandException)e).getCommandError()
== CommandException.Error.RADIO_NOT_AVAILABLE;
}
protected abstract void handlePollCalls(AsyncResult ar);
protected void handleRadioAvailable() {
pollCallsWhenSafe();
}
/**
* Obtain a complete message that indicates that this operation
* does not require polling of getCurrentCalls(). However, if other
* operations that do need getCurrentCalls() are pending or are
* scheduled while this operation is pending, the invocation
* of getCurrentCalls() will be postponed until this
* operation is also complete.
*/
protected Message
obtainNoPollCompleteMessage(int what) {
pendingOperations++;
lastRelevantPoll = null;
return obtainMessage(what);
}
/**
* @return true if we're idle or there's a call to getCurrentCalls() pending
* but nothing else
*/
private boolean
checkNoOperationsPending() {
if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" +
pendingOperations);
return pendingOperations == 0;
}
//***** Overridden from Handler
public abstract void handleMessage (Message msg);
protected abstract void log(String msg);
}

View File

@@ -37,7 +37,7 @@ import android.util.Log;
public class CallerInfoAsyncQuery {
private static final boolean DBG = false;
private static final String LOG_TAG = "CallerInfoAsyncQuery";
private static final String LOG_TAG = "PHONE";
private static final int EVENT_NEW_QUERY = 1;
private static final int EVENT_ADD_LISTENER = 2;

View File

@@ -14,15 +14,16 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import com.android.internal.telephony.RILConstants;
import android.util.Log;
/**
* {@hide}
*/
public class CommandException extends RuntimeException
{
public class CommandException extends RuntimeException {
private Error e;
public enum Error {
@@ -38,30 +39,28 @@ public class CommandException extends RuntimeException
SMS_FAIL_RETRY,
}
public CommandException(Error e)
{
public CommandException(Error e) {
super(e.toString());
this.e = e;
}
public static CommandException
fromRilErrno(int ril_errno)
{
fromRilErrno(int ril_errno) {
switch(ril_errno) {
case RILConstants.SUCCESS: return null;
case RILConstants.RIL_ERRNO_INVALID_RESPONSE:
case RILConstants.RIL_ERRNO_INVALID_RESPONSE:
return new CommandException(Error.INVALID_RESPONSE);
case RILConstants.RADIO_NOT_AVAILABLE:
case RILConstants.RADIO_NOT_AVAILABLE:
return new CommandException(Error.RADIO_NOT_AVAILABLE);
case RILConstants.GENERIC_FAILURE:
case RILConstants.GENERIC_FAILURE:
return new CommandException(Error.GENERIC_FAILURE);
case RILConstants.PASSWORD_INCORRECT:
case RILConstants.PASSWORD_INCORRECT:
return new CommandException(Error.PASSWORD_INCORRECT);
case RILConstants.SIM_PIN2:
case RILConstants.SIM_PIN2:
return new CommandException(Error.SIM_PIN2);
case RILConstants.SIM_PUK2:
case RILConstants.SIM_PUK2:
return new CommandException(Error.SIM_PUK2);
case RILConstants.REQUEST_NOT_SUPPORTED:
case RILConstants.REQUEST_NOT_SUPPORTED:
return new CommandException(Error.REQUEST_NOT_SUPPORTED);
case RILConstants.OP_NOT_ALLOWED_DURING_VOICE_CALL:
return new CommandException(Error.OP_NOT_ALLOWED_DURING_VOICE_CALL);
@@ -75,8 +74,7 @@ public class CommandException extends RuntimeException
}
}
public Error getCommandError()
{
public Error getCommandError() {
return e;
}

View File

@@ -14,50 +14,79 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
import com.android.internal.telephony.*;
package com.android.internal.telephony;
import android.os.Message;
import android.os.Handler;
/**
* {@hide}
*/
public interface CommandsInterface
{
public interface CommandsInterface {
enum RadioState {
RADIO_OFF, /* Radio explictly powered off (eg CFUN=0) */
RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
SIM_NOT_READY, /* Radio is on, but the SIM interface is not ready */
SIM_LOCKED_OR_ABSENT, /* SIM PIN locked, PUK required, network
SIM_LOCKED_OR_ABSENT, /* SIM PIN locked, PUK required, network
personalization, or SIM absent */
SIM_READY; /* Radio is on and SIM interface is available */
SIM_READY, /* Radio is on and SIM interface is available */
RUIM_NOT_READY, /* Radio is on, but the RUIM interface is not ready */
RUIM_READY, /* Radio is on and the RUIM interface is available */
RUIM_LOCKED_OR_ABSENT, /* RUIM PIN locked, PUK required, network
personalization locked, or RUIM absent */
NV_NOT_READY, /* Radio is on, but the NV interface is not available */
NV_READY; /* Radio is on and the NV interface is available */
boolean isOn() /* and available...*/
{
public boolean isOn() /* and available...*/ {
return this == SIM_NOT_READY
|| this == SIM_LOCKED_OR_ABSENT
|| this == SIM_READY
|| this == RUIM_NOT_READY
|| this == RUIM_READY
|| this == RUIM_LOCKED_OR_ABSENT
|| this == NV_NOT_READY
|| this == NV_READY;
}
public boolean isAvailable() {
return this != RADIO_UNAVAILABLE;
}
public boolean isSIMReady() {
return this == SIM_READY;
}
public boolean isRUIMReady() {
return this == RUIM_READY;
}
public boolean isNVReady() {
return this == NV_READY;
}
public boolean isGsm() {
return this == SIM_NOT_READY
|| this == SIM_LOCKED_OR_ABSENT
|| this == SIM_READY;
}
boolean isAvailable()
{
return this != RADIO_UNAVAILABLE;
}
boolean isSIMReady()
{
// if you add new states after SIM_READY, include them too
return this == SIM_READY;
public boolean isCdma() {
return this == RUIM_NOT_READY
|| this == RUIM_READY
|| this == RUIM_LOCKED_OR_ABSENT
|| this == NV_NOT_READY
|| this == NV_READY;
}
}
enum SimStatus {
SIM_ABSENT,
SIM_NOT_READY,
SIM_READY,
SIM_PIN,
SIM_PUK,
SIM_NETWORK_PERSONALIZATION
enum IccStatus {
ICC_ABSENT,
ICC_NOT_READY,
ICC_READY,
ICC_PIN,
ICC_PUK,
ICC_NETWORK_PERSONALIZATION
}
//***** Constants
@@ -93,7 +122,7 @@ public interface CommandsInterface
static final String CB_FACILITY_BA_MT = "AC";
static final String CB_FACILITY_BA_SIM = "SC";
static final String CB_FACILITY_BA_FD = "FD";
// Used for various supp services apis
// See 27.007 +CCFC or +CLCK
@@ -102,7 +131,7 @@ public interface CommandsInterface
static final int SERVICE_CLASS_DATA = (1 << 1); //synoym for 16+32+64+128
static final int SERVICE_CLASS_FAX = (1 << 2);
static final int SERVICE_CLASS_SMS = (1 << 3);
static final int SERVICE_CLASS_DATA_SYNC = (1 << 4);
static final int SERVICE_CLASS_DATA_SYNC = (1 << 4);
static final int SERVICE_CLASS_DATA_ASYNC = (1 << 5);
static final int SERVICE_CLASS_PACKET = (1 << 6);
static final int SERVICE_CLASS_PAD = (1 << 7);
@@ -122,8 +151,8 @@ public interface CommandsInterface
RadioState getRadioState();
/**
* Fires on any RadioState transition
/**
* Fires on any RadioState transition
* Always fires immediately as well
*
* do not attempt to calculate transitions by storing getRadioState() values
@@ -131,58 +160,85 @@ public interface CommandsInterface
* registration methods
*/
void registerForRadioStateChanged(Handler h, int what, Object obj);
void unregisterForRadioStateChanged(Handler h);
/**
* Fires on any transition into RadioState.isOn()
/**
* Fires on any transition into RadioState.isOn()
* Fires immediately if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForOn(Handler h, int what, Object obj);
void unregisterForOn(Handler h);
/**
* Fires on any transition out of RadioState.isAvailable()
/**
* Fires on any transition out of RadioState.isAvailable()
* Fires immediately if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForAvailable(Handler h, int what, Object obj);
//void unregisterForAvailable(Handler h);
/**
void unregisterForAvailable(Handler h);
/**
* Fires on any transition into !RadioState.isAvailable()
* Fires immediately if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForNotAvailable(Handler h, int what, Object obj);
//void unregisterForNotAvailable(Handler h);
/**
void unregisterForNotAvailable(Handler h);
/**
* Fires on any transition into RADIO_OFF or !RadioState.isAvailable()
* Fires immediately if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForOffOrNotAvailable(Handler h, int what, Object obj);
//void unregisterForNotAvailable(Handler h);
void unregisterForOffOrNotAvailable(Handler h);
/**
/**
* Fires on any transition into SIM_READY
* Fires immediately if if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForSIMReady(Handler h, int what, Object obj);
//void unregisterForSIMReady(Handler h);
void unregisterForSIMReady(Handler h);
/** Any transition into SIM_LOCKED_OR_ABSENT */
void registerForSIMLockedOrAbsent(Handler h, int what, Object obj);
//void unregisterForSIMLockedOrAbsent(Handler h);
void unregisterForSIMLockedOrAbsent(Handler h);
void registerForCallStateChanged(Handler h, int what, Object obj);
//void unregisterForCallStateChanged(Handler h);
void unregisterForCallStateChanged(Handler h);
void registerForNetworkStateChanged(Handler h, int what, Object obj);
//void unregisterForNetworkStateChanged(Handler h);
void registerForPDPStateChanged(Handler h, int what, Object obj);
//void unregisterForPDPStateChanged(Handler h);
void unregisterForNetworkStateChanged(Handler h);
void registerForDataStateChanged(Handler h, int what, Object obj);
void unregisterForDataStateChanged(Handler h);
void registerForRadioTechnologyChanged(Handler h, int what, Object obj);
void unregisterForRadioTechnologyChanged(Handler h);
void registerForNVReady(Handler h, int what, Object obj);
void unregisterForNVReady(Handler h);
void registerForRUIMLockedOrAbsent(Handler h, int what, Object obj);
void unregisterForRUIMLockedOrAbsent(Handler h);
/** InCall voice privacy notifications */
void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
void unregisterForInCallVoicePrivacyOn(Handler h);
void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj);
void unregisterForInCallVoicePrivacyOff(Handler h);
/**
* Fires on any transition into RUIM_READY
* Fires immediately if if currently in that state
* In general, actions should be idempotent. State may change
* before event is received.
*/
void registerForRUIMReady(Handler h, int what, Object obj);
void unregisterForRUIMReady(Handler h);
/**
* unlike the register* methods, there's only one new SMS handler
@@ -192,21 +248,24 @@ public interface CommandsInterface
* AsyncResult.result is a String containing the SMS PDU
*/
void setOnNewSMS(Handler h, int what, Object obj);
void unSetOnNewSMS(Handler h);
/**
* Register for NEW_SMS_ON_SIM unsolicited message
* Register for NEW_SMS_ON_SIM unsolicited message
*
* AsyncResult.result is an int array containing the index of new SMS
*/
void setOnSmsOnSim(Handler h, int what, Object obj);
void unSetOnSmsOnSim(Handler h);
/**
* Register for NEW_SMS_STATUS_REPORT unsolicited message
* Register for NEW_SMS_STATUS_REPORT unsolicited message
*
* AsyncResult.result is a String containing the status report PDU
*/
void setOnSmsStatus(Handler h, int what, Object obj);
void unSetOnSmsStatus(Handler h);
/**
* unlike the register* methods, there's only one NITZ time handler
*
@@ -220,13 +279,14 @@ public interface CommandsInterface
* seconds on system startup
*/
void setOnNITZTime(Handler h, int what, Object obj);
void unSetOnNITZTime(Handler h);
/**
* unlike the register* methods, there's only one USSD notify handler
*
* Represents the arrival of a USSD "notify" message, which may
* or may not have been triggered by a previous USSD send
*
*
* AsyncResult.result is a String[]
* ((String[])(AsyncResult.result))[0] contains status code
* "0" USSD-Notify -- text in ((const char **)data)[1]
@@ -241,26 +301,29 @@ public interface CommandsInterface
*/
void setOnUSSD(Handler h, int what, Object obj);
void unSetOnUSSD(Handler h);
/**
* unlike the register* methods, there's only one signal strength handler
* AsyncResult.result is an int[2]
* response.obj.result[0] is received signal strength (0-31, 99)
* response.obj.result[1] is bit error rate (0-7, 99)
* AsyncResult.result is an int[2]
* response.obj.result[0] is received signal strength (0-31, 99)
* response.obj.result[1] is bit error rate (0-7, 99)
* as defined in TS 27.007 8.5
*/
void setOnSignalStrengthUpdate(Handler h, int what, Object obj);
void unSetOnSignalStrengthUpdate(Handler h);
/**
* Sets the handler for SIM SMS storage full unsolicited message.
* Sets the handler for SIM/RUIM SMS storage full unsolicited message.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
void setOnSimSmsFull(Handler h, int what, Object obj);
void setOnIccSmsFull(Handler h, int what, Object obj);
void unSetOnIccSmsFull(Handler h);
/**
* Sets the handler for SIM Refresh notifications.
@@ -270,8 +333,9 @@ public interface CommandsInterface
* @param what User-defined message code.
* @param obj User object.
*/
void setOnSimRefresh(Handler h, int what, Object obj);
void setOnIccRefresh(Handler h, int what, Object obj);
void unSetOnIccRefresh(Handler h);
/**
* Sets the handler for RING notifications.
* Unlike the register* methods, there's only one notification handler
@@ -281,7 +345,8 @@ public interface CommandsInterface
* @param obj User object.
*/
void setOnCallRing(Handler h, int what, Object obj);
void unSetOnCallRing(Handler h);
/**
* Sets the handler for RESTRICTED_STATE changed notification,
* eg, for Domain Specific Access Control
@@ -292,7 +357,8 @@ public interface CommandsInterface
*/
void setOnRestrictedStateChanged(Handler h, int what, Object obj);
void unSetOnRestrictedStateChanged(Handler h);
/**
* Sets the handler for Supplementary Service Notifications.
* Unlike the register* methods, there's only one notification handler
@@ -302,6 +368,7 @@ public interface CommandsInterface
* @param obj User object.
*/
void setOnSuppServiceNotification(Handler h, int what, Object obj);
void unSetOnSuppServiceNotification(Handler h);
/**
* Sets the handler for Session End Notifications for STK.
@@ -312,6 +379,7 @@ public interface CommandsInterface
* @param obj User object.
*/
void setOnStkSessionEnd(Handler h, int what, Object obj);
void unSetOnStkSessionEnd(Handler h);
/**
* Sets the handler for Proactive Commands for STK.
@@ -322,6 +390,7 @@ public interface CommandsInterface
* @param obj User object.
*/
void setOnStkProactiveCmd(Handler h, int what, Object obj);
void unSetOnStkProactiveCmd(Handler h);
/**
* Sets the handler for Event Notifications for STK.
@@ -332,6 +401,7 @@ public interface CommandsInterface
* @param obj User object.
*/
void setOnStkEvent(Handler h, int what, Object obj);
void unSetOnStkEvent(Handler h);
/**
* Sets the handler for Call Set Up Notifications for STK.
@@ -342,6 +412,7 @@ public interface CommandsInterface
* @param obj User object.
*/
void setOnStkCallSetUp(Handler h, int what, Object obj);
void unSetOnStkCallSetUp(Handler h);
/**
* Enables/disbables supplementary service related notifications from
@@ -351,19 +422,21 @@ public interface CommandsInterface
* @param result Message to be posted when command completes.
*/
void setSuppServiceNotifications(boolean enable, Message result);
//void unSetSuppServiceNotifications(Handler h);
/**
* Returns current SIM status.
* Returns current ICC status.
*
* AsyncResult.result is IccStatus
*
* AsyncResult.result is SimStatus
*
*/
void getSimStatus(Message result);
void getIccStatus(Message result);
/**
* Supply the SIM PIN to the SIM card
*
* Supply the ICC PIN to the ICC card
*
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -373,11 +446,11 @@ public interface CommandsInterface
* ar.exception and ar.result are null on success
*/
void supplySimPin(String pin, Message result);
void supplyIccPin(String pin, Message result);
/**
* Supply the SIM PUK to the SIM card
*
* Supply the ICC PUK to the ICC card
*
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -387,13 +460,13 @@ public interface CommandsInterface
* ar.exception and ar.result are null on success
*/
void supplySimPuk(String puk, String newPin, Message result);
void supplyIccPuk(String puk, String newPin, Message result);
/**
* Supply the SIM PIN2 to the SIM card
* Only called following operation where SIM_PIN2 was
* Supply the ICC PIN2 to the ICC card
* Only called following operation where ICC_PIN2 was
* returned as a a failure from a previous operation
*
*
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -403,13 +476,13 @@ public interface CommandsInterface
* ar.exception and ar.result are null on success
*/
void supplySimPin2(String pin2, Message result);
void supplyIccPin2(String pin2, Message result);
/**
* Supply the SIM PUK2 to the SIM card
* Only called following operation where SIM_PUK2 was
* returned as a a failure from a previous operation
*
*
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -419,16 +492,16 @@ public interface CommandsInterface
* ar.exception and ar.result are null on success
*/
void supplySimPuk2(String puk2, String newPin2, Message result);
void supplyIccPuk2(String puk2, String newPin2, Message result);
void changeSimPin(String oldPin, String newPin, Message result);
void changeSimPin2(String oldPin2, String newPin2, Message result);
void changeIccPin(String oldPin, String newPin, Message result);
void changeIccPin2(String oldPin2, String newPin2, Message result);
void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result);
void supplyNetworkDepersonalization(String netpin, Message result);
/**
/**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -438,16 +511,26 @@ public interface CommandsInterface
*/
void getCurrentCalls (Message result);
/**
/**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result contains a List of PDPContextState
* @deprecated
*/
void getPDPContextList(Message result);
/**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result contains a List of PDPContextState
*/
void getPDPContextList(Message result);
void getDataCallList(Message result);
/**
/**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -460,7 +543,7 @@ public interface CommandsInterface
*/
void dial (String address, int clirMode, Message result);
/**
/**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -469,7 +552,7 @@ public interface CommandsInterface
*/
void getIMSI(Message result);
/**
/**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -478,7 +561,7 @@ public interface CommandsInterface
*/
void getIMEI(Message result);
/**
/**
* returned message
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
@@ -487,7 +570,7 @@ public interface CommandsInterface
*/
void getIMEISV(Message result);
/**
/**
* Hang up one individual connection.
* returned message
* retMsg.obj = AsyncResult ar
@@ -512,7 +595,7 @@ public interface CommandsInterface
/**
* 3GPP 22.030 6.5.5
* "Releases all active calls (if any exist) and accepts
* "Releases all active calls (if any exist) and accepts
* the other (held or waiting) call."
*
* ar.exception carries exception on failure
@@ -523,7 +606,7 @@ public interface CommandsInterface
/**
* 3GPP 22.030 6.5.5
* "Places all active calls (if any exist) on hold and accepts
* "Places all active calls (if any exist) on hold and accepts
* the other (held or waiting) call."
*
* ar.exception carries exception on failure
@@ -539,12 +622,27 @@ public interface CommandsInterface
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
*/
*/
void conference (Message result);
/**
* Set preferred Voice Privacy (VP).
*
* @param enable true is enhanced and false is normal VP
* @param result is a callback message
*/
void setPreferredVoicePrivacy(boolean enable, Message result);
/**
* Get currently set preferred Voice Privacy (VP) mode.
*
* @param result is a callback message
*/
void getPreferredVoicePrivacy(Message result);
/**
* 3GPP 22.030 6.5.5
* "Places all active calls on hold except call X with which
* "Places all active calls on hold except call X with which
* communication shall be supported."
*/
void separateConnection (int gsmIndex, Message result);
@@ -554,15 +652,15 @@ public interface CommandsInterface
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
*/
*/
void acceptCall (Message result);
/**
/**
* also known as UDUB
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
*/
*/
void rejectCall (Message result);
/**
@@ -586,14 +684,21 @@ public interface CommandsInterface
void getLastCallFailCause (Message result);
/**
/**
* Reason for last PDP context deactivate or failure to activate
* cause code returned as int[0] in Message.obj.response
* returns an integer cause code defined in TS 24.008
* section 6.1.3.1.3 or close approximation
* @deprecated
*/
void getLastPdpFailCause (Message result);
/**
* The preferred new alternative to getLastPdpFailCause
* that is also CDMA-compatible.
*/
void getLastDataCallFailCause (Message result);
void setMute (boolean enableMute, Message response);
void getMute (Message response);
@@ -601,8 +706,8 @@ public interface CommandsInterface
/**
* response.obj is an AsyncResult
* response.obj.result is an int[2]
* response.obj.result[0] is received signal strength (0-31, 99)
* response.obj.result[1] is bit error rate (0-7, 99)
* response.obj.result[0] is received signal strength (0-31, 99)
* response.obj.result[1] is bit error rate (0-7, 99)
* as defined in TS 27.007 8.5
*/
void getSignalStrength (Message response);
@@ -612,21 +717,21 @@ public interface CommandsInterface
* response.obj.result is an int[3]
* response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
* response.obj.result[1] is LAC if registered or -1 if not
* response.obj.result[2] is CID if registered or -1 if not
* response.obj.result[2] is CID if registered or -1 if not
* valid LAC and CIDs are 0x0000 - 0xffff
*
*
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
void getRegistrationState (Message response);
/**
* response.obj.result is an int[3]
* response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
* response.obj.result[1] is LAC if registered or -1 if not
* response.obj.result[2] is CID if registered or -1 if not
* response.obj.result[2] is CID if registered or -1 if not
* valid LAC and CIDs are 0x0000 - 0xffff
*
*
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
@@ -637,14 +742,14 @@ public interface CommandsInterface
* response.obj.result[0] is long alpha or null if unregistered
* response.obj.result[1] is short alpha or null if unregistered
* response.obj.result[2] is numeric or null if unregistered
*/
*/
void getOperator(Message response);
/**
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
* ar.result is null on success and failure
*/
*/
void sendDtmf(char c, Message result);
@@ -667,26 +772,40 @@ public interface CommandsInterface
* smscPDU is smsc address in PDU form GSM BCD format prefixed
* by a length byte (as expected by TS 27.005) or NULL for default SMSC
* pdu is SMS in PDU format as an ASCII hex string
* less the SMSC address
* less the SMSC address
*/
void sendSMS (String smscPDU, String pdu, Message response);
/**
* @param pdu is CDMA-SMS in internal pseudo-PDU format
* @param response sent when operation completes
*/
void sendCdmaSms(byte[] pdu, Message response);
/**
* Deletes the specified SMS record from SIM memory (EF_SMS).
*
*
* @param index index of the SMS record to delete
* @param response sent when operation completes
*/
void deleteSmsOnSim(int index, Message response);
/**
* Deletes the specified SMS record from RUIM memory (EF_SMS in DF_CDMA).
*
* @param index index of the SMS record to delete
* @param response sent when operation completes
*/
void deleteSmsOnRuim(int index, Message response);
/**
* Writes an SMS message to SIM memory (EF_SMS).
*
*
* @param status status of message on SIM. One of:
* SmsManger.STATUS_ON_SIM_READ
* SmsManger.STATUS_ON_SIM_UNREAD
* SmsManger.STATUS_ON_SIM_SENT
* SmsManger.STATUS_ON_SIM_UNSENT
* SmsManger.STATUS_ON_ICC_READ
* SmsManger.STATUS_ON_ICC_UNREAD
* SmsManger.STATUS_ON_ICC_SENT
* SmsManger.STATUS_ON_ICC_UNSENT
* @param pdu message PDU, as hex string
* @param response sent when operation completes.
* response.obj will be an AsyncResult, and will indicate
@@ -694,89 +813,105 @@ public interface CommandsInterface
*/
void writeSmsToSim(int status, String smsc, String pdu, Message response);
void writeSmsToRuim(int status, String pdu, Message response);
/**
* @deprecated
* @param apn
* @param user
* @param password
* @param response
*/
void setupDefaultPDP(String apn, String user, String password, Message response);
/**
* @deprecated
* @param cid
* @param response
*/
void deactivateDefaultPDP(int cid, Message response);
void setRadioPower(boolean on, Message response);
void acknowledgeLastIncomingSMS(boolean success, Message response);
/**
* parameters equivilient to 27.007 AT+CRSM command
void acknowledgeLastIncomingCdmaSms(boolean success, Message response);
/**
* parameters equivilient to 27.007 AT+CRSM command
* response.obj will be an AsyncResult
* response.obj.userObj will be a SimIoResult on success
* response.obj.userObj will be a IccIoResult on success
*/
void simIO (int command, int fileid, String path, int p1, int p2, int p3,
void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
String data, String pin2, Message response);
/**
* (AsyncResult)response.obj).result is an int[] with element [0] set to
* 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
* 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
*
* @param response is callback message
*/
void queryCLIP(Message response);
/**
* response.obj will be a an int[2]
*
* response.obj[0] will be TS 27.007 +CLIR parameter 'n'
* 0 presentation indicator is used according to the subscription of the CLIR service
* 1 CLIR invocation
* 2 CLIR suppression
* 0 presentation indicator is used according to the subscription of the CLIR service
* 1 CLIR invocation
* 2 CLIR suppression
*
* response.obj[1] will be TS 27.007 +CLIR parameter 'm'
* 0 CLIR not provisioned
* 1 CLIR provisioned in permanent mode
* 2 unknown (e.g. no network, etc.)
* 3 CLIR temporary mode presentation restricted
* 4 CLIR temporary mode presentation allowed
* 0 CLIR not provisioned
* 1 CLIR provisioned in permanent mode
* 2 unknown (e.g. no network, etc.)
* 3 CLIR temporary mode presentation restricted
* 4 CLIR temporary mode presentation allowed
*/
void getCLIR(Message response);
/**
* clirMode is one of the CLIR_* constants above
*
* response.obj is null
*/
void setCLIR(int clirMode, Message response);
/**
* (AsyncResult)response.obj).result is an int[] with element [0] set to
* 0 for disabled, 1 for enabled.
* 0 for disabled, 1 for enabled.
*
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
void queryCallWaiting(int serviceClass, Message response);
/**
* @param enable is true to enable, false to disable
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
void setCallWaiting(boolean enable, int serviceClass, Message response);
/**
* @param action is one of CF_ACTION_*
* @param cfReason is one of CF_REASON_*
* @param serviceClass is a sum of SERVICE_CLASSS_*
* @param serviceClass is a sum of SERVICE_CLASSS_*
*/
void setCallForward(int action, int cfReason, int serviceClass,
String number, int timeSeconds, Message response);
void setCallForward(int action, int cfReason, int serviceClass,
String number, int timeSeconds, Message response);
/**
* cfReason is one of CF_REASON_*
*
* ((AsyncResult)response.obj).result will be an array of
* CallForwardInfo's
*
*
* An array of length 0 means "disabled for all codes"
*/
void queryCallForwardStatus(int cfReason, int serviceClass,
@@ -815,7 +950,7 @@ public interface CommandsInterface
* @param serviceClass is a sum of SERVICE_CLASS_*
* @param response is callback message
*/
void queryFacilityLock (String facility, String password, int serviceClass,
Message response);
@@ -828,7 +963,7 @@ public interface CommandsInterface
*/
void setFacilityLock (String facility, boolean lockState, String password,
int serviceClass, Message response);
void sendUSSD (String ussdString, Message response);
@@ -850,7 +985,7 @@ public interface CommandsInterface
/**
* Query the list of band mode supported by RF.
*
*
* @param response is callback message
* ((AsyncResult)response.obj).result is an int[] with every
* element representing one avialable BM_*_BAND
@@ -923,4 +1058,136 @@ public interface CommandsInterface
* @param response Callback message
*/
public void handleCallSetupRequestFromSim(boolean accept, Message response);
//***** new Methods for CDMA support
/**
* Request the device ESN / MEID / IMEI / IMEISV.
* "response" is const char **
* [0] is IMEI if GSM subscription is available
* [1] is IMEISV if GSM subscription is available
* [2] is ESN if CDMA subscription is available
* [3] is MEID if CDMA subscription is available
*/
public void getDeviceIdentity(Message response);
/**
* Request the device IMSI_M / MDN / AH_SID / H_SID / H_NID.
* "response" is const char **
* [0] is IMSI_M if CDMA subscription is available
* [1] is MDN if CDMA subscription is available
* [2] is AH_SID (Analog Home SID) if CDMA subscription
* [3] is H_SID (Home SID) if CDMA subscription is available
* [4] is H_NID (Home SID) if CDMA subscription is available
*/
public void getCDMASubscription(Message response);
/**
* Send Flash Code.
* "response" is is NULL
* [0] is a FLASH string
*/
public void sendCDMAFeatureCode(String FeatureCode, Message response);
/** Set the Phone type created */
void setPhoneType(int phoneType);
/**
* Query the CDMA roaming preference setting
*
* @param response is callback message to report one of CDMA_RM_*
*/
void queryCdmaRoamingPreference(Message response);
/**
* Requests to set the CDMA roaming preference
* @param cdmaRoamingType one of CDMA_RM_*
* @param response is callback message
*/
void setCdmaRoamingPreference(int cdmaRoamingType, Message response);
/**
* Requests to set the CDMA subscription mode
* @param cdmaSubscriptionType one of CDMA_SUBSCRIPTION_*
* @param response is callback message
*/
void setCdmaSubscription(int cdmaSubscriptionType, Message response);
/**
* Set the TTY mode for the CDMA phone
*
* @param enable is true to enable, false to disable
* @param response is callback message
*/
void setTTYModeEnabled(boolean enable, Message response);
/**
* Query the TTY mode for the CDMA phone
* (AsyncResult)response.obj).result is an int[] with element [0] set to
* 0 for disabled, 1 for enabled.
*
* @param response is callback message
*/
void queryTTYModeEnabled(Message response);
/**
* Setup a packet data connection On successful completion, the result
* message will return the following: [0] indicating PDP CID, which is
* generated by RIL. This Connection ID is used in both GSM/UMTS and CDMA
* modes [1] indicating the network interface name for GSM/UMTS or CDMA [2]
* indicating the IP address for this interface for GSM/UMTS and NULL in the
* case of CDMA
*
* @param radioTechnology
* indicates whether to setup connection on radio technology CDMA
* (0) or GSM/UMTS (1)
* @param profile
* Profile Number or NULL to indicate default profile
* @param apn
* the APN to connect to if radio technology is GSM/UMTS.
* Otherwise null for CDMA.
* @param user
* the username for APN, or NULL
* @param password
* the password for APN, or NULL
* @param result
* Callback message
*/
public void setupDataCall(String radioTechnology, String profile, String apn,
String user, String password, Message result);
/**
* Deactivate packet data connection
*
* @param cid
* The connection ID
* @param result
* Callback message is empty on completion
*/
public void deactivateDataCall(int cid, Message result);
/**
* Activate or deactivate cell broadcast SMS.
*
* @param activate
* 0 = activate, 1 = deactivate
* @param result
* Callback message is empty on completion
*/
public void activateCdmaBroadcastSms(int activate, Message result);
/**
* Configure cdma cell broadcast SMS.
*
* @param result
* Callback message is empty on completion
*/
public void setCdmaBroadcastConfig(int[] configValuesArray, Message result);
/**
* Query the current configuration of cdma cell broadcast SMS.
*
* @param result
* Callback message contains the configuration from the modem on completion
*/
public void getCdmaBroadcastConfig(Message result);
}

View File

@@ -19,8 +19,8 @@ package com.android.internal.telephony;
/**
* {@hide}
*/
public abstract class Connection
{
public abstract class Connection {
// Number presentation type for caller id display
public static int PRESENTATION_ALLOWED = 1; // normal
public static int PRESENTATION_RESTRICTED = 2; // block by user
@@ -42,7 +42,7 @@ public abstract class Connection
INCOMING_REJECTED, /* an incoming call that was rejected */
POWER_OFF, /* radio is turned off explicitly */
OUT_OF_SERVICE, /* out of service */
SIM_ERROR, /* No SIM, SIM locked, or other SIM error */
ICC_ERROR, /* No ICC, ICC locked, or other ICC error */
CALL_BARRED, /* call was blocked by call barrring */
FDN_BLOCKED, /* call was blocked by fixed dial number */
CS_RESTRICTED, /* call was blocked by restricted all voice access */
@@ -54,7 +54,7 @@ public abstract class Connection
/* Instance Methods */
/**
/**
* Gets address (e.g., phone number) associated with connection
* TODO: distinguish reasons for unavailablity
*
@@ -92,7 +92,7 @@ public abstract class Connection
public abstract long getDisconnectTime();
/**
* returns the number of milliseconds the call has been connected,
* returns the number of milliseconds the call has been connected,
* or 0 if the call has never connected.
* If the call is still connected, then returns the elapsed
* time since connect
@@ -113,8 +113,8 @@ public abstract class Connection
public abstract DisconnectCause getDisconnectCause();
/**
* Returns true of this connection originated elsewhere
* ("MT" or mobile terminated; another party called this terminal)
* Returns true of this connection originated elsewhere
* ("MT" or mobile terminated; another party called this terminal)
* or false if this call originated here (MO or mobile originated)
*/
public abstract boolean isIncoming();
@@ -122,32 +122,30 @@ public abstract class Connection
/**
* If this Connection is connected, then it is associated with
* a Call.
*
*
* Returns getCall().getState() or Call.State.IDLE if not
* connected
*/
public Call.State getState()
{
public Call.State getState() {
Call c;
c = getCall();
if (c == null) {
if (c == null) {
return Call.State.IDLE;
} else {
return c.getState();
}
}
/**
* isAlive()
*
*
* @return true if the connection isn't disconnected
* (could be active, holding, ringing, dialing, etc)
*/
public boolean
isAlive()
{
isAlive() {
return getState().isAlive();
}
@@ -155,29 +153,26 @@ public abstract class Connection
* Returns true if Connection is connected and is INCOMING or WAITING
*/
public boolean
isRinging()
{
isRinging() {
return getState().isRinging();
}
/**
*
*
* @return the userdata set in setUserData()
*/
public Object getUserData()
{
public Object getUserData() {
return userData;
}
/**
*
*
* @param userdata user can store an any userdata in the Connection object.
*/
public void setUserData(Object userdata)
{
public void setUserData(Object userdata) {
this.userData = userdata;
}
/**
* Hangup individual Connection
*/
@@ -191,16 +186,16 @@ public abstract class Connection
public abstract void separate() throws CallStateException;
public enum PostDialState {
NOT_STARTED, /* The post dial string playback hasn't
been started, or this call is not yet
NOT_STARTED, /* The post dial string playback hasn't
been started, or this call is not yet
connected, or this is an incoming call */
STARTED, /* The post dial string playback has begun */
WAIT, /* The post dial string playback is waiting for a
WAIT, /* The post dial string playback is waiting for a
call to proceedAfterWaitChar() */
WILD, /* The post dial string playback is waiting for a
WILD, /* The post dial string playback is waiting for a
call to proceedAfterWildChar() */
COMPLETE, /* The post dial string playback is complete */
CANCELLED /* The post dial string playback was cancelled
CANCELLED /* The post dial string playback was cancelled
with cancelPostDial() */
}
@@ -215,7 +210,7 @@ public abstract class Connection
/**
* See Phone.setOnPostDialWaitCharacter()
*/
public abstract void proceedAfterWaitChar();
/**
@@ -232,5 +227,5 @@ public abstract class Connection
* @return one of PRESENTATION_*
*/
public abstract int getNumberPresentation();
}

View File

@@ -0,0 +1,299 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/**
* {@hide}
*/
public abstract class DataConnection extends Handler {
// the inherited class
public enum State {
ACTIVE, /* has active data connection */
ACTIVATING, /* during connecting process */
INACTIVE; /* has empty data connection */
public String toString() {
switch (this) {
case ACTIVE:
return "active";
case ACTIVATING:
return "setting up";
default:
return "inactive";
}
}
public boolean isActive() {
return this == ACTIVE;
}
public boolean isInactive() {
return this == INACTIVE;
}
}
public enum FailCause {
NONE,
BAD_APN,
BAD_PAP_SECRET,
BARRED,
USER_AUTHENTICATION,
SERVICE_OPTION_NOT_SUPPORTED,
SERVICE_OPTION_NOT_SUBSCRIBED,
SIM_LOCKED,
RADIO_OFF,
NO_SIGNAL,
NO_DATA_PLAN,
RADIO_NOT_AVAILABLE,
SUSPENED_TEMPORARY,
RADIO_ERROR_RETRY,
UNKNOWN;
public boolean isPermanentFail() {
return (this == RADIO_OFF);
}
public String toString() {
switch (this) {
case NONE:
return "no error";
case BAD_APN:
return "bad apn";
case BAD_PAP_SECRET:
return "bad pap secret";
case BARRED:
return "barred";
case USER_AUTHENTICATION:
return "error user autentication";
case SERVICE_OPTION_NOT_SUPPORTED:
return "data not supported";
case SERVICE_OPTION_NOT_SUBSCRIBED:
return "datt not subcribed";
case SIM_LOCKED:
return "sim locked";
case RADIO_OFF:
return "radio is off";
case NO_SIGNAL:
return "no signal";
case NO_DATA_PLAN:
return "no data plan";
case RADIO_NOT_AVAILABLE:
return "radio not available";
case SUSPENED_TEMPORARY:
return "suspend temporary";
case RADIO_ERROR_RETRY:
return "transient radio error";
default:
return "unknown data error";
}
}
}
// ***** Event codes
protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = 1;
protected static final int EVENT_GET_LAST_FAIL_DONE = 2;
protected static final int EVENT_LINK_STATE_CHANGED = 3;
protected static final int EVENT_DEACTIVATE_DONE = 4;
protected static final int EVENT_FORCE_RETRY = 5;
//***** Tag IDs for EventLog
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
//***** Member Variables
protected PhoneBase phone;
protected Message onConnectCompleted;
protected Message onDisconnect;
protected int cid;
protected String interfaceName;
protected String ipAddress;
protected String gatewayAddress;
protected String[] dnsServers;
protected State state;
protected long createTime;
protected long lastFailTime;
protected FailCause lastFailCause;
protected static final String NULL_IP = "0.0.0.0";
Object userData;
// receivedDisconnectReq is set when disconnect during activation
protected boolean receivedDisconnectReq;
/* Instance Methods */
protected abstract void onSetupConnectionCompleted(AsyncResult ar);
protected abstract void onDeactivated(AsyncResult ar);
protected abstract void disconnect(Message msg);
protected abstract void notifyFail(FailCause cause, Message onCompleted);
protected abstract void notifyDisconnect(Message msg);
protected abstract void onLinkStateChanged(DataLink.LinkState linkState);
protected abstract FailCause getFailCauseFromRequest(int rilCause);
public abstract String toString();
protected abstract void log(String s);
//***** Constructor
protected DataConnection(PhoneBase phone) {
super();
this.phone = phone;
onConnectCompleted = null;
onDisconnect = null;
this.cid = -1;
receivedDisconnectReq = false;
this.dnsServers = new String[2];
clearSettings();
}
protected void setHttpProxy(String httpProxy, String httpPort) {
if (httpProxy == null || httpProxy.length() == 0) {
phone.setSystemProperty("net.gprs.http-proxy", null);
return;
}
if (httpPort == null || httpPort.length() == 0) {
httpPort = "8080"; // Default to port 8080
}
phone.setSystemProperty("net.gprs.http-proxy",
"http://" + httpProxy + ":" + httpPort + "/");
}
public String getInterface() {
return interfaceName;
}
public String getIpAddress() {
return ipAddress;
}
public String getGatewayAddress() {
return gatewayAddress;
}
public String[] getDnsServers() {
return dnsServers;
}
public void clearSettings() {
log("DataConnection.clearSettings()");
this.state = State.INACTIVE;
this.createTime = -1;
this.lastFailTime = -1;
this.lastFailCause = FailCause.NONE;
receivedDisconnectReq = false;
onConnectCompleted = null;
interfaceName = null;
ipAddress = null;
gatewayAddress = null;
dnsServers[0] = null;
dnsServers[1] = null;
}
protected void onGetLastFailCompleted(AsyncResult ar) {
if (receivedDisconnectReq) {
// Don't bother reporting the error if there's already a
// pending disconnect request, since DataConnectionTracker
// has already updated its state.
notifyDisconnect(onDisconnect);
} else {
FailCause cause = FailCause.UNKNOWN;
if (ar.exception == null) {
int rilFailCause = ((int[]) (ar.result))[0];
cause = getFailCauseFromRequest(rilFailCause);
}
notifyFail(cause, onConnectCompleted);
}
}
protected void onForceRetry() {
if (receivedDisconnectReq) {
notifyDisconnect(onDisconnect);
} else {
notifyFail(FailCause.RADIO_ERROR_RETRY, onConnectCompleted);
}
}
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
log("DataConnection.handleMessage()");
switch (msg.what) {
case EVENT_SETUP_DATA_CONNECTION_DONE:
onSetupConnectionCompleted((AsyncResult) msg.obj);
break;
case EVENT_FORCE_RETRY:
onForceRetry();
break;
case EVENT_GET_LAST_FAIL_DONE:
onGetLastFailCompleted((AsyncResult) msg.obj);
break;
case EVENT_LINK_STATE_CHANGED:
ar = (AsyncResult) msg.obj;
DataLink.LinkState ls = (DataLink.LinkState) ar.result;
onLinkStateChanged(ls);
break;
case EVENT_DEACTIVATE_DONE:
onDeactivated((AsyncResult) msg.obj);
break;
}
}
public State getState() {
log("DataConnection.getState()");
return state;
}
public long getConnectionTime() {
log("DataConnection.getConnectionTime()");
return createTime;
}
public long getLastFailTime() {
log("DataConnection.getLastFailTime()");
return lastFailTime;
}
public FailCause getLastFailCause() {
log("DataConnection.getLastFailCause()");
return lastFailCause;
}
}

View File

@@ -0,0 +1,313 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.app.PendingIntent;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.INetStatService;
import android.os.Message;
import android.os.RemoteException;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
/**
* {@hide}
*
*/
public abstract class DataConnectionTracker extends Handler {
private static final boolean DBG = true;
/**
* IDLE: ready to start data connection setup, default state
* INITING: state of issued setupDefaultPDP() but not finish yet
* CONNECTING: state of issued startPppd() but not finish yet
* SCANNING: data connection fails with one apn but other apns are available
* ready to start data connection on other apns (before INITING)
* CONNECTED: IP connection is setup
* DISCONNECTING: Connection.disconnect() has been called, but PDP
* context is not yet deactivated
* FAILED: data connection fail for all apns settings
*
* getDataConnectionState() maps State to DataState
* FAILED or IDLE : DISCONNECTED
* INITING or CONNECTING or SCANNING: CONNECTING
* CONNECTED : CONNECTED or DISCONNECTING
*/
public enum State {
IDLE,
INITING,
CONNECTING,
SCANNING,
CONNECTED,
DISCONNECTING,
FAILED
}
public enum Activity {
NONE,
DATAIN,
DATAOUT,
DATAINANDOUT
}
//***** Event Codes
protected static final int EVENT_DATA_SETUP_COMPLETE = 1;
protected static final int EVENT_RADIO_AVAILABLE = 3;
protected static final int EVENT_RECORDS_LOADED = 4;
protected static final int EVENT_TRY_SETUP_DATA = 5;
protected static final int EVENT_DATA_STATE_CHANGED = 6;
protected static final int EVENT_POLL_PDP = 7;
protected static final int EVENT_GET_PDP_LIST_COMPLETE = 11;
protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 12;
protected static final int EVENT_VOICE_CALL_STARTED = 14;
protected static final int EVENT_VOICE_CALL_ENDED = 15;
protected static final int EVENT_GPRS_DETACHED = 19;
protected static final int EVENT_LINK_STATE_CHANGED = 20;
protected static final int EVENT_ROAMING_ON = 21;
protected static final int EVENT_ROAMING_OFF = 22;
protected static final int EVENT_ENABLE_NEW_APN = 23;
protected static final int EVENT_RESTORE_DEFAULT_APN = 24;
protected static final int EVENT_DISCONNECT_DONE = 25;
protected static final int EVENT_GPRS_ATTACHED = 26;
protected static final int EVENT_START_NETSTAT_POLL = 27;
protected static final int EVENT_START_RECOVERY = 28;
protected static final int EVENT_APN_CHANGED = 29;
protected static final int EVENT_CDMA_DATA_DETACHED = 30;
protected static final int EVENT_NV_READY = 31;
protected static final int EVENT_PS_RESTRICT_ENABLED = 32;
protected static final int EVENT_PS_RESTRICT_DISABLED = 33;
//***** Constants
protected static final int RECONNECT_DELAY_INITIAL_MILLIS = 5 * 1000;
/** Cap out with 1 hour retry interval. */
protected static final int RECONNECT_DELAY_MAX_MILLIS = 60 * 60 * 1000;
/** Slow poll when attempting connection recovery. */
protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
/** Default ping deadline, in seconds. */
protected final int DEFAULT_PING_DEADLINE = 5;
/** Default max failure count before attempting to network re-registration. */
protected final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
/**
* After detecting a potential connection problem, this is the max number
* of subsequent polls before attempting a radio reset. At this point,
* poll interval is 5 seconds (POLL_NETSTAT_SLOW_MILLIS), so set this to
* poll for about 2 more minutes.
*/
protected static final int NO_RECV_POLL_LIMIT = 24;
// 1 sec. default polling interval when screen is on.
protected static final int POLL_NETSTAT_MILLIS = 1000;
// 10 min. default polling interval when screen is off.
protected static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
// 2 min for round trip time
protected static final int POLL_LONGEST_RTT = 120 * 1000;
// 10 for packets without ack
protected static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
// how long to wait before switching back to default APN
protected static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000;
// system property that can override the above value
protected static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore";
// represents an invalid IP address
protected static final String NULL_IP = "0.0.0.0";
// member variables
protected PhoneBase phone;
protected Activity activity = Activity.NONE;
protected State state = State.IDLE;
protected Handler mDataConnectionTracker = null;
protected INetStatService netstat;
protected long txPkts, rxPkts, sentSinceLastRecv;
protected int netStatPollPeriod;
protected int mNoRecvPollCount = 0;
protected boolean netStatPollEnabled = false;
// wifi connection status will be updated by sticky intent
protected boolean mIsWifiConnected = false;
/** Intent sent when the reconnect alarm fires. */
protected PendingIntent mReconnectIntent = null;
/** CID of active data connection */
protected int cidActive;
/**
* Default constructor
*/
protected DataConnectionTracker(PhoneBase phone) {
super();
this.phone = phone;
}
public Activity getActivity() {
return activity;
}
public State getState() {
return state;
}
public String getStateInString() {
switch (state) {
case IDLE: return "IDLE";
case INITING: return "INIT";
case CONNECTING: return "CING";
case SCANNING: return "SCAN";
case CONNECTED: return "CNTD";
case DISCONNECTING: return "DING";
case FAILED: return "FAIL";
default: return "ERRO";
}
}
/**
* The data connection is expected to be setup while device
* 1. has Icc card
* 2. registered for data service
* 3. user doesn't explicitly disable data service
* 4. wifi is not on
*
* @return false while no data connection if all above requirements are met.
*/
public abstract boolean isDataConnectionAsDesired();
//The data roaming setting is now located in the shared preferences.
// See if the requested preference value is the same as that stored in
// the shared values. If it is not, then update it.
public void setDataOnRoamingEnabled(boolean enabled) {
if (getDataOnRoamingEnabled() != enabled) {
Settings.Secure.putInt(phone.getContext().getContentResolver(),
Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
}
Message roamingMsg = phone.getServiceState().getRoaming() ?
obtainMessage(EVENT_ROAMING_ON) : obtainMessage(EVENT_ROAMING_OFF);
sendMessage(roamingMsg);
}
//Retrieve the data roaming setting from the shared preferences.
public boolean getDataOnRoamingEnabled() {
try {
return Settings.Secure.getInt(phone.getContext().getContentResolver(),
Settings.Secure.DATA_ROAMING) > 0;
} catch (SettingNotFoundException snfe) {
return false;
}
}
// abstract handler methods
protected abstract void onTrySetupData();
protected abstract void onRoamingOff();
protected abstract void onRoamingOn();
protected abstract void onRadioAvailable();
protected abstract void onRadioOffOrNotAvailable();
protected abstract void onDataSetupComplete(AsyncResult ar);
protected abstract void onDisconnectDone(AsyncResult ar);
protected abstract void onVoiceCallStarted();
protected abstract void onVoiceCallEnded();
//***** Overridden from Handler
public void handleMessage (Message msg) {
switch (msg.what) {
case EVENT_TRY_SETUP_DATA:
onTrySetupData();
break;
case EVENT_ROAMING_OFF:
onRoamingOff();
break;
case EVENT_ROAMING_ON:
onRoamingOn();
break;
case EVENT_RADIO_AVAILABLE:
onRadioAvailable();
break;
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
onRadioOffOrNotAvailable();
break;
case EVENT_DATA_SETUP_COMPLETE:
cidActive = msg.arg1;
onDataSetupComplete((AsyncResult) msg.obj);
break;
case EVENT_DISCONNECT_DONE:
onDisconnectDone((AsyncResult) msg.obj);
break;
case EVENT_VOICE_CALL_STARTED:
onVoiceCallStarted();
break;
case EVENT_VOICE_CALL_ENDED:
onVoiceCallEnded();
break;
default:
Log.e("DATA", "Unidentified event = " + msg.what);
break;
}
}
/**
* Simply tear down data connections due to radio off
* and don't setup again.
*/
public abstract void cleanConnectionBeforeRadioOff();
/**
* Report the current state of data connectivity (enabled or disabled)
* @return {@code false} if data connectivity has been explicitly disabled,
* {@code true} otherwise.
*/
public abstract boolean getDataEnabled();
/**
* Report on whether data connectivity is enabled
* @return {@code false} if data connectivity has been explicitly disabled,
* {@code true} otherwise.
*/
public abstract boolean getAnyDataEnabled();
/**
* Prevent mobile data connections from being established,
* or once again allow mobile data connections. If the state
* toggles, then either tear down or set up data, as
* appropriate to match the new state.
* @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
* @return {@code true} if the operation succeeded
*/
public abstract boolean setDataEnabled(boolean enable);
protected abstract void startNetStatPoll();
protected abstract void stopNetStatPoll();
protected abstract void restartRadio();
protected abstract void log(String s);
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import android.os.Handler;
import android.os.Registrant;
@@ -24,14 +24,13 @@ import android.os.Registrant;
*
* {@hide}
*/
abstract class DataLink extends Handler implements DataLinkInterface {
public abstract class DataLink extends Handler implements DataLinkInterface {
/** Registrant for link status change notifications. */
Registrant mLinkChangeRegistrant;
protected Registrant mLinkChangeRegistrant;
protected DataConnectionTracker dataConnection;
DataLink(DataConnectionTracker dc) {
protected DataLink(DataConnectionTracker dc) {
dataConnection = dc;
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import android.database.Cursor;
import android.os.Handler;
@@ -24,7 +24,7 @@ import android.os.Handler;
*
* {@hide}
*/
interface DataLinkInterface {
public interface DataLinkInterface {
/**
* Link state enumeration.
*
@@ -35,21 +35,21 @@ interface DataLinkInterface {
LINK_DOWN,
LINK_EXITED
}
/** Normal exit */
final static int EXIT_OK = 0;
/** Open failed */
final static int EXIT_OPEN_FAILED = 7;
/**
* Sets the handler for link state change events.
*
*
* @param h Handler
* @param what User-defined message code
* @param obj User object
*/
void setOnLinkChange(Handler h, int what, Object obj);
/**
* Sets up the data link.
*/
@@ -59,14 +59,14 @@ interface DataLinkInterface {
* Tears down the data link.
*/
void disconnect();
/**
* Returns the exit code for a data link failure.
* Returns the exit code for a data link failure.
*
* @return exit code
*/
int getLastLinkExitCode();
/**
* Sets password information that may be required by the data link
* (eg, PAP secrets).

View File

@@ -33,7 +33,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
private static final boolean DBG = true;
private ITelephonyRegistry mRegistry;
/*package*/
/*package*/
DefaultPhoneNotifier() {
mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
@@ -94,7 +94,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
public void notifyDataConnection(Phone sender, String reason) {
try {
mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),
mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),
sender.isDataConnectivityPossible(), reason, sender.getActiveApn(),
sender.getInterfaceName(null));
} catch (RemoteException ex) {
@@ -119,7 +119,7 @@ public class DefaultPhoneNotifier implements PhoneNotifier {
// system process is dead
}
}
private void log(String s) {
Log.d(LOG_TAG, "[PhoneNotifier] " + s);
}

View File

@@ -14,9 +14,8 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
import com.android.internal.telephony.*;
package com.android.internal.telephony;
//import com.android.internal.telephony.*;
import android.util.Log;
import java.lang.Comparable;
import android.telephony.PhoneNumberUtils;
@@ -24,10 +23,9 @@ import android.telephony.PhoneNumberUtils;
/**
* {@hide}
*/
public class DriverCall implements Comparable
{
static final String LOG_TAG = "GSM";
public class DriverCall implements Comparable {
static final String LOG_TAG = "RILB";
public enum State {
ACTIVE,
HOLDING,
@@ -48,11 +46,10 @@ public class DriverCall implements Comparable
public boolean isVoice;
public int als;
public int numberPresentation;
/** returns null on error */
static DriverCall
fromCLCCLine(String line)
{
fromCLCCLine(String line) {
DriverCall ret = new DriverCall();
//+CLCC: 1,0,2,0,0,\"+18005551212\",145
@@ -66,10 +63,10 @@ public class DriverCall implements Comparable
ret.isVoice = (0 == p.nextInt());
ret.isMpty = p.nextBoolean();
// use ALLOWED as default presentation while parsing CLCC
ret.numberPresentation = Connection.PRESENTATION_ALLOWED;
if (p.hasMore()) {
// Some lame implementations return strings
// like "NOT AVAILABLE" in the CLCC line
@@ -98,13 +95,11 @@ public class DriverCall implements Comparable
}
public
DriverCall()
{
DriverCall() {
}
public String
toString()
{
toString() {
return "id=" + index + ","
+ (isMT ? "mt" : "mo") + ","
+ state + ","
@@ -114,8 +109,7 @@ public class DriverCall implements Comparable
}
public static State
stateFromCLCC(int state) throws ATParseEx
{
stateFromCLCC(int state) throws ATParseEx {
switch(state) {
case 0: return State.ACTIVE;
case 1: return State.HOLDING;
@@ -127,7 +121,7 @@ public class DriverCall implements Comparable
throw new ATParseEx("illegal call state " + state);
}
}
public static int
presentationFromCLIP(int cli) throws ATParseEx
{
@@ -141,12 +135,11 @@ public class DriverCall implements Comparable
}
}
//***** Comparable Implementation
//***** Comparable Implementation
/** For sorting by index */
public int
compareTo (Object o)
{
compareTo (Object o) {
DriverCall dc;
dc = (DriverCall)o;

View File

@@ -14,25 +14,21 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
/**
* {@hide}
*/
public class EncodeException extends Exception
{
public EncodeException()
{
public class EncodeException extends Exception {
public EncodeException() {
super();
}
public EncodeException(String s)
{
public EncodeException(String s) {
super(s);
}
public EncodeException(char c)
{
public EncodeException(char c) {
super("Unencodable char: '" + c + "'");
}
}

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import android.telephony.gsm.SmsMessage;
import android.telephony.SmsMessage;
import android.util.SparseIntArray;
import android.util.Log;
@@ -28,16 +28,15 @@ import android.util.Log;
*
* {@hide}
*/
public class GsmAlphabet
{
public class GsmAlphabet {
static final String LOG_TAG = "GSM";
//***** Constants
/**
* This escapes extended characters, and when present indicates that the
* This escapes extended characters, and when present indicates that the
* following character should
* be looked up in the "extended" table
*
@@ -55,8 +54,7 @@ public class GsmAlphabet
* should follow GSM_EXTENDED_ESCAPE in the GSM alphabet string
*/
public static int
charToGsm(char c)
{
charToGsm(char c) {
try {
return charToGsm(c, false);
} catch (EncodeException ex) {
@@ -67,7 +65,7 @@ public class GsmAlphabet
/**
* char to GSM alphabet char
* @param throwException If true, throws EncodeException on invalid char.
* @param throwException If true, throws EncodeException on invalid char.
* If false, returns GSM alphabet ' ' char.
*
* Returns GSM_EXTENDED_ESCAPE if this character is in the extended table
@@ -76,10 +74,9 @@ public class GsmAlphabet
*/
public static int
charToGsm(char c, boolean throwException) throws EncodeException
{
charToGsm(char c, boolean throwException) throws EncodeException {
int ret;
ret = charToGsm.get(c, -1);
if (ret == -1) {
@@ -99,7 +96,7 @@ public class GsmAlphabet
return ret;
}
/**
* char to extended GSM alphabet char
@@ -110,10 +107,9 @@ public class GsmAlphabet
*
*/
public static int
charToGsmExtended(char c)
{
charToGsmExtended(char c) {
int ret;
ret = charToGsmExtended.get(c, -1);
if (ret == -1) {
@@ -124,34 +120,32 @@ public class GsmAlphabet
}
/**
* Converts a character in the GSM alphabet into a char
* Converts a character in the GSM alphabet into a char
*
* if GSM_EXTENDED_ESCAPE is passed, 0xffff is returned. In this case,
* the following character in the stream should be decoded with
* the following character in the stream should be decoded with
* gsmExtendedToChar()
*
* If an unmappable value is passed (one greater than 127), ' ' is returned
*/
public static char
gsmToChar(int gsmChar)
{
gsmToChar(int gsmChar) {
return (char)gsmToChar.get(gsmChar, ' ');
}
/**
* Converts a character in the extended GSM alphabet into a char
* Converts a character in the extended GSM alphabet into a char
*
* if GSM_EXTENDED_ESCAPE is passed, ' ' is returned since no second
* extension page has yet been defined (see Note 1 in table 6.2.1.1 of
* TS 23.038 v7.00)
*
*
* If an unmappable value is passed , ' ' is returned
*/
public static char
gsmExtendedToChar(int gsmChar)
{
gsmExtendedToChar(int gsmChar) {
int ret;
ret = gsmExtendedToChar.get(gsmChar, -1);
@@ -205,7 +199,7 @@ public class GsmAlphabet
}
/**
* Converts a String into a byte array containing
* Converts a String into a byte array containing
* the 7-bit packed GSM Alphabet representation of the string.
*
* Unencodable chars are encoded as spaces
@@ -224,7 +218,7 @@ public class GsmAlphabet
}
/**
* Converts a String into a byte array containing
* Converts a String into a byte array containing
* the 7-bit packed GSM Alphabet representation of the string.
*
* Byte 0 in the returned byte array is the count of septets used
@@ -238,7 +232,7 @@ public class GsmAlphabet
* enforced maximum.
* @param startingBitOffset the number of padding bits to put before
* the start of the first septet at the begining of the array
* @param throwException If true, throws EncodeException on invalid char.
* @param throwException If true, throws EncodeException on invalid char.
* If false, replaces unencodable char with GSM alphabet space char.
*
* @throws EncodeException if String is too large to encode
@@ -294,27 +288,26 @@ public class GsmAlphabet
* @param bitOffset the bit offset that the septet should be packed at
* (septet index * 7)
*/
private static void
packSmsChar(byte[] packedChars, int bitOffset, int value)
{
private static void
packSmsChar(byte[] packedChars, int bitOffset, int value) {
int byteOffset = bitOffset / 8;
int shift = bitOffset % 8;
packedChars[++byteOffset] |= value << shift;
if (shift > 1) {
packedChars[++byteOffset] = (byte)(value >> (8 - shift));
}
packedChars[++byteOffset] = (byte)(value >> (8 - shift));
}
}
/**
* Convert a GSM alphabet 7 bit packed string (SMS string) into a
* Convert a GSM alphabet 7 bit packed string (SMS string) into a
* {@link java.lang.String}.
*
* See TS 23.038 6.1.2.1 for SMS Character Packing
*
* @param pdu the raw data from the pdu
* @param offset the byte offset of
* @param offset the byte offset of
* @param lengthSeptets string length in septets, not bytes
* @return String representation or null on decoding exception
*/
@@ -324,27 +317,26 @@ public class GsmAlphabet
}
/**
* Convert a GSM alphabet 7 bit packed string (SMS string) into a
* Convert a GSM alphabet 7 bit packed string (SMS string) into a
* {@link java.lang.String}.
*
* See TS 23.038 6.1.2.1 for SMS Character Packing
*
* @param pdu the raw data from the pdu
* @param offset the byte offset of
* @param offset the byte offset of
* @param lengthSeptets string length in septets, not bytes
* @param numPaddingBits the number of padding bits before the start of the
* string in the first byte
* @return String representation or null on decoding exception
*/
public static String gsm7BitPackedToString(byte[] pdu, int offset,
int lengthSeptets, int numPaddingBits)
{
int lengthSeptets, int numPaddingBits) {
StringBuilder ret = new StringBuilder(lengthSeptets);
boolean prevCharWasEscape;
try {
prevCharWasEscape = false;
for (int i = 0 ; i < lengthSeptets ; i++) {
int bitOffset = (7 * i) + numPaddingBits;
@@ -381,15 +373,14 @@ public class GsmAlphabet
/**
* Convert a GSM alphabet string that's stored in 8-bit unpacked
* Convert a GSM alphabet string that's stored in 8-bit unpacked
* format (as it often appears in SIM records) into a String
*
* Field may be padded with trailing 0xff's. The decode stops
* at the first 0xff encountered.
*/
public static String
gsm8BitUnpackedToString(byte[] data, int offset, int length)
{
gsm8BitUnpackedToString(byte[] data, int offset, int length) {
boolean prevWasEscape;
StringBuilder ret = new StringBuilder(length);
@@ -420,8 +411,8 @@ public class GsmAlphabet
prevWasEscape = false;
}
}
return ret.toString();
return ret.toString();
}
/**
@@ -429,8 +420,7 @@ public class GsmAlphabet
* array
*/
public static byte[]
stringToGsm8BitPacked(String s)
{
stringToGsm8BitPacked(String s) {
byte[] ret;
int septets = 0;
@@ -452,15 +442,14 @@ public class GsmAlphabet
*
* Field is padded with 0xff's, string is truncated if necessary
*/
public static void
stringToGsm8BitUnpackedField(String s, byte dest[], int offset, int length)
{
stringToGsm8BitUnpackedField(String s, byte dest[], int offset, int length) {
int outByteIndex = offset;
// Septets are stored in byte-aligned octets
for (int i = 0, sz = s.length()
; i < sz && (outByteIndex - offset) < length
; i < sz && (outByteIndex - offset) < length
; i++
) {
char c = s.charAt(i);
@@ -475,7 +464,7 @@ public class GsmAlphabet
dest[outByteIndex++] = GSM_EXTENDED_ESCAPE;
v = GsmAlphabet.charToGsmExtended(c);
v = GsmAlphabet.charToGsmExtended(c);
}
dest[outByteIndex++] = (byte)v;
@@ -492,8 +481,7 @@ public class GsmAlphabet
* needed to represent this character. Counts unencodable char as 1 septet.
*/
public static int
countGsmSeptets(char c)
{
countGsmSeptets(char c) {
try {
return countGsmSeptets(c, false);
} catch (EncodeException ex) {
@@ -509,21 +497,20 @@ public class GsmAlphabet
* char. Otherwise, counts invalid char as 1 septet
*/
public static int
countGsmSeptets(char c, boolean throwsException) throws EncodeException
{
if (charToGsm.get(c, -1) != -1) {
return 1;
}
if (charToGsmExtended.get(c, -1) != -1) {
return 2;
}
countGsmSeptets(char c, boolean throwsException) throws EncodeException {
if (charToGsm.get(c, -1) != -1) {
return 1;
}
if (charToGsmExtended.get(c, -1) != -1) {
return 2;
}
if (throwsException) {
throw new EncodeException(c);
} else {
// count as a space char
return 1;
} else {
// count as a space char
return 1;
}
}
@@ -532,8 +519,7 @@ public class GsmAlphabet
* needed to represent this string. Counts unencodable char as 1 septet.
*/
public static int
countGsmSeptets(CharSequence s)
{
countGsmSeptets(CharSequence s) {
try {
return countGsmSeptets(s, false);
} catch (EncodeException ex) {
@@ -549,8 +535,7 @@ public class GsmAlphabet
* char. Otherwise, counts invalid char as 1 septet
*/
public static int
countGsmSeptets(CharSequence s, boolean throwsException) throws EncodeException
{
countGsmSeptets(CharSequence s, boolean throwsException) throws EncodeException {
int charIndex = 0;
int sz = s.length();
int count = 0;
@@ -559,9 +544,9 @@ public class GsmAlphabet
count += countGsmSeptets(s.charAt(charIndex), throwsException);
charIndex++;
}
return count;
}
}
/**
* Returns the index into <code>s</code> of the first character
@@ -623,7 +608,7 @@ public class GsmAlphabet
* @return index of first character that won't fit, or the length
* of the entire string if everything fits
*/
public static int
public static int
findLimitIndex(String s, int start, int limit, int encodingType) throws EncodeException {
if (encodingType == SmsMessage.ENCODING_7BIT) {
return findGsmSeptetLimitIndex(s, start, limit);
@@ -643,10 +628,10 @@ public class GsmAlphabet
private static final SparseIntArray gsmToChar = new SparseIntArray();
private static final SparseIntArray charToGsmExtended = new SparseIntArray();
private static final SparseIntArray gsmExtendedToChar = new SparseIntArray();
static {
int i = 0;
charToGsm.put('@', i++);
charToGsm.put('\u00a3', i++);
charToGsm.put('$', i++);
@@ -663,7 +648,7 @@ public class GsmAlphabet
charToGsm.put('\r', i++);
charToGsm.put('\u00c5', i++);
charToGsm.put('\u00e5', i++);
charToGsm.put('\u0394', i++);
charToGsm.put('_', i++);
charToGsm.put('\u03a6', i++);
@@ -680,7 +665,7 @@ public class GsmAlphabet
charToGsm.put('\u00e6', i++);
charToGsm.put('\u00df', i++);
charToGsm.put('\u00c9', i++);
charToGsm.put(' ', i++);
charToGsm.put('!', i++);
charToGsm.put('"', i++);
@@ -697,7 +682,7 @@ public class GsmAlphabet
charToGsm.put('-', i++);
charToGsm.put('.', i++);
charToGsm.put('/', i++);
charToGsm.put('0', i++);
charToGsm.put('1', i++);
charToGsm.put('2', i++);
@@ -714,7 +699,7 @@ public class GsmAlphabet
charToGsm.put('=', i++);
charToGsm.put('>', i++);
charToGsm.put('?', i++);
charToGsm.put('\u00a1', i++);
charToGsm.put('A', i++);
charToGsm.put('B', i++);
@@ -731,7 +716,7 @@ public class GsmAlphabet
charToGsm.put('M', i++);
charToGsm.put('N', i++);
charToGsm.put('O', i++);
charToGsm.put('P', i++);
charToGsm.put('Q', i++);
charToGsm.put('R', i++);
@@ -748,7 +733,7 @@ public class GsmAlphabet
charToGsm.put('\u0147', i++);
charToGsm.put('\u00dc', i++);
charToGsm.put('\u00a7', i++);
charToGsm.put('\u00bf', i++);
charToGsm.put('a', i++);
charToGsm.put('b', i++);
@@ -765,7 +750,7 @@ public class GsmAlphabet
charToGsm.put('m', i++);
charToGsm.put('n', i++);
charToGsm.put('o', i++);
charToGsm.put('p', i++);
charToGsm.put('q', i++);
charToGsm.put('r', i++);
@@ -782,8 +767,8 @@ public class GsmAlphabet
charToGsm.put('\u00f1', i++);
charToGsm.put('\u00fc', i++);
charToGsm.put('\u00e0', i++);
charToGsmExtended.put('\f', 10);
charToGsmExtended.put('^', 20);
charToGsmExtended.put('{', 40);
@@ -794,12 +779,12 @@ public class GsmAlphabet
charToGsmExtended.put(']', 62);
charToGsmExtended.put('|', 64);
charToGsmExtended.put('\u20ac', 101);
int size = charToGsm.size();
for (int j=0; j<size; j++) {
gsmToChar.put(charToGsm.valueAt(j), charToGsm.keyAt(j));
}
size = charToGsmExtended.size();
for (int j=0; j<size; j++) {
gsmExtendedToChar.put(charToGsmExtended.valueAt(j), charToGsmExtended.keyAt(j));
@@ -808,6 +793,6 @@ public class GsmAlphabet
sGsmSpaceChar = charToGsm.get(' ');
}
}

View File

@@ -14,27 +14,27 @@
** limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import com.android.internal.telephony.gsm.AdnRecord;
import com.android.internal.telephony.AdnRecord;
import java.util.List;
/** Interface for applications to access the SIM phone book.
/** Interface for applications to access the ICC phone book.
*
* <p>The following code snippet demonstrates a static method to
* retrieve the ISimPhoneBook interface from Android:</p>
* <pre>private static ISimPhoneBook getSimPhoneBookInterface()
* retrieve the IIccPhoneBook interface from Android:</p>
* <pre>private static IIccPhoneBook getSimPhoneBookInterface()
throws DeadObjectException {
IServiceManager sm = ServiceManagerNative.getDefault();
ISimPhoneBook spb;
spb = ISimPhoneBook.Stub.asInterface(sm.getService("simphonebook"));
IIccPhoneBook spb;
spb = IIccPhoneBook.Stub.asInterface(sm.getService("iccphonebook"));
return spb;
}
* </pre>
*/
interface ISimPhoneBook {
interface IIccPhoneBook {
/**
* Loads the AdnRecords in efid and returns them as a

View File

@@ -39,9 +39,9 @@ interface IPhoneSubInfo {
String getSubscriberId();
/**
* Retrieves the serial number of the SIM, if applicable.
* Retrieves the serial number of the ICC, if applicable.
*/
String getSimSerialNumber();
String getIccSerialNumber();
/**
* Retrieves the phone number string for line 1.
@@ -53,13 +53,13 @@ interface IPhoneSubInfo {
*/
String getLine1AlphaTag();
/**
* Retrieves the voice mail number.
*/
/**
* Retrieves the voice mail number.
*/
String getVoiceMailNumber();
/**
* Retrieves the alpha identifier associated with the voice mail number.
*/
/**
* Retrieves the alpha identifier associated with the voice mail number.
*/
String getVoiceMailAlphaTag();
}

View File

@@ -14,20 +14,20 @@
** limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import android.app.PendingIntent;
import com.android.internal.telephony.gsm.SmsRawData;
import com.android.internal.telephony.SmsRawData;
/** Interface for applications to access the SIM phone book.
/** Interface for applications to access the ICC phone book.
*
* <p>The following code snippet demonstrates a static method to
* retrieve the ISimSms interface from Android:</p>
* <pre>private static ISimSms getSimSmsInterface()
* retrieve the ISms interface from Android:</p>
* <pre>private static ISms getSmsInterface()
throws DeadObjectException {
IServiceManager sm = ServiceManagerNative.getDefault();
ISimSms ss;
ss = ISimSms.Stub.asInterface(sm.getService("isms"));
ISms ss;
ss = ISms.Stub.asInterface(sm.getService("isms"));
return ss;
}
* </pre>
@@ -35,45 +35,45 @@ import com.android.internal.telephony.gsm.SmsRawData;
interface ISms {
/**
* Retrieves all messages currently stored on SIM.
* Retrieves all messages currently stored on ICC.
*
* @return list of SmsRawData of all sms on SIM
* @return list of SmsRawData of all sms on ICC
*/
List<SmsRawData> getAllMessagesFromSimEf();
List<SmsRawData> getAllMessagesFromIccEf();
/**
* Update the specified message on the SIM.
* Update the specified message on the ICC.
*
* @param messageIndex record index of message to update
* @param newStatus new message status (STATUS_ON_SIM_READ,
* STATUS_ON_SIM_UNREAD, STATUS_ON_SIM_SENT,
* STATUS_ON_SIM_UNSENT, STATUS_ON_SIM_FREE)
* @param newStatus new message status (STATUS_ON_ICC_READ,
* STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
* STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
* @param pdu the raw PDU to store
* @return success or not
*
*/
boolean updateMessageOnSimEf(int messageIndex, int newStatus,
boolean updateMessageOnIccEf(int messageIndex, int newStatus,
in byte[] pdu);
/**
* Copy a raw SMS PDU to the SIM.
* Copy a raw SMS PDU to the ICC.
*
* @param pdu the raw PDU to store
* @param status message status (STATUS_ON_SIM_READ, STATUS_ON_SIM_UNREAD,
* STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT)
* @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
* STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
* @return success or not
*
*/
boolean copyMessageToSimEf(int status, in byte[] pdu, in byte[] smsc);
boolean copyMessageToIccEf(int status, in byte[] pdu, in byte[] smsc);
/**
* Send a SMS
*
* @param smsc the SMSC to send the message through, or NULL for the
* defatult SMSC
* default SMSC
* @param pdu the raw PDU to send
* @param sentIntent if not NULL this <code>Intent</code> is
* broadcast when the message is sucessfully sent, or failed.
* broadcast when the message is successfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
@@ -88,13 +88,13 @@ interface ISms {
/**
* Send a multi-part text based SMS.
*
*
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message
* @param sentIntents if not null, an <code>ArrayList</code> of
* @param sentIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been sent.
* The result code will be <code>Activity.RESULT_OK<code> for success,
@@ -102,7 +102,7 @@ interface ISms {
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* @param deliveryIntents if not null, an <code>ArrayList</code> of
* @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been delivered
* to the recipient. The raw pdu of the status report is in the

View File

@@ -21,7 +21,7 @@ import java.util.List;
import android.telephony.NeighboringCellInfo;
/**
* Interface used to interact with the phone. Mostly this is used by the
* Interface used to interact with the phone. Mostly this is used by the
* TelephonyManager class. A few places are still using this directly.
* Please clean them up if possible and use TelephonyManager insteadl.
*
@@ -135,7 +135,7 @@ interface ITelephony {
/**
* Cancels the missed calls notification.
*/
void cancelMissedCallsNotification();
void cancelMissedCallsNotification();
/**
* Supply a pin to unlock the SIM. Blocks until a result is determined.
@@ -147,7 +147,7 @@ interface ITelephony {
/**
* Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
* without SEND (so <code>dial</code> is not appropriate).
*
*
* @param dialString the MMI command to be executed.
* @return true if MMI command is executed.
*/
@@ -213,4 +213,13 @@ interface ITelephony {
int getCallState();
int getDataActivity();
int getDataState();
/**
* Returns the current active phone type as integer.
* Returns TelephonyManager.PHONE_TYPE_CDMA if RILConstants.CDMA_PHONE
* and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE
*/
int getActivePhoneType();
}

View File

@@ -22,35 +22,34 @@ import android.os.Handler;
/**
* {@hide}
*/
public interface SimCard
{
/* The extra data for broacasting intent INTENT_SIM_STATE_CHANGE */
static public final String INTENT_KEY_SIM_STATE = "ss";
/* NOT_READY means the SIM interface is not ready (eg, radio is off or powering on) */
static public final String INTENT_VALUE_SIM_NOT_READY = "NOT_READY";
/* ABSENT means SIM is missing */
static public final String INTENT_VALUE_SIM_ABSENT = "ABSENT";
/* LOCKED means SIM is locked by pin or by network */
static public final String INTENT_VALUE_SIM_LOCKED = "LOCKED";
/* READY means SIM is ready to access */
static public final String INTENT_VALUE_SIM_READY = "READY";
/* IMSI means SIM IMSI is ready in property */
static public final String INTENT_VALUE_SIM_IMSI = "IMSI";
/* LOADED means all SIM records, including IMSI, are loaded */
static public final String INTENT_VALUE_SIM_LOADED = "LOADED";
/* The extra data for broacasting intent INTENT_SIM_STATE_CHANGE */
public interface IccCard {
/* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
static public final String INTENT_KEY_ICC_STATE = "ss";
/* NOT_READY means the ICC interface is not ready (eg, radio is off or powering on) */
static public final String INTENT_VALUE_ICC_NOT_READY = "NOT_READY";
/* ABSENT means ICC is missing */
static public final String INTENT_VALUE_ICC_ABSENT = "ABSENT";
/* LOCKED means ICC is locked by pin or by network */
static public final String INTENT_VALUE_ICC_LOCKED = "LOCKED";
/* READY means ICC is ready to access */
static public final String INTENT_VALUE_ICC_READY = "READY";
/* IMSI means ICC IMSI is ready in property */
static public final String INTENT_VALUE_ICC_IMSI = "IMSI";
/* LOADED means all ICC records, including IMSI, are loaded */
static public final String INTENT_VALUE_ICC_LOADED = "LOADED";
/* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
static public final String INTENT_KEY_LOCKED_REASON = "reason";
/* PIN means SIM is locked on PIN1 */
/* PIN means ICC is locked on PIN1 */
static public final String INTENT_VALUE_LOCKED_ON_PIN = "PIN";
/* PUK means SIM is locked on PUK1 */
/* PUK means ICC is locked on PUK1 */
static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK";
/* NETWORK means SIM is locked on NETWORK PERSONALIZATION */
/* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
/*
UNKNOWN is a transient state, for example, after uesr inputs sim pin under
PIN_REQUIRED state, the query for sim status returns UNKNOWN before it
UNKNOWN is a transient state, for example, after uesr inputs ICC pin under
PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it
turns to READY
*/
public enum State {
@@ -73,7 +72,7 @@ public interface SimCard
* Notifies handler of any transition into State.ABSENT
*/
void registerForAbsent(Handler h, int what, Object obj);
void unregisterForAbsent(Handler h);
void unregisterForAbsent(Handler h);
/**
* Notifies handler of any transition into State.isPinLocked()
@@ -88,7 +87,7 @@ public interface SimCard
void unregisterForNetworkLocked(Handler h);
/**
* Supply the SIM PIN to the SIM
* Supply the ICC PIN to the ICC
*
* When the operation is complete, onComplete will be sent to it's
* Handler.
@@ -100,11 +99,11 @@ public interface SimCard
*
* If the supplied PIN is incorrect:
* ((AsyncResult)onComplete.obj).exception != null
* && ((AsyncResult)onComplete.obj).exception
* && ((AsyncResult)onComplete.obj).exception
* instanceof com.android.internal.telephony.gsm.CommandException)
* && ((CommandException)(((AsyncResult)onComplete.obj).exception))
* .getCommandError() == CommandException.Error.PASSWORD_INCORRECT
*
*
*
*/
@@ -114,30 +113,30 @@ public interface SimCard
void supplyPuk2 (String puk2, String newPin2, Message onComplete);
/**
* Check whether sim pin lock is enabled
* Check whether ICC pin lock is enabled
* This is a sync call which returns the cached pin enabled state
*
* @return true for sim locked enabled
* false for sim locked disabled
* @return true for ICC locked enabled
* false for ICC locked disabled
*/
boolean getSimLockEnabled ();
boolean getIccLockEnabled ();
/**
* Set the sim pin lock enabled or disabled
* Set the ICC pin lock enabled or disabled
* When the operation is complete, onComplete will be sent to its handler
*
* @param enabled "true" for locked "false" for unlocked.
* @param password needed to change the sim pin state, aka. Pin1
* @param password needed to change the ICC pin state, aka. Pin1
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
void setSimLockEnabled(boolean enabled, String password, Message onComplete);
void setIccLockEnabled(boolean enabled, String password, Message onComplete);
/**
* Change the sim password used in sim pin lock
* Change the ICC password used in ICC pin lock
* When the operation is complete, onComplete will be sent to its handler
*
* @param oldPassword is the old password
@@ -147,33 +146,33 @@ public interface SimCard
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
void changeSimLockPassword(String oldPassword, String newPassword,
void changeIccLockPassword(String oldPassword, String newPassword,
Message onComplete);
/**
* Check whether sim fdn (fixed dialing number) is enabled
* Check whether ICC fdn (fixed dialing number) is enabled
* This is a sync call which returns the cached pin enabled state
*
* @return true for sim fdn enabled
* false for sim fdn disabled
* @return true for ICC fdn enabled
* false for ICC fdn disabled
*/
boolean getSimFdnEnabled ();
boolean getIccFdnEnabled ();
/**
* Set the sim fdn enabled or disabled
* Set the ICC fdn enabled or disabled
* When the operation is complete, onComplete will be sent to its handler
*
* @param enabled "true" for locked "false" for unlocked.
* @param password needed to change the sim fdn enable, aka Pin2
* @param password needed to change the ICC fdn enable, aka Pin2
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
void setSimFdnEnabled(boolean enabled, String password, Message onComplete);
void setIccFdnEnabled(boolean enabled, String password, Message onComplete);
/**
* Change the sim password used in sim fdn enable
* Change the ICC password used in ICC fdn enable
* When the operation is complete, onComplete will be sent to its handler
*
* @param oldPassword is the old password
@@ -183,13 +182,13 @@ public interface SimCard
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
void changeSimFdnPassword(String oldPassword, String newPassword,
void changeIccFdnPassword(String oldPassword, String newPassword,
Message onComplete);
void supplyNetworkDepersonalization (String pin, Message onComplete);
/**
* Returns service provider name stored in SIM card.
* Returns service provider name stored in ICC card.
* If there is no service provider name associated or the record is not
* yet available, null will be returned <p>
*
@@ -199,7 +198,7 @@ public interface SimCard
*
* Also available via Android property "gsm.sim.operator.alpha"
*
* @return Service Provider Name stored in SIM card
* @return Service Provider Name stored in ICC card
* null if no service provider name associated or the record is not
* yet available
*

View File

@@ -0,0 +1,178 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
/**
* See also RIL_AppStatus in include/telephony/ril.h
*
* {@hide}
*/
public class IccCardApplication {
public enum AppType{
APPTYPE_UNKNOWN,
APPTYPE_SIM,
APPTYPE_USIM,
APPTYPE_RUIM,
APPTYPE_CSIM
};
public enum AppState{
APPSTATE_UNKNOWN,
APPSTATE_DETECTED,
APPSTATE_PIN,
APPSTATE_PUK,
APPSTATE_SUBSCRIPTION_PERSO,
APPSTATE_READY;
boolean isPinRequired() {
return this == APPSTATE_PIN;
}
boolean isPukRequired() {
return this == APPSTATE_PUK;
}
boolean isSubscriptionPersoEnabled() {
return this == APPSTATE_SUBSCRIPTION_PERSO;
}
boolean isAppReady() {
return this == APPSTATE_READY;
}
boolean isAppNotReady() {
return this == APPSTATE_UNKNOWN ||
this == APPSTATE_DETECTED;
}
};
public enum PersoSubState{
PERSOSUBSTATE_UNKNOWN,
PERSOSUBSTATE_IN_PROGRESS,
PERSOSUBSTATE_READY,
PERSOSUBSTATE_SIM_NETWORK,
PERSOSUBSTATE_SIM_NETWORK_SUBSET,
PERSOSUBSTATE_SIM_CORPORATE,
PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
PERSOSUBSTATE_SIM_SIM,
PERSOSUBSTATE_SIM_NETWORK_PUK,
PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK,
PERSOSUBSTATE_SIM_CORPORATE_PUK,
PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK,
PERSOSUBSTATE_SIM_SIM_PUK,
PERSOSUBSTATE_RUIM_NETWORK1,
PERSOSUBSTATE_RUIM_NETWORK2,
PERSOSUBSTATE_RUIM_HRPD,
PERSOSUBSTATE_RUIM_CORPORATE,
PERSOSUBSTATE_RUIM_SERVICE_PROVIDER,
PERSOSUBSTATE_RUIM_RUIM,
PERSOSUBSTATE_RUIM_NETWORK1_PUK,
PERSOSUBSTATE_RUIM_NETWORK2_PUK,
PERSOSUBSTATE_RUIM_HRPD_PUK,
PERSOSUBSTATE_RUIM_CORPORATE_PUK,
PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK,
PERSOSUBSTATE_RUIM_RUIM_PUK;
boolean isPersoSubStateUnknown() {
return this == PERSOSUBSTATE_UNKNOWN;
}
};
public AppType app_type;
public AppState app_state;
// applicable only if app_state == RIL_APPSTATE_SUBSCRIPTION_PERSO
public PersoSubState perso_substate;
// null terminated string, e.g., from 0xA0, 0x00 -> 0x41, 0x30, 0x30, 0x30 */
public String aid;
// null terminated string
public String app_label;
// applicable to USIM and CSIM
public int pin1_replaced;
public int pin1;
public int pin2;
AppType AppTypeFromRILInt(int type) {
AppType newType;
/* RIL_AppType ril.h */
switch(type) {
case 0: newType = AppType.APPTYPE_UNKNOWN; break;
case 1: newType = AppType.APPTYPE_SIM; break;
case 2: newType = AppType.APPTYPE_USIM; break;
case 3: newType = AppType.APPTYPE_RUIM; break;
case 4: newType = AppType.APPTYPE_CSIM; break;
default:
throw new RuntimeException(
"Unrecognized RIL_AppType: " +type);
}
return newType;
}
AppState AppStateFromRILInt(int state) {
AppState newState;
/* RIL_AppState ril.h */
switch(state) {
case 0: newState = AppState.APPSTATE_UNKNOWN; break;
case 1: newState = AppState.APPSTATE_DETECTED; break;
case 2: newState = AppState.APPSTATE_PIN; break;
case 3: newState = AppState.APPSTATE_PUK; break;
case 4: newState = AppState.APPSTATE_SUBSCRIPTION_PERSO; break;
case 5: newState = AppState.APPSTATE_READY; break;
default:
throw new RuntimeException(
"Unrecognized RIL_AppState: " +state);
}
return newState;
}
PersoSubState PersoSubstateFromRILInt(int substate) {
PersoSubState newSubState;
/* RIL_PeroSubstate ril.h */
switch(substate) {
case 0: newSubState = PersoSubState.PERSOSUBSTATE_UNKNOWN; break;
case 1: newSubState = PersoSubState.PERSOSUBSTATE_IN_PROGRESS; break;
case 2: newSubState = PersoSubState.PERSOSUBSTATE_READY; break;
case 3: newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK; break;
case 4: newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_SUBSET; break;
case 5: newSubState = PersoSubState.PERSOSUBSTATE_SIM_CORPORATE; break;
case 6: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SERVICE_PROVIDER; break;
case 7: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SIM; break;
case 8: newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_PUK; break;
case 9: newSubState = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK; break;
case 10: newSubState = PersoSubState.PERSOSUBSTATE_SIM_CORPORATE_PUK; break;
case 11: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK; break;
case 12: newSubState = PersoSubState.PERSOSUBSTATE_SIM_SIM_PUK; break;
case 13: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK1; break;
case 14: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK2; break;
case 15: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_HRPD; break;
case 16: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_CORPORATE; break;
case 17: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_SERVICE_PROVIDER; break;
case 18: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_RUIM; break;
case 19: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK1_PUK; break;
case 20: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_NETWORK2_PUK; break;
case 21: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_HRPD_PUK ; break;
case 22: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_CORPORATE_PUK; break;
case 23: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK; break;
case 24: newSubState = PersoSubState.PERSOSUBSTATE_RUIM_RUIM_PUK; break;
default:
throw new RuntimeException(
"Unrecognized RIL_PersoSubstate: " +substate);
}
return newSubState;
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import java.util.ArrayList;
/**
* See also RIL_CardStatus in include/telephony/ril.h
*
* {@hide}
*/
public class IccCardStatus {
static final int CARD_MAX_APPS = 8;
public enum CardState {
CARDSTATE_ABSENT,
CARDSTATE_PRESENT,
CARDSTATE_ERROR;
boolean isCardPresent() {
return this == CARDSTATE_PRESENT;
}
};
public enum PinState {
PINSTATE_UNKNOWN,
PINSTATE_ENABLED_NOT_VERIFIED,
PINSTATE_ENABLED_VERIFIED,
PINSTATE_DISABLED,
PINSTATE_ENABLED_BLOCKED,
PINSTATE_ENABLED_PERM_BLOCKED
};
public CardState card_state;
public PinState universal_pin_state;
public int gsm_umts_subscription_app_index;
public int cdma_subscription_app_index;
public int num_applications;
ArrayList<IccCardApplication> application = new ArrayList<IccCardApplication>(CARD_MAX_APPS);
CardState CardStateFromRILInt(int state) {
CardState newState;
/* RIL_CardState ril.h */
switch(state) {
case 0: newState = CardState.CARDSTATE_ABSENT; break;
case 1: newState = CardState.CARDSTATE_PRESENT; break;
case 2: newState = CardState.CARDSTATE_ERROR; break;
default:
throw new RuntimeException(
"Unrecognized RIL_CardState: " +state);
}
return newState;
}
PinState PinStateFromRILInt(int state) {
PinState newState;
/* RIL_PinState ril.h */
switch(state) {
case 0: newState = PinState.PINSTATE_UNKNOWN; break;
case 1: newState = PinState.PINSTATE_ENABLED_NOT_VERIFIED; break;
case 2: newState = PinState.PINSTATE_ENABLED_VERIFIED; break;
case 3: newState = PinState.PINSTATE_DISABLED; break;
case 4: newState = PinState.PINSTATE_ENABLED_BLOCKED; break;
case 5: newState = PinState.PINSTATE_ENABLED_PERM_BLOCKED; break;
default:
throw new RuntimeException(
"Unrecognized RIL_PinState: " +state);
}
return newState;
}
}

View File

@@ -14,13 +14,13 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
/**
* {@hide}
*/
public interface SimConstants {
// SIM file ids from TS 51.011
public interface IccConstants {
// GSM SIM file ids from TS 51.011
public static final int EF_ADN = 0x6F3A;
public static final int EF_FDN = 0x6F3B;
public static final int EF_SDN = 0x6F49;
@@ -42,7 +42,7 @@ public interface SimConstants {
public static final int EF_CFIS = 0x6FCB;
public static final int EF_IMG = 0x4f20;
// SIM file ids from CPHS (phase 2, version 4.2) CPHS4_2.WW6
// GSM SIM file ids from CPHS (phase 2, version 4.2) CPHS4_2.WW6
public static final int EF_MAILBOX_CPHS = 0x6F17;
public static final int EF_VOICE_MAIL_INDICATOR_CPHS = 0x6F11;
public static final int EF_CFF_CPHS = 0x6F13;
@@ -50,6 +50,10 @@ public interface SimConstants {
public static final int EF_SPN_SHORT_CPHS = 0x6f18;
public static final int EF_INFO_CPHS = 0x6f16;
// CDMA RUIM file ids from 3GPP2 C.S0023-0
public static final int EF_CST = 0x6f32;
public static final int EF_RUIM_SPN =0x6F41;
// SMS record length from TS 51.011 10.5.3
static public final int SMS_RECORD_LENGTH = 176;
}

View File

@@ -14,20 +14,17 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
/**
* {@hide}
*/
public class SimFileTypeMismatch extends SimException
{
SimFileTypeMismatch()
{
public class IccException extends Exception {
public IccException() {
}
SimFileTypeMismatch(String s)
{
public IccException(String s) {
super(s);
}
}

View File

@@ -0,0 +1,513 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.os.*;
import android.util.Log;
import java.util.ArrayList;
/**
* {@hide}
*/
public abstract class IccFileHandler extends Handler {
//from TS 11.11 9.1 or elsewhere
static protected final int COMMAND_READ_BINARY = 0xb0;
static protected final int COMMAND_UPDATE_BINARY = 0xd6;
static protected final int COMMAND_READ_RECORD = 0xb2;
static protected final int COMMAND_UPDATE_RECORD = 0xdc;
static protected final int COMMAND_SEEK = 0xa2;
static protected final int COMMAND_GET_RESPONSE = 0xc0;
// from TS 11.11 9.2.5
static protected final int READ_RECORD_MODE_ABSOLUTE = 4;
//***** types of files TS 11.11 9.3
static protected final int EF_TYPE_TRANSPARENT = 0;
static protected final int EF_TYPE_LINEAR_FIXED = 1;
static protected final int EF_TYPE_CYCLIC = 3;
//***** types of files TS 11.11 9.3
static protected final int TYPE_RFU = 0;
static protected final int TYPE_MF = 1;
static protected final int TYPE_DF = 2;
static protected final int TYPE_EF = 4;
// size of GET_RESPONSE for EF's
static protected final int GET_RESPONSE_EF_SIZE_BYTES = 15;
static protected final int GET_RESPONSE_EF_IMG_SIZE_BYTES = 10;
// Byte order received in response to COMMAND_GET_RESPONSE
// Refer TS 51.011 Section 9.2.1
static protected final int RESPONSE_DATA_RFU_1 = 0;
static protected final int RESPONSE_DATA_RFU_2 = 1;
static protected final int RESPONSE_DATA_FILE_SIZE_1 = 2;
static protected final int RESPONSE_DATA_FILE_SIZE_2 = 3;
static protected final int RESPONSE_DATA_FILE_ID_1 = 4;
static protected final int RESPONSE_DATA_FILE_ID_2 = 5;
static protected final int RESPONSE_DATA_FILE_TYPE = 6;
static protected final int RESPONSE_DATA_RFU_3 = 7;
static protected final int RESPONSE_DATA_ACCESS_CONDITION_1 = 8;
static protected final int RESPONSE_DATA_ACCESS_CONDITION_2 = 9;
static protected final int RESPONSE_DATA_ACCESS_CONDITION_3 = 10;
static protected final int RESPONSE_DATA_FILE_STATUS = 11;
static protected final int RESPONSE_DATA_LENGTH = 12;
static protected final int RESPONSE_DATA_STRUCTURE = 13;
static protected final int RESPONSE_DATA_RECORD_LENGTH = 14;
//***** Events
/** Finished retrieving size of transparent EF; start loading. */
static protected final int EVENT_GET_BINARY_SIZE_DONE = 4;
/** Finished loading contents of transparent EF; post result. */
static protected final int EVENT_READ_BINARY_DONE = 5;
/** Finished retrieving size of records for linear-fixed EF; now load. */
static protected final int EVENT_GET_RECORD_SIZE_DONE = 6;
/** Finished loading single record from a linear-fixed EF; post result. */
static protected final int EVENT_READ_RECORD_DONE = 7;
/** Finished retrieving record size; post result. */
static protected final int EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE = 8;
/** Finished retrieving image instance record; post result. */
static protected final int EVENT_READ_IMG_DONE = 9;
/** Finished retrieving icon data; post result. */
static protected final int EVENT_READ_ICON_DONE = 10;
// member variables
protected PhoneBase phone;
static class LoadLinearFixedContext {
int efid;
int recordNum, recordSize, countRecords;
boolean loadAll;
Message onLoaded;
ArrayList<byte[]> results;
LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) {
this.efid = efid;
this.recordNum = recordNum;
this.onLoaded = onLoaded;
this.loadAll = false;
}
LoadLinearFixedContext(int efid, Message onLoaded) {
this.efid = efid;
this.recordNum = 1;
this.loadAll = true;
this.onLoaded = onLoaded;
}
}
/**
* Default constructor
*/
protected IccFileHandler(PhoneBase phone) {
super();
this.phone = phone;
}
public void dispose() {
}
//***** Public Methods
/**
* Load a record from a SIM Linear Fixed EF
*
* @param fileid EF id
* @param recordNum 1-based (not 0-based) record number
* @param onLoaded
*
* ((AsyncResult)(onLoaded.obj)).result is the byte[]
*
*/
public void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) {
Message response
= obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
new LoadLinearFixedContext(fileid, recordNum, onLoaded));
phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
}
/**
* Load a image instance record from a SIM Linear Fixed EF-IMG
*
* @param recordNum 1-based (not 0-based) record number
* @param onLoaded
*
* ((AsyncResult)(onLoaded.obj)).result is the byte[]
*
*/
public void loadEFImgLinearFixed(int recordNum, Message onLoaded) {
Message response = obtainMessage(EVENT_READ_IMG_DONE,
new LoadLinearFixedContext(IccConstants.EF_IMG, recordNum,
onLoaded));
phone.mCM.iccIO(COMMAND_GET_RESPONSE, IccConstants.EF_IMG, "img",
recordNum, READ_RECORD_MODE_ABSOLUTE,
GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null, response);
}
/**
* get record size for a linear fixed EF
*
* @param fileid EF id
* @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
* int[0] is the record length int[1] is the total length of the EF
* file int[3] is the number of records in the EF file So int[0] *
* int[3] = int[1]
*/
public void getEFLinearRecordSize(int fileid, Message onLoaded) {
Message response
= obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE,
new LoadLinearFixedContext(fileid, onLoaded));
phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
}
/**
* Load all records from a SIM Linear Fixed EF
*
* @param fileid EF id
* @param onLoaded
*
* ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
*
*/
public void loadEFLinearFixedAll(int fileid, Message onLoaded) {
Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,
new LoadLinearFixedContext(fileid,onLoaded));
phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
}
/**
* Load a SIM Transparent EF
*
* @param fileid EF id
* @param onLoaded
*
* ((AsyncResult)(onLoaded.obj)).result is the byte[]
*
*/
public void loadEFTransparent(int fileid, Message onLoaded) {
Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
fileid, 0, onLoaded);
phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, null,
0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);
}
/**
* Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to
* retrive STK's icon data.
*
* @param fileid EF id
* @param onLoaded
*
* ((AsyncResult)(onLoaded.obj)).result is the byte[]
*
*/
public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
int length, Message onLoaded) {
Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
onLoaded);
phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, "img", highOffset, lowOffset,
length, null, null, response);
}
/**
* Update a record in a linear fixed EF
* @param fileid EF id
* @param recordNum 1-based (not 0-based) record number
* @param data must be exactly as long as the record in the EF
* @param pin2 for CHV2 operations, otherwist must be null
* @param onComplete onComplete.obj will be an AsyncResult
* onComplete.obj.userObj will be a IccIoResult on success
*/
public void updateEFLinearFixed(int fileid, int recordNum, byte[] data,
String pin2, Message onComplete) {
phone.mCM.iccIO(COMMAND_UPDATE_RECORD, fileid, null,
recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
IccUtils.bytesToHexString(data), pin2, onComplete);
}
/**
* Update a transparent EF
* @param fileid EF id
* @param data must be exactly as long as the EF
*/
public void updateEFTransparent(int fileid, byte[] data, Message onComplete) {
phone.mCM.iccIO(COMMAND_UPDATE_BINARY, fileid, null,
0, 0, data.length,
IccUtils.bytesToHexString(data), null, onComplete);
}
//***** Abstract Methods
//***** Private Methods
private void sendResult(Message response, Object result, Throwable ex) {
if (response == null) {
return;
}
AsyncResult.forMessage(response, result, ex);
response.sendToTarget();
}
//***** Overridden from Handler
public void handleMessage(Message msg) {
AsyncResult ar;
IccIoResult result;
Message response = null;
String str;
LoadLinearFixedContext lc;
IccException iccException;
byte data[];
int size;
int fileid;
int recordNum;
int recordSize[];
try {
switch (msg.what) {
case EVENT_READ_IMG_DONE:
ar = (AsyncResult) msg.obj;
lc = (LoadLinearFixedContext) ar.userObj;
result = (IccIoResult) ar.result;
response = lc.onLoaded;
iccException = result.getException();
if (iccException != null) {
sendResult(response, result.payload, ar.exception);
}
break;
case EVENT_READ_ICON_DONE:
ar = (AsyncResult) msg.obj;
response = (Message) ar.userObj;
result = (IccIoResult) ar.result;
iccException = result.getException();
if (iccException != null) {
sendResult(response, result.payload, ar.exception);
}
break;
case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE:
ar = (AsyncResult)msg.obj;
lc = (LoadLinearFixedContext) ar.userObj;
result = (IccIoResult) ar.result;
response = lc.onLoaded;
if (ar.exception != null) {
sendResult(response, null, ar.exception);
break;
}
iccException = result.getException();
if (iccException != null) {
sendResult(response, null, iccException);
break;
}
data = result.payload;
if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] ||
EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
throw new IccFileTypeMismatch();
}
recordSize = new int[3];
recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
+ (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
recordSize[2] = recordSize[1] / recordSize[0];
sendResult(response, recordSize, null);
break;
case EVENT_GET_RECORD_SIZE_DONE:
ar = (AsyncResult)msg.obj;
lc = (LoadLinearFixedContext) ar.userObj;
result = (IccIoResult) ar.result;
response = lc.onLoaded;
if (ar.exception != null) {
sendResult(response, null, ar.exception);
break;
}
iccException = result.getException();
if (iccException != null) {
sendResult(response, null, iccException);
break;
}
data = result.payload;
fileid = lc.efid;
recordNum = lc.recordNum;
if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
throw new IccFileTypeMismatch();
}
if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) {
throw new IccFileTypeMismatch();
}
lc.recordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
+ (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
lc.countRecords = size / lc.recordSize;
if (lc.loadAll) {
lc.results = new ArrayList<byte[]>(lc.countRecords);
}
phone.mCM.iccIO(COMMAND_READ_RECORD, lc.efid, null,
lc.recordNum,
READ_RECORD_MODE_ABSOLUTE,
lc.recordSize, null, null,
obtainMessage(EVENT_READ_RECORD_DONE, lc));
break;
case EVENT_GET_BINARY_SIZE_DONE:
ar = (AsyncResult)msg.obj;
response = (Message) ar.userObj;
result = (IccIoResult) ar.result;
if (ar.exception != null) {
sendResult(response, null, ar.exception);
break;
}
iccException = result.getException();
if (iccException != null) {
sendResult(response, null, iccException);
break;
}
data = result.payload;
fileid = msg.arg1;
if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
throw new IccFileTypeMismatch();
}
if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) {
throw new IccFileTypeMismatch();
}
size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
+ (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
phone.mCM.iccIO(COMMAND_READ_BINARY, fileid, null,
0, 0, size, null, null,
obtainMessage(EVENT_READ_BINARY_DONE,
fileid, 0, response));
break;
case EVENT_READ_RECORD_DONE:
ar = (AsyncResult)msg.obj;
lc = (LoadLinearFixedContext) ar.userObj;
result = (IccIoResult) ar.result;
response = lc.onLoaded;
if (ar.exception != null) {
sendResult(response, null, ar.exception);
break;
}
iccException = result.getException();
if (iccException != null) {
sendResult(response, null, iccException);
break;
}
if (!lc.loadAll) {
sendResult(response, result.payload, null);
} else {
lc.results.add(result.payload);
lc.recordNum++;
if (lc.recordNum > lc.countRecords) {
sendResult(response, lc.results, null);
} else {
phone.mCM.iccIO(COMMAND_READ_RECORD, lc.efid, null,
lc.recordNum,
READ_RECORD_MODE_ABSOLUTE,
lc.recordSize, null, null,
obtainMessage(EVENT_READ_RECORD_DONE, lc));
}
}
break;
case EVENT_READ_BINARY_DONE:
ar = (AsyncResult)msg.obj;
response = (Message) ar.userObj;
result = (IccIoResult) ar.result;
if (ar.exception != null) {
sendResult(response, null, ar.exception);
break;
}
iccException = result.getException();
if (iccException != null) {
sendResult(response, null, iccException);
break;
}
sendResult(response, result.payload, null);
break;
}} catch (Exception exc) {
if (response != null) {
sendResult(response, null, exc);
} else {
loge("uncaught exception" + exc);
}
}
}
protected abstract void logd(String s);
protected abstract void loge(String s);
}

View File

@@ -14,25 +14,21 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
/**
* {@hide}
*/
public class SimFileNotFound extends SimException
{
SimFileNotFound()
{
public class IccFileNotFound extends IccException {
IccFileNotFound() {
}
SimFileNotFound(String s)
{
IccFileNotFound(String s) {
super(s);
}
SimFileNotFound(int ef)
{
super("SIM EF Not Found 0x" + Integer.toHexString(ef));
IccFileNotFound(int ef) {
super("ICC EF Not Found 0x" + Integer.toHexString(ef));
}
}

View File

@@ -14,45 +14,17 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
/**
* {@hide}
*/
public class SimException extends Exception
{
SimException()
{
public class IccFileTypeMismatch extends IccException {
public IccFileTypeMismatch() {
}
SimException(String s)
{
public IccFileTypeMismatch(String s) {
super(s);
}
}
final class SimVmFixedException extends SimException {
SimVmFixedException()
{
}
SimVmFixedException(String s)
{
super(s);
}
}
final class SimVmNotSupportedException extends SimException {
SimVmNotSupportedException()
{
}
SimVmNotSupportedException(String s)
{
super(s);
}
}

View File

@@ -14,33 +14,30 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
/**
* {@hide}
*/
public class
SimIoResult
{
IccIoResult {
int sw1;
int sw2;
byte[] payload;
public SimIoResult(int sw1, int sw2, byte[] payload)
{
public byte[] payload;
public IccIoResult(int sw1, int sw2, byte[] payload) {
this.sw1 = sw1;
this.sw2 = sw2;
this.payload = payload;
}
public SimIoResult(int sw1, int sw2, String hexString)
{
this(sw1, sw2, SimUtils.hexStringToBytes(hexString));
public IccIoResult(int sw1, int sw2, String hexString) {
this(sw1, sw2, IccUtils.hexStringToBytes(hexString));
}
public String toString()
{
return "SimIoResponse sw1:0x" + Integer.toHexString(sw1) + " sw2:0x"
public String toString() {
return "IccIoResponse sw1:0x" + Integer.toHexString(sw1) + " sw2:0x"
+ Integer.toHexString(sw2);
}
@@ -49,27 +46,25 @@ SimIoResult
* See GSM 11.11 Section 9.4
* (the fun stuff is absent in 51.011)
*/
public boolean success()
{
public boolean success() {
return sw1 == 0x90 || sw1 == 0x91 || sw1 == 0x9e || sw1 == 0x9f;
}
/**
* Returns exception on error or null if success
*/
public SimException getException()
{
public IccException getException() {
if (success()) return null;
switch (sw1) {
case 0x94:
if (sw2 == 0x08) {
return new SimFileTypeMismatch();
return new IccFileTypeMismatch();
} else {
return new SimFileNotFound();
return new IccFileNotFound();
}
default:
return new SimException("sw1:" + sw1 + " sw2:" + sw2);
return new IccException("sw1:" + sw1 + " sw2:" + sw2);
}
}
}

View File

@@ -0,0 +1,266 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.content.pm.PackageManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.ServiceManager;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* SimPhoneBookInterfaceManager to provide an inter-process communication to
* access ADN-like SIM records.
*/
public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
protected static final boolean DBG = true;
protected PhoneBase phone;
protected AdnRecordCache adnCache;
protected Object mLock = new Object();
protected int recordSize[];
protected boolean success;
protected List<AdnRecord> records;
protected static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false;
protected static final int EVENT_GET_SIZE_DONE = 1;
protected static final int EVENT_LOAD_DONE = 2;
protected static final int EVENT_UPDATE_DONE = 3;
protected Handler mBaseHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
case EVENT_GET_SIZE_DONE:
ar = (AsyncResult) msg.obj;
synchronized (mLock) {
if (ar.exception == null) {
recordSize = (int[])ar.result;
// recordSize[0] is the record length
// recordSize[1] is the total length of the EF file
// recordSize[2] is the number of records in the EF file
logd("GET_RECORD_SIZE Size " + recordSize[0] +
" total " + recordSize[1] +
" #record " + recordSize[2]);
mLock.notifyAll();
}
}
break;
case EVENT_UPDATE_DONE:
ar = (AsyncResult) msg.obj;
synchronized (mLock) {
success = (ar.exception == null);
mLock.notifyAll();
}
break;
case EVENT_LOAD_DONE:
ar = (AsyncResult)msg.obj;
synchronized (mLock) {
if (ar.exception == null) {
records = (List<AdnRecord>)
((ArrayList<AdnRecord>) ar.result);
} else {
if(DBG) logd("Cannot load ADN records");
if (records != null) {
records.clear();
}
}
mLock.notifyAll();
}
break;
}
}
};
public IccPhoneBookInterfaceManager(PhoneBase phone) {
this.phone = phone;
}
public void dispose() {
}
protected void publish() {
//NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
ServiceManager.addService("simphonebook", this);
}
protected abstract void logd(String msg);
protected abstract void loge(String msg);
/**
* Replace oldAdn with newAdn in ADN-like record in EF
*
* getAdnRecordsInEf must be called at least once before this function,
* otherwise an error will be returned
* throws SecurityException if no WRITE_CONTACTS permission
*
* @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
* @param oldTag adn tag to be replaced
* @param oldPhoneNumber adn number to be replaced
* Set both oldTag and oldPhoneNubmer to "" means to replace an
* empty record, aka, insert new record
* @param newTag adn tag to be stored
* @param newPhoneNumber adn number ot be stored
* Set both newTag and newPhoneNubmer to "" means to replace the old
* record with empty one, aka, delete old record
* @param pin2 required to update EF_FDN, otherwise must be null
* @return true for success
*/
public boolean
updateAdnRecordsInEfBySearch (int efid,
String oldTag, String oldPhoneNumber,
String newTag, String newPhoneNumber, String pin2) {
if (phone.getContext().checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(
"Requires android.permission.WRITE_CONTACTS permission");
}
if (DBG) logd("updateAdnRecordsInEfBySearch: efid=" + efid +
" ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
" ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
synchronized(mLock) {
checkThread();
success = false;
Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE);
AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
try {
mLock.wait();
} catch (InterruptedException e) {
logd("interrupted while trying to update by search");
}
}
return success;
}
/**
* Update an ADN-like EF record by record index
*
* This is useful for iteration the whole ADN file, such as write the whole
* phone book or erase/format the whole phonebook
* throws SecurityException if no WRITE_CONTACTS permission
*
* @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
* @param newTag adn tag to be stored
* @param newPhoneNumber adn number to be stored
* Set both newTag and newPhoneNubmer to "" means to replace the old
* record with empty one, aka, delete old record
* @param index is 1-based adn record index to be updated
* @param pin2 required to update EF_FDN, otherwise must be null
* @return true for success
*/
public boolean
updateAdnRecordsInEfByIndex(int efid, String newTag,
String newPhoneNumber, int index, String pin2) {
if (phone.getContext().checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(
"Requires android.permission.WRITE_CONTACTS permission");
}
if (DBG) logd("updateAdnRecordsInEfByIndex: efid=" + efid +
" Index=" + index + " ==> " +
"("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
synchronized(mLock) {
checkThread();
success = false;
Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE);
AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
try {
mLock.wait();
} catch (InterruptedException e) {
logd("interrupted while trying to update by index");
}
}
return success;
}
/**
* Get the capacity of records in efid
*
* @param efid the EF id of a ADN-like ICC
* @return int[3] array
* recordSizes[0] is the single record length
* recordSizes[1] is the total length of the EF file
* recordSizes[2] is the number of records in the EF file
*/
public abstract int[] getAdnRecordsSize(int efid);
/**
* Loads the AdnRecords in efid and returns them as a
* List of AdnRecords
*
* throws SecurityException if no READ_CONTACTS permission
*
* @param efid the EF id of a ADN-like ICC
* @return List of AdnRecord
*/
public List<AdnRecord> getAdnRecordsInEf(int efid) {
if (phone.getContext().checkCallingOrSelfPermission(
android.Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(
"Requires android.permission.READ_CONTACTS permission");
}
if (DBG) logd("getAdnRecordsInEF: efid=" + efid);
synchronized(mLock) {
checkThread();
Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE);
adnCache.requestLoadAllAdnLike(efid, response);
try {
mLock.wait();
} catch (InterruptedException e) {
logd("interrupted while trying to load from the SIM");
}
}
return records;
}
protected void checkThread() {
if (!ALLOW_SIM_OP_IN_UI_THREAD) {
// Make sure this isn't the UI thread, since it will block
if (mBaseHandler.getLooper().equals(Looper.myLooper())) {
loge("query() called on the main UI thread!");
throw new IllegalStateException(
"You cannot call query on this provder from the main UI thread.");
}
}
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.content.pm.PackageManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.ServiceManager;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* SimPhoneBookInterfaceManager to provide an inter-process communication to
* access ADN-like SIM records.
*/
public class IccPhoneBookInterfaceManagerProxy extends IIccPhoneBook.Stub {
private IccPhoneBookInterfaceManager mIccPhoneBookInterfaceManager;
public IccPhoneBookInterfaceManagerProxy(IccPhoneBookInterfaceManager
iccPhoneBookInterfaceManager) {
mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager;
if(ServiceManager.getService("simphonebook") == null) {
ServiceManager.addService("simphonebook", this);
}
}
public void setmIccPhoneBookInterfaceManager(
IccPhoneBookInterfaceManager iccPhoneBookInterfaceManager) {
this.mIccPhoneBookInterfaceManager = iccPhoneBookInterfaceManager;
}
public boolean
updateAdnRecordsInEfBySearch (int efid,
String oldTag, String oldPhoneNumber,
String newTag, String newPhoneNumber,
String pin2) throws android.os.RemoteException {
return mIccPhoneBookInterfaceManager.updateAdnRecordsInEfBySearch(
efid, oldTag, oldPhoneNumber, newTag, newPhoneNumber, pin2);
}
public boolean
updateAdnRecordsInEfByIndex(int efid, String newTag,
String newPhoneNumber, int index, String pin2) throws android.os.RemoteException {
return mIccPhoneBookInterfaceManager.updateAdnRecordsInEfByIndex(efid,
newTag, newPhoneNumber, index, pin2);
}
public int[] getAdnRecordsSize(int efid) throws android.os.RemoteException {
return mIccPhoneBookInterfaceManager.getAdnRecordsSize(efid);
}
public List<AdnRecord> getAdnRecordsInEf(int efid) throws android.os.RemoteException {
return mIccPhoneBookInterfaceManager.getAdnRecordsInEf(efid);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
package com.android.internal.telephony;
import android.content.ContentProvider;
import android.content.UriMatcher;
@@ -31,11 +31,16 @@ import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.IIccPhoneBook;
/**
* {@hide}
*/
public class SimProvider extends ContentProvider {
private static final String TAG = "SimProvider";
public class IccProvider extends ContentProvider {
private static final String TAG = "IccProvider";
private static final boolean DBG = false;
@@ -56,9 +61,9 @@ public class SimProvider extends ContentProvider {
new UriMatcher(UriMatcher.NO_MATCH);
static {
URL_MATCHER.addURI("sim", "adn", ADN);
URL_MATCHER.addURI("sim", "fdn", FDN);
URL_MATCHER.addURI("sim", "sdn", SDN);
URL_MATCHER.addURI("icc", "adn", ADN);
URL_MATCHER.addURI("icc", "fdn", FDN);
URL_MATCHER.addURI("icc", "sdn", SDN);
}
@@ -81,21 +86,21 @@ public class SimProvider extends ContentProvider {
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
ArrayList<ArrayList> results;
if (!mSimulator) {
switch (URL_MATCHER.match(url)) {
case ADN:
results = loadFromEf(SimConstants.EF_ADN);
results = loadFromEf(IccConstants.EF_ADN);
break;
case FDN:
results = loadFromEf(SimConstants.EF_FDN);
results = loadFromEf(IccConstants.EF_FDN);
break;
case SDN:
results = loadFromEf(SimConstants.EF_SDN);
results = loadFromEf(IccConstants.EF_SDN);
break;
default:
throw new IllegalArgumentException("Unknown URL " + url);
}
@@ -152,11 +157,11 @@ public class SimProvider extends ContentProvider {
int match = URL_MATCHER.match(url);
switch (match) {
case ADN:
efType = SimConstants.EF_ADN;
efType = IccConstants.EF_ADN;
break;
case FDN:
efType = SimConstants.EF_FDN;
efType = IccConstants.EF_FDN;
pin2 = initialValues.getAsString("pin2");
break;
@@ -167,7 +172,7 @@ public class SimProvider extends ContentProvider {
String tag = initialValues.getAsString("tag");
String number = initialValues.getAsString("number");
boolean success = addSimRecordToEf(efType, tag, number, pin2);
boolean success = addIccRecordToEf(efType, tag, number, pin2);
if (!success) {
return null;
@@ -183,7 +188,7 @@ public class SimProvider extends ContentProvider {
buf.append("fdn/");
break;
}
// TODO: we need to find out the rowId for the newly added record
buf.append(0);
@@ -218,11 +223,11 @@ public class SimProvider extends ContentProvider {
int match = URL_MATCHER.match(url);
switch (match) {
case ADN:
efType = SimConstants.EF_ADN;
efType = IccConstants.EF_ADN;
break;
case FDN:
efType = SimConstants.EF_FDN;
efType = IccConstants.EF_FDN;
break;
default:
@@ -269,7 +274,7 @@ public class SimProvider extends ContentProvider {
return 0;
}
boolean success = deleteSimRecordFromEf(efType, tag, number, pin2);
boolean success = deleteIccRecordFromEf(efType, tag, number, pin2);
if (!success) {
return 0;
}
@@ -287,11 +292,11 @@ public class SimProvider extends ContentProvider {
int match = URL_MATCHER.match(url);
switch (match) {
case ADN:
efType = SimConstants.EF_ADN;
efType = IccConstants.EF_ADN;
break;
case FDN:
efType = SimConstants.EF_FDN;
efType = IccConstants.EF_FDN;
pin2 = values.getAsString("pin2");
break;
@@ -305,7 +310,7 @@ public class SimProvider extends ContentProvider {
String newTag = values.getAsString("newTag");
String newNumber = values.getAsString("newNumber");
boolean success = updateSimRecordInEf(efType, tag, number,
boolean success = updateIccRecordInEf(efType, tag, number,
newTag, newNumber, pin2);
if (!success) {
@@ -322,17 +327,16 @@ public class SimProvider extends ContentProvider {
if (DBG) log("loadFromEf: efType=" + efType);
try {
ISimPhoneBook simIpb = ISimPhoneBook.Stub.asInterface(
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
ServiceManager.getService("simphonebook"));
if (simIpb != null) {
adnRecords = simIpb.getAdnRecordsInEf(efType);
if (iccIpb != null) {
adnRecords = iccIpb.getAdnRecordsInEf(efType);
}
} catch (RemoteException ex) {
// ignore it
} catch (SecurityException ex) {
if (DBG) log(ex.toString());
}
if (adnRecords != null) {
// Load the results
@@ -351,8 +355,8 @@ public class SimProvider extends ContentProvider {
}
private boolean
addSimRecordToEf(int efType, String name, String number, String pin2) {
if (DBG) log("addSimRecordToEf: efType=" + efType + ", name=" + name +
addIccRecordToEf(int efType, String name, String number, String pin2) {
if (DBG) log("addIccRecordToEf: efType=" + efType + ", name=" + name +
", number=" + number);
boolean success = false;
@@ -361,11 +365,12 @@ public class SimProvider extends ContentProvider {
// updateAdnRecordsInEfBySearch()? In any case, we will leave
// the UI level logic to fill that prereq if necessary. But
// hopefully, we can remove this requirement.
try {
ISimPhoneBook simIpb = ISimPhoneBook.Stub.asInterface(
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
ServiceManager.getService("simphonebook"));
if (simIpb != null) {
success = simIpb.updateAdnRecordsInEfBySearch(efType, "", "",
if (iccIpb != null) {
success = iccIpb.updateAdnRecordsInEfBySearch(efType, "", "",
name, number, pin2);
}
} catch (RemoteException ex) {
@@ -373,23 +378,23 @@ public class SimProvider extends ContentProvider {
} catch (SecurityException ex) {
if (DBG) log(ex.toString());
}
if (DBG) log("addSimRecordToEf: " + success);
if (DBG) log("addIccRecordToEf: " + success);
return success;
}
private boolean
updateSimRecordInEf(int efType, String oldName, String oldNumber,
updateIccRecordInEf(int efType, String oldName, String oldNumber,
String newName, String newNumber,String pin2) {
if (DBG) log("updateSimRecordInEf: efType=" + efType +
if (DBG) log("updateIccRecordInEf: efType=" + efType +
", oldname=" + oldName + ", oldnumber=" + oldNumber +
", newname=" + newName + ", newnumber=" + newNumber);
boolean success = false;
try {
ISimPhoneBook simIpb = ISimPhoneBook.Stub.asInterface(
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
ServiceManager.getService("simphonebook"));
if (simIpb != null) {
success = simIpb.updateAdnRecordsInEfBySearch(efType,
if (iccIpb != null) {
success = iccIpb.updateAdnRecordsInEfBySearch(efType,
oldName, oldNumber, newName, newNumber, pin2);
}
} catch (RemoteException ex) {
@@ -397,34 +402,30 @@ public class SimProvider extends ContentProvider {
} catch (SecurityException ex) {
if (DBG) log(ex.toString());
}
if (DBG) log("updateSimRecordInEf: " + success);
if (DBG) log("updateIccRecordInEf: " + success);
return success;
}
private boolean deleteSimRecordFromEf(int efType,
String name, String number,
String pin2) {
if (DBG) log("deleteSimRecordFromEf: efType=" + efType +
private boolean deleteIccRecordFromEf(int efType, String name, String number, String pin2) {
if (DBG) log("deleteIccRecordFromEf: efType=" + efType +
", name=" + name + ", number=" + number + ", pin2=" + pin2);
boolean success = false;
try {
ISimPhoneBook simIpb = ISimPhoneBook.Stub.asInterface(
IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
ServiceManager.getService("simphonebook"));
if (simIpb != null) {
success = simIpb.updateAdnRecordsInEfBySearch(efType,
name, number, "", "", pin2);
if (iccIpb != null) {
success = iccIpb.updateAdnRecordsInEfBySearch(efType,
name, number, "", "", pin2);
}
} catch (RemoteException ex) {
// ignore it
} catch (SecurityException ex) {
if (DBG) log(ex.toString());
}
if (DBG) log("deleteSimRecordFromEf: " + success);
if (DBG) log("deleteIccRecordFromEf: " + success);
return success;
}
@@ -449,7 +450,7 @@ public class SimProvider extends ContentProvider {
}
private void log(String msg) {
Log.d(TAG, "[SimProvider] " + msg);
Log.d(TAG, "[IccProvider] " + msg);
}
}

View File

@@ -0,0 +1,237 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.util.Log;
import java.util.ArrayList;
/**
* {@hide}
*/
public abstract class IccRecords extends Handler implements IccConstants {
protected static final boolean DBG = true;
//***** Instance Variables
protected PhoneBase phone;
protected RegistrantList recordsLoadedRegistrants = new RegistrantList();
protected int recordsToLoad; // number of pending load requests
protected AdnRecordCache adnCache;
//***** Cached SIM State; cleared on channel close
protected boolean recordsRequested = false; // true if we've made requests for the sim records
public String iccid;
protected String msisdn = null; // My mobile number
protected String msisdnTag = null;
protected String voiceMailNum = null;
protected String voiceMailTag = null;
protected String newVoiceMailNum = null;
protected String newVoiceMailTag = null;
protected boolean isVoiceMailFixed = false;
protected int countVoiceMessages = 0;
protected int mncLength = 0; // 0 is used to indicate that the value
// is not initialized
protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
protected String spn;
protected int spnDisplayCondition;
//***** Constants
// Bitmasks for SPN display rules.
protected static final int SPN_RULE_SHOW_SPN = 0x01;
protected static final int SPN_RULE_SHOW_PLMN = 0x02;
//***** Event Constants
protected static final int EVENT_SET_MSISDN_DONE = 30;
//***** Constructor
public IccRecords(PhoneBase p) {
this.phone = p;
}
protected abstract void onRadioOffOrNotAvailable();
//***** Public Methods
public AdnRecordCache getAdnCache() {
return adnCache;
}
public void registerForRecordsLoaded(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
recordsLoadedRegistrants.add(r);
if (recordsToLoad == 0 && recordsRequested == true) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
public void unregisterForRecordsLoaded(Handler h) {
recordsLoadedRegistrants.remove(h);
}
public String getMsisdnNumber() {
return msisdn;
}
/**
* Set subscriber number to SIM record
*
* The subscriber number is stored in EF_MSISDN (TS 51.011)
*
* When the operation is complete, onComplete will be sent to its handler
*
* @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
* @param number dailing nubmer (up to 20 digits)
* if the number starts with '+', then set to international TOA
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
public void setMsisdnNumber(String alphaTag, String number,
Message onComplete) {
msisdn = number;
msisdnTag = alphaTag;
if(DBG) log("Set MSISDN: " + msisdnTag +" " + msisdn);
AdnRecord adn = new AdnRecord(msisdnTag, msisdn);
new AdnRecordLoader(phone).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
}
public String getMsisdnAlphaTag() {
return msisdnTag;
}
public String getVoiceMailNumber() {
return voiceMailNum;
}
/**
* Return Service Provider Name stored in SIM (EF_SPN=0x6F46) or in RUIM (EF_RUIM_SPN=0x6F41)
* @return null if SIM is not yet ready or no RUIM entry
*/
public String getServiceProviderName() {
return spn;
}
/**
* Set voice mail number to SIM record
*
* The voice mail number can be stored either in EF_MBDN (TS 51.011) or
* EF_MAILBOX_CPHS (CPHS 4.2)
*
* If EF_MBDN is available, store the voice mail number to EF_MBDN
*
* If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
*
* So the voice mail number will be stored in both EFs if both are available
*
* Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
*
* When the operation is complete, onComplete will be sent to its handler
*
* @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
* @param voiceNumber dailing nubmer (upto 20 digits)
* if the number is start with '+', then set to international TOA
* @param onComplete
* onComplete.obj will be an AsyncResult
* ((AsyncResult)onComplete.obj).exception == null on success
* ((AsyncResult)onComplete.obj).exception != null on fail
*/
public abstract void setVoiceMailNumber(String alphaTag, String voiceNumber,
Message onComplete);
public String getVoiceMailAlphaTag() {
return voiceMailTag;
}
/**
* Sets the SIM voice message waiting indicator records
* @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
* @param countWaiting The number of messages waiting, if known. Use
* -1 to indicate that an unknown number of
* messages are waiting
*/
public abstract void setVoiceMessageWaiting(int line, int countWaiting);
/** @return true if there are messages waiting, false otherwise. */
public boolean getVoiceMessageWaiting() {
return countVoiceMessages != 0;
}
/**
* Returns number of voice messages waiting, if available
* If not available (eg, on an older CPHS SIM) -1 is returned if
* getVoiceMessageWaiting() is true
*/
public int getCountVoiceMessages() {
return countVoiceMessages;
}
/**
* Called by STK Service when REFRESH is received.
* @param fileChanged indicates whether any files changed
* @param fileList if non-null, a list of EF files that changed
*/
public abstract void onRefresh(boolean fileChanged, int[] fileList);
public boolean getRecordsLoaded() {
if (recordsToLoad == 0 && recordsRequested == true) {
return true;
} else {
return false;
}
}
//***** Overridden from Handler
public abstract void handleMessage(Message msg);
protected abstract void onRecordLoaded();
protected abstract void onAllRecordsLoaded();
/**
* Returns the SpnDisplayRule based on settings on the SIM and the
* specified plmn (currently-registered PLMN). See TS 22.101 Annex A
* and TS 51.011 10.3.11 for details.
*
* If the SPN is not found on the SIM, the rule is always PLMN_ONLY.
*/
protected abstract int getDisplayRule(String plmn);
protected abstract void log(String s);
}

View File

@@ -0,0 +1,166 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.app.PendingIntent;
import android.content.Context;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
/**
* IccSmsInterfaceManager to provide an inter-process communication to
* access Sms in Icc.
*/
public abstract class IccSmsInterfaceManager extends ISms.Stub {
static final boolean DBG = true;
protected PhoneBase mPhone;
protected Context mContext;
protected SMSDispatcher mDispatcher;
protected IccSmsInterfaceManager(PhoneBase phone){
mPhone = phone;
mContext = phone.getContext();
}
protected void enforceReceiveAndSend(String message) {
mContext.enforceCallingPermission(
"android.permission.RECEIVE_SMS", message);
mContext.enforceCallingPermission(
"android.permission.SEND_SMS", message);
}
/**
* Send a Raw PDU SMS
*
* @param smsc the SMSC to send the message through, or NULL for the
* defatult SMSC
* @param pdu the raw PDU to send
* @param sentIntent if not NULL this <code>Intent</code> is
* broadcast when the message is sucessfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* @param deliveryIntent if not NULL this <code>Intent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*/
public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
Context context = mPhone.getContext();
context.enforceCallingPermission(
"android.permission.SEND_SMS",
"Sending SMS message");
if (DBG) log("sendRawPdu: smsc=" + smsc +
" pdu="+ pdu + " sentIntent" + sentIntent +
" deliveryIntent" + deliveryIntent);
mDispatcher.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
}
/**
* Send a multi-part text based SMS.
*
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message
* @param sentIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been sent.
* The result code will be <code>Activity.RESULT_OK<code> for success,
* or one of these errors:
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
* @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been delivered
* to the recipient. The raw pdu of the status report is in the
* extended data ("pdu").
*/
public void sendMultipartText(String destinationAddress, String scAddress, List<String> parts,
List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
Context context = mPhone.getContext();
context.enforceCallingPermission(
"android.permission.SEND_SMS",
"Sending SMS message");
if (DBG) log("sendMultipartText");
mDispatcher.sendMultipartText(destinationAddress, scAddress, (ArrayList<String>) parts,
(ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
}
/**
* create SmsRawData lists from all sms record byte[]
* Use null to indicate "free" record
*
* @param messages List of message records from EF_SMS.
* @return SmsRawData list of all in-used records
*/
protected ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) {
int count = messages.size();
ArrayList<SmsRawData> ret;
ret = new ArrayList<SmsRawData>(count);
for (int i = 0; i < count; i++) {
byte[] ba = messages.get(i);
if (ba[0] == STATUS_ON_ICC_FREE) {
ret.add(null);
} else {
ret.add(new SmsRawData(messages.get(i)));
}
}
return ret;
}
/**
* Generates an EF_SMS record from status and raw PDU.
*
* @param status Message status. See TS 51.011 10.5.3.
* @param pdu Raw message PDU.
* @return byte array for the record.
*/
protected byte[] makeSmsRecordData(int status, byte[] pdu) {
byte[] data = new byte[IccConstants.SMS_RECORD_LENGTH];
// Status bits for this record. See TS 51.011 10.5.3
data[0] = (byte)(status & 7);
System.arraycopy(pdu, 0, data, 1, pdu.length);
// Pad out with 0xFF's.
for (int j = pdu.length+1; j < IccConstants.SMS_RECORD_LENGTH; j++) {
data[j] = -1;
}
return data;
}
protected abstract void log(String msg);
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.app.PendingIntent;
import android.os.ServiceManager;
import java.util.List;
public class IccSmsInterfaceManagerProxy extends ISms.Stub {
private IccSmsInterfaceManager mIccSmsInterfaceManager;
public IccSmsInterfaceManagerProxy(IccSmsInterfaceManager
iccSmsInterfaceManager) {
this.mIccSmsInterfaceManager = iccSmsInterfaceManager;
if(ServiceManager.getService("isms") == null) {
ServiceManager.addService("isms", this);
}
}
public void setmIccSmsInterfaceManager(IccSmsInterfaceManager iccSmsInterfaceManager) {
this.mIccSmsInterfaceManager = iccSmsInterfaceManager;
}
public boolean
updateMessageOnIccEf(int index, int status, byte[] pdu) throws android.os.RemoteException {
return mIccSmsInterfaceManager.updateMessageOnIccEf(index, status, pdu);
}
public boolean copyMessageToIccEf(int status, byte[] pdu,
byte[] smsc) throws android.os.RemoteException {
return mIccSmsInterfaceManager.copyMessageToIccEf(status, pdu, smsc);
}
public List<SmsRawData> getAllMessagesFromIccEf() throws android.os.RemoteException {
return mIccSmsInterfaceManager.getAllMessagesFromIccEf();
}
public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent) throws android.os.RemoteException {
mIccSmsInterfaceManager.sendRawPdu(smsc, pdu, sentIntent,
deliveryIntent);
}
public void sendMultipartText(String destinationAddress, String scAddress,
List<String> parts, List<PendingIntent> sentIntents,
List<PendingIntent> deliveryIntents) throws android.os.RemoteException {
mIccSmsInterfaceManager.sendMultipartText(destinationAddress, scAddress,
parts, sentIntents, deliveryIntents);
}
}

View File

@@ -14,48 +14,48 @@
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
import java.io.UnsupportedEncodingException;
package com.android.internal.telephony;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.Log;
import com.android.internal.telephony.GsmAlphabet;
import java.io.UnsupportedEncodingException;
/**
* Various methods, useful for dealing with SIM data.
*/
public class SimUtils
{
static final String LOG_TAG="GSM";
public class IccUtils {
static final String LOG_TAG="IccUtils";
/**
* Many fields in GSM SIM's are stored as nibble-swizzled BCD
*
* Assumes left-justified field that may be padded right with 0xf
* Assumes left-justified field that may be padded right with 0xf
* values.
*
* Stops on invalid BCD value, returning string so far
*/
public static String
bcdToString(byte[] data, int offset, int length)
{
bcdToString(byte[] data, int offset, int length) {
StringBuilder ret = new StringBuilder(length*2);
for (int i = offset ; i < offset + length ; i++) {
byte b;
int v;
v = data[i] & 0xf;
if (v > 9) break;
ret.append((char)('0' + v));
v = (data[i] >> 4) & 0xf;
if (v > 9) break;
ret.append((char)('0' + v));
ret.append((char)('0' + v));
}
return ret.toString();
return ret.toString();
}
@@ -66,7 +66,7 @@ public class SimUtils
* significant nibble.
*
* Out-of-range digits are treated as 0 for the sake of the time stamp,
* because of this:
* because of this:
*
* TS 23.040 section 9.2.3.11
* "if the MS receives a non-integer value in the SCTS, it shall
@@ -74,13 +74,12 @@ public class SimUtils
* exactly as received"
*/
public static int
bcdByteToInt(byte b)
{
bcdByteToInt(byte b) {
int ret = 0;
// treat out-of-range BCD values as 0
if ((b & 0xf0) <= 0x90) {
ret = (b >> 4) & 0xf;
ret = (b >> 4) & 0xf;
}
if ((b & 0x0f) <= 0x09) {
@@ -90,6 +89,24 @@ public class SimUtils
return ret;
}
/** Decodes BCD byte like {@link bcdByteToInt}, but the most significant BCD
* digit is expected in the most significant nibble.
*/
public static int
beBcdByteToInt(byte b) {
int ret = 0;
// treat out-of-range BCD values as 0
if ((b & 0xf0) <= 0x90) {
ret = ((b >> 4) & 0xf) * 10;
}
if ((b & 0x0f) <= 0x09) {
ret += (b & 0xf);
}
return ret;
}
/**
* Decodes a string field that's formatted like the EF[ADN] alpha
@@ -97,11 +114,11 @@ public class SimUtils
*
* From TS 51.011 10.5.1:
* Coding:
* this alpha tagging shall use either
* - the SMS default 7 bit coded alphabet as defined in
* TS 23.038 [12] with bit 8 set to 0. The alpha identifier
* this alpha tagging shall use either
* - the SMS default 7 bit coded alphabet as defined in
* TS 23.038 [12] with bit 8 set to 0. The alpha identifier
* shall be left justified. Unused bytes shall be set to 'FF'; or
* - one of the UCS2 coded options as defined in annex B.
* - one of the UCS2 coded options as defined in annex B.
*
* Annex B from TS 11.11 V8.13.0:
* 1) If the first octet in the alpha string is '80', then the
@@ -109,7 +126,7 @@ public class SimUtils
* 2) if the first octet in the alpha string is '81', then the
* second octet contains a value indicating the number of
* characters in the string, and the third octet contains an
* 8 bit number which defines bits 15 to 8 of a 16 bit
* 8 bit number which defines bits 15 to 8 of a 16 bit
* base pointer, where bit 16 is set to zero and bits 7 to 1
* are also set to zero. These sixteen bits constitute a
* base pointer to a "half page" in the UCS2 code space, to be
@@ -127,8 +144,7 @@ public class SimUtils
* base pointer to a "half page" in the UCS2 code space...
*/
public static String
adnStringFieldToString(byte[] data, int offset, int length)
{
adnStringFieldToString(byte[] data, int offset, int length) {
if (length >= 1) {
if (data[offset] == (byte) 0x80) {
int ucslen = (length - 1) / 2;
@@ -208,8 +224,7 @@ public class SimUtils
}
static int
hexCharToInt(char c)
{
hexCharToInt(char c) {
if (c >= '0' && c <= '9') return (c - '0');
if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
@@ -219,17 +234,16 @@ public class SimUtils
/**
* Converts a hex String to a byte array.
*
*
* @param s A string of hexadecimal characters, must be an even number of
* chars long
*
* @return byte array representation
*
*
* @throws RuntimeException on invalid format
*/
public static byte[]
hexStringToBytes(String s)
{
hexStringToBytes(String s) {
byte[] ret;
if (s == null) return null;
@@ -239,10 +253,10 @@ public class SimUtils
ret = new byte[sz/2];
for (int i=0 ; i <sz ; i+=2) {
ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4)
ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4)
| hexCharToInt(s.charAt(i+1)));
}
return ret;
}
@@ -253,10 +267,9 @@ public class SimUtils
* null returns null
*/
public static String
bytesToHexString(byte[] bytes)
{
bytesToHexString(byte[] bytes) {
if (bytes == null) return null;
StringBuilder ret = new StringBuilder(2*bytes.length);
for (int i = 0 ; i < bytes.length ; i++) {
@@ -281,10 +294,9 @@ public class SimUtils
* empty string returned on decode error
*/
public static String
networkNameToString(byte[] data, int offset, int length)
{
networkNameToString(byte[] data, int offset, int length) {
String ret;
if ((data[offset] & 0x80) != 0x80 || length < 1) {
return "";
}
@@ -295,13 +307,12 @@ public class SimUtils
int countSeptets;
int unusedBits = data[offset] & 7;
countSeptets = (((length - 1) * 8) - unusedBits) / 7 ;
ret = GsmAlphabet.gsm7BitPackedToString(
data, offset + 1, countSeptets);
ret = GsmAlphabet.gsm7BitPackedToString(data, offset + 1, countSeptets);
break;
case 1:
// UCS2
try {
ret = new String(data,
ret = new String(data,
offset + 1, length - 1, "utf-16");
} catch (UnsupportedEncodingException ex) {
ret = "";
@@ -332,7 +343,7 @@ public class SimUtils
* @param data The raw data
* @param length The length of image body
* @return The bitmap
*/
*/
public static Bitmap parseToBnW(byte[] data, int length){
int valueIndex = 0;
int width = data[valueIndex++] & 0xFF;
@@ -369,7 +380,7 @@ public class SimUtils
/**
* a TS 131.102 image instance of code scheme '11' into color Bitmap
*
*
* @param data The raw data
* @param length the length of image body
* @param transparency with or without transparency

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
/**
* {@hide}
*/
public final class IccVmFixedException extends IccException {
IccVmFixedException()
{
}
public IccVmFixedException(String s)
{
super(s);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
/**
* {@hide}
*/
public final class IccVmNotSupportedException extends IccException {
IccVmNotSupportedException()
{
}
public IccVmNotSupportedException(String s)
{
super(s);
}
}

View File

@@ -41,14 +41,14 @@ public interface MmiCode
* @return Localized message for UI display, valid only in COMPLETE
* or FAILED states. null otherwise
*/
public CharSequence getMessage();
/**
* Cancels pending MMI request.
* State becomes CANCELLED unless already COMPLETE or FAILED
*/
public void cancel();
public void cancel();
/**
* @return true if the network response is a REQUEST for more user input.

File diff suppressed because it is too large Load Diff

View File

@@ -20,23 +20,30 @@ import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.SharedPreferences;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RegistrantList;
import android.os.SystemProperties;
import android.preference.PreferenceManager;
import android.telephony.ServiceState;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
import com.android.internal.telephony.gsm.PdpConnection;
import com.android.internal.telephony.test.SimulatedRadioControl;
import java.util.List;
import java.util.Locale;
/**
* (<em>Not for SDK use</em>)
* (<em>Not for SDK use</em>)
* A base implementation for the com.android.internal.telephony.Phone interface.
*
*
* Note that implementations of Phone.java are expected to be used
* from a single application thread. This should be the same thread that
* originally called PhoneFactory to obtain the interface.
@@ -46,42 +53,101 @@ import java.util.Locale;
*/
public abstract class PhoneBase implements Phone {
private static final String LOG_TAG = "GSM";
private static final String LOG_TAG = "PHONE";
private static final boolean LOCAL_DEBUG = true;
protected final RegistrantList mPhoneStateRegistrants
// Key used to read and write the saved network selection value
public static final String NETWORK_SELECTION_KEY = "network_selection_key";
// Key used to read/write "disable data connection on boot" pref (used for testing)
public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
//***** Event Constants
protected static final int EVENT_RADIO_AVAILABLE = 1;
/** Supplementary Service Notification received. */
protected static final int EVENT_SSN = 2;
protected static final int EVENT_SIM_RECORDS_LOADED = 3;
protected static final int EVENT_MMI_DONE = 4;
protected static final int EVENT_RADIO_ON = 5;
protected static final int EVENT_GET_BASEBAND_VERSION_DONE = 6;
protected static final int EVENT_USSD = 7;
protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 8;
protected static final int EVENT_GET_IMEI_DONE = 9;
protected static final int EVENT_GET_IMEISV_DONE = 10;
protected static final int EVENT_GET_SIM_STATUS_DONE = 11;
protected static final int EVENT_SET_CALL_FORWARD_DONE = 12;
protected static final int EVENT_GET_CALL_FORWARD_DONE = 13;
protected static final int EVENT_CALL_RING = 14;
// Used to intercept the carrier selection calls so that
// we can save the values.
protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 15;
protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 16;
protected static final int EVENT_SET_CLIR_COMPLETE = 17;
protected static final int EVENT_REGISTERED_TO_NETWORK = 18;
protected static final int EVENT_SET_VM_NUMBER_DONE = 19;
// Events for CDMA support
protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 20;
protected static final int EVENT_RUIM_RECORDS_LOADED = 21;
protected static final int EVENT_NV_READY = 22;
protected static final int EVENT_SET_ENHANCED_VP = 23;
// Key used to read/write current CLIR setting
public static final String CLIR_KEY = "clir_key";
// Key used to read/write "disable DNS server check" pref (used for testing)
public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
//***** Instance Variables
public CommandsInterface mCM;
protected IccFileHandler mIccFileHandler;
boolean mDnsCheckDisabled = false;
/**
* Set a system property, unless we're in unit test mode
*/
public void
setSystemProperty(String property, String value) {
if(getUnitTestMode()) {
return;
}
SystemProperties.set(property, value);
}
protected final RegistrantList mPhoneStateRegistrants
= new RegistrantList();
protected final RegistrantList mNewRingingConnectionRegistrants
protected final RegistrantList mNewRingingConnectionRegistrants
= new RegistrantList();
protected final RegistrantList mIncomingRingRegistrants
= new RegistrantList();
protected final RegistrantList mDisconnectRegistrants
protected final RegistrantList mIncomingRingRegistrants
= new RegistrantList();
protected final RegistrantList mServiceStateRegistrants
= new RegistrantList();
protected final RegistrantList mMmiCompleteRegistrants
protected final RegistrantList mDisconnectRegistrants
= new RegistrantList();
protected final RegistrantList mMmiRegistrants
protected final RegistrantList mServiceStateRegistrants
= new RegistrantList();
protected final RegistrantList mUnknownConnectionRegistrants
protected final RegistrantList mMmiCompleteRegistrants
= new RegistrantList();
protected final RegistrantList mSuppServiceFailedRegistrants
protected final RegistrantList mMmiRegistrants
= new RegistrantList();
protected final RegistrantList mUnknownConnectionRegistrants
= new RegistrantList();
protected final RegistrantList mSuppServiceFailedRegistrants
= new RegistrantList();
protected Looper mLooper; /* to insure registrants are in correct thread*/
protected Context mContext;
/**
* PhoneNotifier is an abstraction for all system-wide
* state change notification. DefaultPhoneNotifier is
/**
* PhoneNotifier is an abstraction for all system-wide
* state change notification. DefaultPhoneNotifier is
* used here unless running we're inside a unit test.
*/
protected PhoneNotifier mNotifier;
@@ -94,7 +160,7 @@ public abstract class PhoneBase 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 notifier An instance of DefaultPhoneNotifier,
* unless unit testing.
*/
protected PhoneBase(PhoneNotifier notifier, Context context) {
@@ -105,13 +171,13 @@ public abstract class PhoneBase 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 notifier An instance of DefaultPhoneNotifier,
* unless unit testing.
* @param unitTestMode when true, prevents notifications
* @param unitTestMode when true, prevents notifications
* of state change events
*/
protected PhoneBase(PhoneNotifier notifier, Context context,
boolean unitTestMode) {
protected PhoneBase(PhoneNotifier notifier, Context context,
boolean unitTestMode) {
this.mNotifier = notifier;
this.mContext = context;
mLooper = Looper.myLooper();
@@ -119,6 +185,9 @@ public abstract class PhoneBase implements Phone {
setLocaleByCarrier();
setUnitTestMode(unitTestMode);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
}
// Inherited documentation suffices.
@@ -126,6 +195,26 @@ public abstract class PhoneBase implements Phone {
return mContext;
}
/**
* Disables the DNS check (i.e., allows "0.0.0.0").
* Useful for lab testing environment.
* @param b true disables the check, false enables.
*/
public void disableDnsCheck(boolean b) {
mDnsCheckDisabled = b;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
editor.commit();
}
/**
* Returns true if the DNS check is currently disabled.
*/
public boolean isDnsCheckDisabled() {
return mDnsCheckDisabled;
}
// Inherited documentation suffices.
public void registerForPhoneStateChanged(Handler h, int what, Object obj) {
checkCorrectThread(h);
@@ -137,29 +226,29 @@ public abstract class PhoneBase implements Phone {
public void unregisterForPhoneStateChanged(Handler h) {
mPhoneStateRegistrants.remove(h);
}
/**
* Notify registrants of a PhoneStateChanged.
* Subclasses of Phone probably want to replace this with a
* Subclasses of Phone probably want to replace this with a
* version scoped to their packages
*/
protected void notifyCallStateChangedP() {
AsyncResult ar = new AsyncResult(null, this, null);
mPhoneStateRegistrants.notifyRegistrants(ar);
}
// Inherited documentation suffices.
public void registerForUnknownConnection(Handler h, int what, Object obj) {
checkCorrectThread(h);
mUnknownConnectionRegistrants.addUnique(h, what, obj);
}
// Inherited documentation suffices.
public void unregisterForUnknownConnection(Handler h) {
mUnknownConnectionRegistrants.remove(h);
}
// Inherited documentation suffices.
public void registerForNewRingingConnection(
Handler h, int what, Object obj) {
@@ -173,12 +262,33 @@ public abstract class PhoneBase implements Phone {
mNewRingingConnectionRegistrants.remove(h);
}
// Inherited documentation suffices.
public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
mCM.registerForInCallVoicePrivacyOn(h,what,obj);
}
// Inherited documentation suffices.
public void unregisterForInCallVoicePrivacyOn(Handler h){
mCM.unregisterForInCallVoicePrivacyOn(h);
}
// Inherited documentation suffices.
public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
mCM.registerForInCallVoicePrivacyOff(h,what,obj);
}
// Inherited documentation suffices.
public void unregisterForInCallVoicePrivacyOff(Handler h){
mCM.unregisterForInCallVoicePrivacyOff(h);
}
/**
* Notifiy registrants of a new ringing Connection.
* Subclasses of Phone probably want to replace this with a
* Subclasses of Phone probably want to replace this with a
* version scoped to their packages
*/
protected void notifyNewRingingConnectionP(Connection cn) {
protected void notifyNewRingingConnectionP(Connection cn) {
AsyncResult ar = new AsyncResult(null, cn, null);
mNewRingingConnectionRegistrants.notifyRegistrants(ar);
}
@@ -187,15 +297,15 @@ public abstract class PhoneBase implements Phone {
public void registerForIncomingRing(
Handler h, int what, Object obj) {
checkCorrectThread(h);
mIncomingRingRegistrants.addUnique(h, what, obj);
}
// Inherited documentation suffices.
public void unregisterForIncomingRing(Handler h) {
mIncomingRingRegistrants.remove(h);
}
// Inherited documentation suffices.
public void registerForDisconnect(Handler h, int what, Object obj) {
checkCorrectThread(h);
@@ -211,15 +321,15 @@ public abstract class PhoneBase implements Phone {
// Inherited documentation suffices.
public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
checkCorrectThread(h);
mSuppServiceFailedRegistrants.addUnique(h, what, obj);
}
// Inherited documentation suffices.
public void unregisterForSuppServiceFailed(Handler h) {
mSuppServiceFailedRegistrants.remove(h);
}
// Inherited documentation suffices.
public void registerForMmiInitiate(Handler h, int what, Object obj) {
checkCorrectThread(h);
@@ -231,7 +341,7 @@ public abstract class PhoneBase implements Phone {
public void unregisterForMmiInitiate(Handler h) {
mMmiRegistrants.remove(h);
}
// Inherited documentation suffices.
public void registerForMmiComplete(Handler h, int what, Object obj) {
checkCorrectThread(h);
@@ -247,10 +357,31 @@ public abstract class PhoneBase implements Phone {
}
/**
* Subclasses should override this. See documentation in superclass.
* Method to retrieve the saved operator id from the Shared Preferences
*/
public abstract List getPendingMmiCodes();
private String getSavedNetworkSelection() {
// open the shared preferences and search with our key.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
return sp.getString(NETWORK_SELECTION_KEY, "");
}
/**
* Method to restore the previously saved operator id, or reset to
* automatic selection, all depending upon the value in the shared
* preferences.
*/
public void restoreSavedNetworkSelection(Message response) {
// retrieve the operator id
String networkSelection = getSavedNetworkSelection();
// set to auto if the id is empty, otherwise select the network.
if (TextUtils.isEmpty(networkSelection)) {
mCM.setNetworkSelectionModeAutomatic(response);
} else {
mCM.setNetworkSelectionModeManual(networkSelection, response);
}
}
// Inherited documentation suffices.
public void setUnitTestMode(boolean f) {
mUnitTestMode = f;
@@ -260,11 +391,11 @@ public abstract class PhoneBase implements Phone {
public boolean getUnitTestMode() {
return mUnitTestMode;
}
/**
* To be invoked when a voice call Connection disconnects.
*
* Subclasses of Phone probably want to replace this with a
* Subclasses of Phone probably want to replace this with a
* version scoped to their packages
*/
protected void notifyDisconnectP(Connection cn) {
@@ -286,7 +417,7 @@ public abstract class PhoneBase implements Phone {
}
/**
* Subclasses of Phone probably want to replace this with a
* Subclasses of Phone probably want to replace this with a
* version scoped to their packages
*/
protected void notifyServiceStateChangedP(ServiceState ss) {
@@ -312,7 +443,7 @@ public abstract class PhoneBase implements Phone {
private void checkCorrectThread(Handler h) {
if (h.getLooper() != mLooper) {
throw new RuntimeException(
"com.android.internal.telephony.Phone must be used from within one thread");
"com.android.internal.telephony.Phone must be used from within one thread");
}
}
@@ -401,4 +532,107 @@ public abstract class PhoneBase implements Phone {
}
}
}
/*
* Retrieves the Handler of the Phone instance
*/
public abstract Handler getHandler();
/**
* Retrieves the IccFileHandler of the Phone instance
*/
public abstract IccFileHandler getIccFileHandler();
/**
* Query the status of the CDMA roaming preference
*/
public void queryCdmaRoamingPreference(Message response) {
mCM.queryCdmaRoamingPreference(response);
}
/**
* Set the status of the CDMA roaming preference
*/
public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
mCM.setCdmaRoamingPreference(cdmaRoamingType, response);
}
/**
* Set the status of the CDMA subscription mode
*/
public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
mCM.setCdmaSubscription(cdmaSubscriptionType, response);
}
/**
* Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
*/
public void setPreferredNetworkType(int networkType, Message response) {
mCM.setPreferredNetworkType(networkType, response);
}
/**
* Set the status of the preferred Network Type: Global, CDMA only or GSM/UMTS only
*/
public void getPreferredNetworkType(Message response) {
mCM.getPreferredNetworkType(response);
}
public void setTTYModeEnabled(boolean enable, Message onComplete) {
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
}
public void queryTTYModeEnabled(Message onComplete) {
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
}
/**
* This should only be called in GSM mode.
* Only here for some backward compatibility
* issues concerning the GSMPhone class.
* @deprecated
*/
public List<PdpConnection> getCurrentPdpList() {
return null;
}
public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
}
public void getEnhancedVoicePrivacy(Message onComplete) {
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
}
public void setBandMode(int bandMode, Message response) {
mCM.setBandMode(bandMode, response);
}
public void queryAvailableBandMode(Message response) {
mCM.queryAvailableBandMode(response);
}
public void invokeOemRilRequestRaw(byte[] data, Message response) {
mCM.invokeOemRilRequestRaw(data, response);
}
public void invokeOemRilRequestStrings(String[] strings, Message response) {
mCM.invokeOemRilRequestStrings(strings, response);
}
public void notifyDataActivity() {
mNotifier.notifyDataActivity(this);
}
public void notifyDataConnection(String reason) {
mNotifier.notifyDataConnection(this, reason);
}
public abstract String getPhoneName();
}

View File

@@ -16,80 +16,55 @@
package com.android.internal.telephony;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Collections;
import android.util.Log;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.RIL;
import com.android.internal.telephony.test.ModelInterpreter;
import com.android.internal.telephony.test.SimulatedCommands;
import android.os.Looper;
import android.os.SystemProperties;
import android.content.Context;
import android.content.Intent;
import android.net.LocalServerSocket;
import android.app.ActivityManagerNative;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.gsm.GSMPhone;
/**
* {@hide}
*/
public class PhoneFactory
{
static final String LOG_TAG="GSM";
public class PhoneFactory {
static final String LOG_TAG = "PHONE";
static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
static final int SOCKET_OPEN_MAX_RETRY = 3;
//***** Class Variables
//***** Class Variables
static private ArrayList<Phone> sPhones = new ArrayList<Phone>();
static private Phone sProxyPhone = null;
static private CommandsInterface sCommandsInterface = null;
static private boolean sMadeDefaults = false;
static private PhoneNotifier sPhoneNotifier;
static private Looper sLooper;
static private Context sContext;
static private Object testMailbox;
static final int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
static final int preferredCdmaSubscription = RILConstants.PREFERRED_CDMA_SUBSCRIPTION;
//***** Class Methods
private static void
useNewRIL(Context context)
{
ModelInterpreter mi = null;
GSMPhone phone;
try {
if (false) {
mi = new ModelInterpreter(new InetSocketAddress("127.0.0.1", 6502));
}
phone = new GSMPhone(context, new RIL(context), sPhoneNotifier);
registerPhone (phone);
} catch (IOException ex) {
Log.e(LOG_TAG, "Error creating ModelInterpreter", ex);
}
public static void makeDefaultPhones(Context context) {
makeDefaultPhone(context);
}
/**
* FIXME replace this with some other way of making these
* instances
*/
public static void
makeDefaultPhones(Context context)
{
synchronized(Phone.class) {
if (!sMadeDefaults) {
public static void makeDefaultPhone(Context context) {
synchronized(Phone.class) {
if (!sMadeDefaults) {
sLooper = Looper.myLooper();
sContext = context;
if (sLooper == null) {
throw new RuntimeException(
"PhoneFactory.makeDefaultPhones must be called from Looper thread");
"PhoneFactory.makeDefaultPhone must be called from Looper thread");
}
int retryCount = 0;
@@ -109,7 +84,7 @@ public class PhoneFactory
break;
} else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
throw new RuntimeException("PhoneFactory probably already running");
}else {
} else {
try {
Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
} catch (InterruptedException er) {
@@ -119,44 +94,71 @@ public class PhoneFactory
sPhoneNotifier = new DefaultPhoneNotifier();
if ((SystemProperties.get("ro.radio.noril","")).equals("")) {
useNewRIL(context);
} else {
GSMPhone phone;
phone = new GSMPhone(context, new SimulatedCommands(), sPhoneNotifier);
registerPhone (phone);
}
//Get preferredNetworkMode from Settings.System
int networkMode = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
//Get preferredNetworkMode from Settings.System
int cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION, preferredCdmaSubscription);
Log.i(LOG_TAG, "Cdma Subscription set to " + Integer.toString(cdmaSubscription));
//reads the system properties and makes commandsinterface
sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
switch(networkMode) {
case RILConstants.NETWORK_MODE_WCDMA_PREF:
case RILConstants.NETWORK_MODE_GSM_ONLY:
case RILConstants.NETWORK_MODE_WCDMA_ONLY:
case RILConstants.NETWORK_MODE_GSM_UMTS:
sProxyPhone = new PhoneProxy(new GSMPhone(context,
sCommandsInterface, sPhoneNotifier));
Log.i(LOG_TAG, "Creating GSMPhone");
break;
case RILConstants.NETWORK_MODE_CDMA:
case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
sProxyPhone = new PhoneProxy(new CDMAPhone(context,
sCommandsInterface, sPhoneNotifier));
Log.i(LOG_TAG, "Creating CDMAPhone");
break;
case RILConstants.NETWORK_MODE_GLOBAL:
default:
sProxyPhone = new PhoneProxy(new CDMAPhone(context,
sCommandsInterface, sPhoneNotifier));
Log.i(LOG_TAG, "Creating CDMAPhone");
}
sMadeDefaults = true;
}
}
}
public static Phone getDefaultPhone()
{
public static Phone getDefaultPhone() {
if (sLooper != Looper.myLooper()) {
throw new RuntimeException(
"PhoneFactory.getDefaultPhone must be called from Looper thread");
}
if (!sMadeDefaults) {
throw new IllegalStateException("Default phones haven't been made yet!");
}
return sProxyPhone;
}
if (sLooper != Looper.myLooper()) {
throw new RuntimeException(
"PhoneFactory.getDefaultPhone must be called from Looper thread");
}
synchronized (sPhones) {
return sPhones.isEmpty() ? null : sPhones.get(0);
public static Phone getCdmaPhone() {
synchronized(PhoneProxy.lockForRadioTechnologyChange) {
Phone phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
return phone;
}
}
public static void registerPhone(Phone p)
{
if (sLooper != Looper.myLooper()) {
throw new RuntimeException(
"PhoneFactory.getDefaultPhone must be called from Looper thread");
}
synchronized (sPhones) {
sPhones.add(p);
public static Phone getGsmPhone() {
synchronized(PhoneProxy.lockForRadioTechnologyChange) {
Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier);
return phone;
}
}
}

View File

@@ -0,0 +1,675 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony;
import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.telephony.CellLocation;
import android.telephony.ServiceState;
import android.util.Log;
import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.NetworkInfo;
import com.android.internal.telephony.gsm.PdpConnection;
import com.android.internal.telephony.test.SimulatedRadioControl;
import java.util.List;
public class PhoneProxy extends Handler implements Phone {
public final static Object lockForRadioTechnologyChange = new Object();
// private static boolean radioTechnologyChangeGsmToCdma = false;
// private static boolean radioTechnologyChangeCdmaToGsm = false;
private Phone mActivePhone;
private String mOutgoingPhone;
private CommandsInterface mCommandsInterface;
private IccSmsInterfaceManagerProxy mIccSmsInterfaceManagerProxy;
private IccPhoneBookInterfaceManagerProxy mIccPhoneBookInterfaceManagerProxy;
private PhoneSubInfoProxy mPhoneSubInfoProxy;
private static final int EVENT_RADIO_TECHNOLOGY_CHANGED = 1;
private static final String LOG_TAG = "PHONE";
//***** Class Methods
public PhoneProxy(Phone phone) {
mActivePhone = phone;
mIccSmsInterfaceManagerProxy = new IccSmsInterfaceManagerProxy(
phone.getIccSmsInterfaceManager());
mIccPhoneBookInterfaceManagerProxy = new IccPhoneBookInterfaceManagerProxy(
phone.getIccPhoneBookInterfaceManager());
mPhoneSubInfoProxy = new PhoneSubInfoProxy(phone.getPhoneSubInfo());
mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
mCommandsInterface.registerForRadioTechnologyChanged(
this, EVENT_RADIO_TECHNOLOGY_CHANGED, null);
}
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case EVENT_RADIO_TECHNOLOGY_CHANGED:
//switch Phone from CDMA to GSM or vice versa
mOutgoingPhone = ((PhoneBase)mActivePhone).getPhoneName();
logd("Switching phone from " + mOutgoingPhone + "Phone to " +
(mOutgoingPhone.equals("GSM") ? "CDMAPhone" : "GSMPhone") );
boolean oldPowerState = false; //old power state to off
if (mCommandsInterface.getRadioState().isOn()) {
oldPowerState = true;
logd("Setting Radio Power to Off");
mCommandsInterface.setRadioPower(false, null);
}
if(mOutgoingPhone.equals("GSM")) {
logd("Make a new CDMAPhone and destroy the old GSMPhone.");
((GSMPhone)mActivePhone).dispose();
Phone oldPhone = mActivePhone;
//Give the garbage collector a hint to start the garbage collection asap
// NOTE this has been disabled since radio technology change could happen during
// e.g. a multimedia playing and could slow the system. Tests needs to be done
// to see the effects of the GC call here when system is busy.
//System.gc();
mActivePhone = PhoneFactory.getCdmaPhone();
logd("Resetting Radio");
mCommandsInterface.setRadioPower(oldPowerState, null);
((GSMPhone)oldPhone).removeReferences();
oldPhone = null;
} else {
logd("Make a new GSMPhone and destroy the old CDMAPhone.");
((CDMAPhone)mActivePhone).dispose();
//mActivePhone = null;
Phone oldPhone = mActivePhone;
// Give the GC a hint to start the garbage collection asap
// NOTE this has been disabled since radio technology change could happen during
// e.g. a multimedia playing and could slow the system. Tests needs to be done
// to see the effects of the GC call here when system is busy.
//System.gc();
mActivePhone = PhoneFactory.getGsmPhone();
logd("Resetting Radio:");
mCommandsInterface.setRadioPower(oldPowerState, null);
((CDMAPhone)oldPhone).removeReferences();
oldPhone = null;
}
//Set the new interfaces in the proxy's
mIccSmsInterfaceManagerProxy.setmIccSmsInterfaceManager(
mActivePhone.getIccSmsInterfaceManager());
mIccPhoneBookInterfaceManagerProxy.setmIccPhoneBookInterfaceManager(
mActivePhone.getIccPhoneBookInterfaceManager());
mPhoneSubInfoProxy.setmPhoneSubInfo(this.mActivePhone.getPhoneSubInfo());
mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
//Send an Intent to the PhoneApp that we had a radio technology change
Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName());
ActivityManagerNative.broadcastStickyIntent(intent, null);
break;
default:
Log.e(LOG_TAG, "Error! This handler was not registered for this message type. Message: "
+ msg.what);
break;
}
super.handleMessage(msg);
}
private void logv(String msg) {
Log.v(LOG_TAG, "[PhoneProxy] " + msg);
}
private void logd(String msg) {
Log.d(LOG_TAG, "[PhoneProxy] " + msg);
}
private void logw(String msg) {
Log.w(LOG_TAG, "[PhoneProxy] " + msg);
}
private void loge(String msg) {
Log.e(LOG_TAG, "[PhoneProxy] " + msg);
}
public ServiceState getServiceState() {
return mActivePhone.getServiceState();
}
public CellLocation getCellLocation() {
return mActivePhone.getCellLocation();
}
public DataState getDataConnectionState() {
return mActivePhone.getDataConnectionState();
}
public DataActivityState getDataActivityState() {
return mActivePhone.getDataActivityState();
}
public Context getContext() {
return mActivePhone.getContext();
}
public void disableDnsCheck(boolean b) {
mActivePhone.disableDnsCheck(b);
}
public boolean isDnsCheckDisabled() {
return mActivePhone.isDnsCheckDisabled();
}
public State getState() {
return mActivePhone.getState();
}
public String getPhoneName() {
return mActivePhone.getPhoneName();
}
public String[] getActiveApnTypes() {
return mActivePhone.getActiveApnTypes();
}
public String getActiveApn() {
return mActivePhone.getActiveApn();
}
public int getSignalStrengthASU() {
return mActivePhone.getSignalStrengthASU();
}
public void registerForUnknownConnection(Handler h, int what, Object obj) {
mActivePhone.registerForUnknownConnection(h, what, obj);
}
public void unregisterForUnknownConnection(Handler h) {
mActivePhone.unregisterForUnknownConnection(h);
}
public void registerForPhoneStateChanged(Handler h, int what, Object obj) {
mActivePhone.registerForPhoneStateChanged(h, what, obj);
}
public void unregisterForPhoneStateChanged(Handler h) {
mActivePhone.unregisterForPhoneStateChanged(h);
}
public void registerForNewRingingConnection(Handler h, int what, Object obj) {
mActivePhone.registerForNewRingingConnection(h, what, obj);
}
public void unregisterForNewRingingConnection(Handler h) {
mActivePhone.unregisterForNewRingingConnection(h);
}
public void registerForIncomingRing(Handler h, int what, Object obj) {
mActivePhone.registerForIncomingRing(h, what, obj);
}
public void unregisterForIncomingRing(Handler h) {
mActivePhone.unregisterForIncomingRing(h);
}
public void registerForDisconnect(Handler h, int what, Object obj) {
mActivePhone.registerForDisconnect(h, what, obj);
}
public void unregisterForDisconnect(Handler h) {
mActivePhone.unregisterForDisconnect(h);
}
public void registerForMmiInitiate(Handler h, int what, Object obj) {
mActivePhone.registerForMmiInitiate(h, what, obj);
}
public void unregisterForMmiInitiate(Handler h) {
mActivePhone.unregisterForMmiInitiate(h);
}
public void registerForMmiComplete(Handler h, int what, Object obj) {
mActivePhone.registerForMmiComplete(h, what, obj);
}
public void unregisterForMmiComplete(Handler h) {
mActivePhone.unregisterForMmiComplete(h);
}
public List<? extends MmiCode> getPendingMmiCodes() {
return mActivePhone.getPendingMmiCodes();
}
public void sendUssdResponse(String ussdMessge) {
mActivePhone.sendUssdResponse(ussdMessge);
}
public void registerForServiceStateChanged(Handler h, int what, Object obj) {
mActivePhone.registerForServiceStateChanged(h, what, obj);
}
public void unregisterForServiceStateChanged(Handler h) {
mActivePhone.unregisterForServiceStateChanged(h);
}
public void registerForSuppServiceNotification(Handler h, int what, Object obj) {
mActivePhone.registerForSuppServiceNotification(h, what, obj);
}
public void unregisterForSuppServiceNotification(Handler h) {
mActivePhone.unregisterForSuppServiceNotification(h);
}
public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
mActivePhone.registerForSuppServiceFailed(h, what, obj);
}
public void unregisterForSuppServiceFailed(Handler h) {
mActivePhone.unregisterForSuppServiceFailed(h);
}
public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
mActivePhone.registerForInCallVoicePrivacyOn(h,what,obj);
}
public void unregisterForInCallVoicePrivacyOn(Handler h){
mActivePhone.unregisterForInCallVoicePrivacyOn(h);
}
public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
mActivePhone.registerForInCallVoicePrivacyOff(h,what,obj);
}
public void unregisterForInCallVoicePrivacyOff(Handler h){
mActivePhone.unregisterForInCallVoicePrivacyOff(h);
}
public boolean getIccRecordsLoaded() {
return mActivePhone.getIccRecordsLoaded();
}
public IccCard getIccCard() {
return mActivePhone.getIccCard();
}
public void acceptCall() throws CallStateException {
mActivePhone.acceptCall();
}
public void rejectCall() throws CallStateException {
mActivePhone.rejectCall();
}
public void switchHoldingAndActive() throws CallStateException {
mActivePhone.switchHoldingAndActive();
}
public boolean canConference() {
return mActivePhone.canConference();
}
public void conference() throws CallStateException {
mActivePhone.conference();
}
public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
mActivePhone.enableEnhancedVoicePrivacy(enable, onComplete);
}
public void getEnhancedVoicePrivacy(Message onComplete) {
mActivePhone.getEnhancedVoicePrivacy(onComplete);
}
public boolean canTransfer() {
return mActivePhone.canTransfer();
}
public void explicitCallTransfer() throws CallStateException {
mActivePhone.explicitCallTransfer();
}
public void clearDisconnected() {
mActivePhone.clearDisconnected();
}
public Call getForegroundCall() {
return mActivePhone.getForegroundCall();
}
public Call getBackgroundCall() {
return mActivePhone.getBackgroundCall();
}
public Call getRingingCall() {
return mActivePhone.getRingingCall();
}
public Connection dial(String dialString) throws CallStateException {
return mActivePhone.dial(dialString);
}
public boolean handlePinMmi(String dialString) {
return mActivePhone.handlePinMmi(dialString);
}
public boolean handleInCallMmiCommands(String command) throws CallStateException {
return mActivePhone.handleInCallMmiCommands(command);
}
public void sendDtmf(char c) {
mActivePhone.sendDtmf(c);
}
public void startDtmf(char c) {
mActivePhone.startDtmf(c);
}
public void stopDtmf() {
mActivePhone.stopDtmf();
}
public void setRadioPower(boolean power) {
mActivePhone.setRadioPower(power);
}
public boolean getMessageWaitingIndicator() {
return mActivePhone.getMessageWaitingIndicator();
}
public boolean getCallForwardingIndicator() {
return mActivePhone.getCallForwardingIndicator();
}
public String getLine1Number() {
return mActivePhone.getLine1Number();
}
public String getLine1AlphaTag() {
return mActivePhone.getLine1AlphaTag();
}
public void setLine1Number(String alphaTag, String number, Message onComplete) {
mActivePhone.setLine1Number(alphaTag, number, onComplete);
}
public String getVoiceMailNumber() {
return mActivePhone.getVoiceMailNumber();
}
public String getVoiceMailAlphaTag() {
return mActivePhone.getVoiceMailAlphaTag();
}
public void setVoiceMailNumber(String alphaTag,String voiceMailNumber,
Message onComplete) {
mActivePhone.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete);
}
public void getCallForwardingOption(int commandInterfaceCFReason,
Message onComplete) {
mActivePhone.getCallForwardingOption(commandInterfaceCFReason,
onComplete);
}
public void setCallForwardingOption(int commandInterfaceCFReason,
int commandInterfaceCFAction, String dialingNumber,
int timerSeconds, Message onComplete) {
mActivePhone.setCallForwardingOption(commandInterfaceCFReason,
commandInterfaceCFAction, dialingNumber, timerSeconds, onComplete);
}
public void getOutgoingCallerIdDisplay(Message onComplete) {
mActivePhone.getOutgoingCallerIdDisplay(onComplete);
}
public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
Message onComplete) {
mActivePhone.setOutgoingCallerIdDisplay(commandInterfaceCLIRMode,
onComplete);
}
public void getCallWaiting(Message onComplete) {
mActivePhone.getCallWaiting(onComplete);
}
public void setCallWaiting(boolean enable, Message onComplete) {
mActivePhone.setCallWaiting(enable, onComplete);
}
public void getAvailableNetworks(Message response) {
mActivePhone.getAvailableNetworks(response);
}
public void setNetworkSelectionModeAutomatic(Message response) {
mActivePhone.setNetworkSelectionModeAutomatic(response);
}
public void selectNetworkManually(NetworkInfo network, Message response) {
mActivePhone.selectNetworkManually(network, response);
}
public void setPreferredNetworkType(int networkType, Message response) {
mActivePhone.setPreferredNetworkType(networkType, response);
}
public void getPreferredNetworkType(Message response) {
mActivePhone.getPreferredNetworkType(response);
}
public void getNeighboringCids(Message response) {
mActivePhone.getNeighboringCids(response);
}
public void setOnPostDialCharacter(Handler h, int what, Object obj) {
mActivePhone.setOnPostDialCharacter(h, what, obj);
}
public void setMute(boolean muted) {
mActivePhone.setMute(muted);
}
public boolean getMute() {
return mActivePhone.getMute();
}
public void invokeOemRilRequestRaw(byte[] data, Message response) {
mActivePhone.invokeOemRilRequestRaw(data, response);
}
public void invokeOemRilRequestStrings(String[] strings, Message response) {
mActivePhone.invokeOemRilRequestStrings(strings, response);
}
/**
* @deprecated
*/
public void getPdpContextList(Message response) {
mActivePhone.getPdpContextList(response);
}
public void getDataCallList(Message response) {
mActivePhone.getDataCallList(response);
}
/**
* @deprecated
*/
public List<PdpConnection> getCurrentPdpList() {
return mActivePhone.getCurrentPdpList();
}
public List<DataConnection> getCurrentDataConnectionList() {
return mActivePhone.getCurrentDataConnectionList();
}
public void updateServiceLocation(Message response) {
mActivePhone.updateServiceLocation(response);
}
public void enableLocationUpdates() {
mActivePhone.enableLocationUpdates();
}
public void disableLocationUpdates() {
mActivePhone.disableLocationUpdates();
}
public void setUnitTestMode(boolean f) {
mActivePhone.setUnitTestMode(f);
}
public boolean getUnitTestMode() {
return mActivePhone.getUnitTestMode();
}
public void setBandMode(int bandMode, Message response) {
mActivePhone.setBandMode(bandMode, response);
}
public void queryAvailableBandMode(Message response) {
mActivePhone.queryAvailableBandMode(response);
}
public boolean getDataRoamingEnabled() {
return mActivePhone.getDataRoamingEnabled();
}
public void setDataRoamingEnabled(boolean enable) {
mActivePhone.setDataRoamingEnabled(enable);
}
public void queryCdmaRoamingPreference(Message response) {
mActivePhone.queryCdmaRoamingPreference(response);
}
public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
mActivePhone.setCdmaRoamingPreference(cdmaRoamingType, response);
}
public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
mActivePhone.setCdmaSubscription(cdmaSubscriptionType, response);
}
public SimulatedRadioControl getSimulatedRadioControl() {
return mActivePhone.getSimulatedRadioControl();
}
public boolean enableDataConnectivity() {
return mActivePhone.enableDataConnectivity();
}
public boolean disableDataConnectivity() {
return mActivePhone.disableDataConnectivity();
}
public int enableApnType(String type) {
return mActivePhone.enableApnType(type);
}
public int disableApnType(String type) {
return mActivePhone.disableApnType(type);
}
public boolean isDataConnectivityPossible() {
return mActivePhone.isDataConnectivityPossible();
}
public String getInterfaceName(String apnType) {
return mActivePhone.getInterfaceName(apnType);
}
public String getIpAddress(String apnType) {
return mActivePhone.getIpAddress(apnType);
}
public String getGateway(String apnType) {
return mActivePhone.getGateway(apnType);
}
public String[] getDnsServers(String apnType) {
return mActivePhone.getDnsServers(apnType);
}
public String getDeviceId() {
return mActivePhone.getDeviceId();
}
public String getDeviceSvn() {
return mActivePhone.getDeviceSvn();
}
public String getSubscriberId() {
return mActivePhone.getSubscriberId();
}
public String getIccSerialNumber() {
return mActivePhone.getIccSerialNumber();
}
public String getEsn() {
return mActivePhone.getEsn();
}
public String getMeid() {
return mActivePhone.getMeid();
}
public PhoneSubInfo getPhoneSubInfo(){
return mActivePhone.getPhoneSubInfo();
}
public IccSmsInterfaceManager getIccSmsInterfaceManager(){
return mActivePhone.getIccSmsInterfaceManager();
}
public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
return mActivePhone.getIccPhoneBookInterfaceManager();
}
public void setTTYModeEnabled(boolean enable, Message onComplete) {
mActivePhone.setTTYModeEnabled(enable, onComplete);
}
public void queryTTYModeEnabled(Message onComplete) {
mActivePhone.queryTTYModeEnabled(onComplete);
}
public void activateCellBroadcastSms(int activate, Message response) {
mActivePhone.activateCellBroadcastSms(activate, response);
}
public void getCellBroadcastSmsConfig(Message response) {
mActivePhone.getCellBroadcastSmsConfig(response);
}
public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
mActivePhone.setCellBroadcastSmsConfig(configValuesArray, response);
}
public void notifyDataActivity() {
mActivePhone.notifyDataActivity();
}
}

Some files were not shown because too many files have changed in this diff Show More