am 3b7c09b4: LayoutLib: Correctly resolve ?attr/foo [DO NOT MERGE]
* commit '3b7c09b4336f421c489523c10278ecfbfb0708a7':
LayoutLib: Correctly resolve ?attr/foo [DO NOT MERGE]
diff --git a/Android.mk b/Android.mk
index 4d567df..b9157fe 100644
--- a/Android.mk
+++ b/Android.mk
@@ -38,7 +38,6 @@
core/java/android/content/EventLogTags.logtags \
core/java/android/speech/tts/EventLogTags.logtags \
core/java/android/webkit/EventLogTags.logtags \
- telephony/java/com/android/internal/telephony/EventLogTags.logtags \
# The following filters out code we are temporarily not including at all.
# TODO: Move AWT and beans (and associated harmony code) back into libcore.
@@ -204,12 +203,10 @@
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/IIccPhoneBook.aidl \
- telephony/java/com/android/internal/telephony/ISms.aidl \
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
+ telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
- telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
voip/java/android/net/sip/ISipSession.aidl \
voip/java/android/net/sip/ISipSessionListener.aidl \
voip/java/android/net/sip/ISipService.aidl
@@ -339,7 +336,9 @@
include external/junit/Common.mk
non_base_dirs := \
- ../../external/apache-http/src/org/apache/http
+ ../../external/apache-http/src/org/apache/http \
+ ../opt/telephony/src/java/android/telephony \
+ ../opt/telephony/src/java/android/telephony/gsm \
# These are relative to frameworks/base
dirs_to_check_apis := \
@@ -390,6 +389,8 @@
core \
ext \
framework \
+ mms-common \
+ telephony-common \
framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES
framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 0d8a7cd..61e5b4c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -133,6 +133,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/accessibilityservice/IAccessibilityServiceClient.P)
$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/media/video/Disco*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/current.txt b/api/current.txt
index bc97e81..b5fd82b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20282,6 +20282,7 @@
public class CdmaCellLocation extends android.telephony.CellLocation {
ctor public CdmaCellLocation();
ctor public CdmaCellLocation(android.os.Bundle);
+ method public static double convertQuartSecToDecDegrees(int);
method public void fillInNotifierBundle(android.os.Bundle);
method public int getBaseStationId();
method public int getBaseStationLatitude();
@@ -21525,9 +21526,9 @@
method public static java.lang.String formatElapsedTime(long);
method public static java.lang.String formatElapsedTime(java.lang.StringBuilder, long);
method public static final java.lang.CharSequence formatSameDayTime(long, long, int, int);
- method public static java.lang.String getAMPMString(int);
- method public static java.lang.String getDayOfWeekString(int, int);
- method public static java.lang.String getMonthString(int, int);
+ method public static deprecated java.lang.String getAMPMString(int);
+ method public static deprecated java.lang.String getDayOfWeekString(int, int);
+ method public static deprecated java.lang.String getMonthString(int, int);
method public static java.lang.CharSequence getRelativeDateTimeString(android.content.Context, long, long, long, int);
method public static java.lang.CharSequence getRelativeTimeSpanString(long);
method public static java.lang.CharSequence getRelativeTimeSpanString(long, long, long);
@@ -21535,24 +21536,24 @@
method public static java.lang.CharSequence getRelativeTimeSpanString(android.content.Context, long, boolean);
method public static java.lang.CharSequence getRelativeTimeSpanString(android.content.Context, long);
method public static boolean isToday(long);
- field public static final java.lang.String ABBREV_MONTH_FORMAT = "%b";
+ field public static final deprecated java.lang.String ABBREV_MONTH_FORMAT = "%b";
field public static final java.lang.String ABBREV_WEEKDAY_FORMAT = "%a";
field public static final long DAY_IN_MILLIS = 86400000L; // 0x5265c00L
- field public static final int FORMAT_12HOUR = 64; // 0x40
- field public static final int FORMAT_24HOUR = 128; // 0x80
+ field public static final deprecated int FORMAT_12HOUR = 64; // 0x40
+ field public static final deprecated int FORMAT_24HOUR = 128; // 0x80
field public static final int FORMAT_ABBREV_ALL = 524288; // 0x80000
field public static final int FORMAT_ABBREV_MONTH = 65536; // 0x10000
field public static final int FORMAT_ABBREV_RELATIVE = 262144; // 0x40000
field public static final int FORMAT_ABBREV_TIME = 16384; // 0x4000
field public static final int FORMAT_ABBREV_WEEKDAY = 32768; // 0x8000
- field public static final int FORMAT_CAP_AMPM = 256; // 0x100
- field public static final int FORMAT_CAP_MIDNIGHT = 4096; // 0x1000
- field public static final int FORMAT_CAP_NOON = 1024; // 0x400
- field public static final int FORMAT_CAP_NOON_MIDNIGHT = 5120; // 0x1400
+ field public static final deprecated int FORMAT_CAP_AMPM = 256; // 0x100
+ field public static final deprecated int FORMAT_CAP_MIDNIGHT = 4096; // 0x1000
+ field public static final deprecated int FORMAT_CAP_NOON = 1024; // 0x400
+ field public static final deprecated int FORMAT_CAP_NOON_MIDNIGHT = 5120; // 0x1400
field public static final int FORMAT_NO_MIDNIGHT = 2048; // 0x800
field public static final int FORMAT_NO_MONTH_DAY = 32; // 0x20
field public static final int FORMAT_NO_NOON = 512; // 0x200
- field public static final int FORMAT_NO_NOON_MIDNIGHT = 2560; // 0xa00
+ field public static final deprecated int FORMAT_NO_NOON_MIDNIGHT = 2560; // 0xa00
field public static final int FORMAT_NO_YEAR = 8; // 0x8
field public static final int FORMAT_NUMERIC_DATE = 131072; // 0x20000
field public static final int FORMAT_SHOW_DATE = 16; // 0x10
@@ -21561,12 +21562,12 @@
field public static final int FORMAT_SHOW_YEAR = 4; // 0x4
field public static final deprecated int FORMAT_UTC = 8192; // 0x2000
field public static final long HOUR_IN_MILLIS = 3600000L; // 0x36ee80L
- field public static final java.lang.String HOUR_MINUTE_24 = "%H:%M";
- field public static final int LENGTH_LONG = 10; // 0xa
- field public static final int LENGTH_MEDIUM = 20; // 0x14
- field public static final int LENGTH_SHORT = 30; // 0x1e
- field public static final int LENGTH_SHORTER = 40; // 0x28
- field public static final int LENGTH_SHORTEST = 50; // 0x32
+ field public static final deprecated java.lang.String HOUR_MINUTE_24 = "%H:%M";
+ field public static final deprecated int LENGTH_LONG = 10; // 0xa
+ field public static final deprecated int LENGTH_MEDIUM = 20; // 0x14
+ field public static final deprecated int LENGTH_SHORT = 30; // 0x1e
+ field public static final deprecated int LENGTH_SHORTER = 40; // 0x28
+ field public static final deprecated int LENGTH_SHORTEST = 50; // 0x32
field public static final long MINUTE_IN_MILLIS = 60000L; // 0xea60L
field public static final java.lang.String MONTH_DAY_FORMAT = "%-d";
field public static final java.lang.String MONTH_FORMAT = "%B";
@@ -21577,8 +21578,8 @@
field public static final java.lang.String YEAR_FORMAT = "%Y";
field public static final java.lang.String YEAR_FORMAT_TWO_DIGITS = "%g";
field public static final long YEAR_IN_MILLIS = 31449600000L; // 0x7528ad000L
- field public static final int[] sameMonthTable;
- field public static final int[] sameYearTable;
+ field public static final deprecated int[] sameMonthTable;
+ field public static final deprecated int[] sameYearTable;
}
public final class Formatter {
@@ -24096,6 +24097,7 @@
method public long getDrawingTime();
method public boolean getFilterTouchesWhenObscured();
method public boolean getFitsSystemWindows();
+ method public void getFocusRect(android.graphics.Rect);
method public java.util.ArrayList<android.view.View> getFocusables(int);
method public void getFocusedRect(android.graphics.Rect);
method public boolean getGlobalVisibleRect(android.graphics.Rect, android.graphics.Point);
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index f277339..3e722ea 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -34,6 +34,12 @@
LOCAL_STATIC_LIBRARIES := \
libdiskusage
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_C_INCLUDES += external/libselinux/include
+LOCAL_SHARED_LIBRARIES += libselinux
+LOCAL_CFLAGS := -DHAVE_SELINUX
+endif # HAVE_SELINUX
+
LOCAL_MODULE := installd
LOCAL_MODULE_TAGS := optional
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index a509156..41e7b8d 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -17,6 +17,10 @@
#include "installd.h"
#include <diskusage/dirsize.h>
+#ifdef HAVE_SELINUX
+#include <selinux/android.h>
+#endif
+
/* Directory records that are used in execution of commands. */
dir_rec_t android_data_dir;
dir_rec_t android_asec_dir;
@@ -72,12 +76,31 @@
return -errno;
}
+#ifdef HAVE_SELINUX
+ if (selinux_android_setfilecon(libdir, pkgname, AID_SYSTEM) < 0) {
+ ALOGE("cannot setfilecon dir '%s': %s\n", libdir, strerror(errno));
+ unlink(libdir);
+ unlink(pkgdir);
+ return -errno;
+ }
+#endif
+
if (chown(pkgdir, uid, gid) < 0) {
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
unlink(libdir);
unlink(pkgdir);
return -errno;
}
+
+#ifdef HAVE_SELINUX
+ if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+ ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+ unlink(libdir);
+ unlink(pkgdir);
+ return -errno;
+ }
+#endif
+
return 0;
}
@@ -175,6 +198,15 @@
unlink(pkgdir);
return -errno;
}
+
+#ifdef HAVE_SELINUX
+ if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+ ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+ unlink(pkgdir);
+ return -errno;
+ }
+#endif
+
return 0;
}
@@ -366,12 +398,18 @@
ALOGE("failed to chgrp '%s': %s\n", pkgpath, strerror(errno));
return -1;
}
-
if (chmod(pkgpath, S_IRUSR|S_IWUSR|S_IRGRP) < 0) {
ALOGE("failed to chmod '%s': %s\n", pkgpath, strerror(errno));
return -1;
}
+#ifdef HAVE_SELINUX
+ if (selinux_android_setfilecon(pkgpath, pkgname, s.st_uid) < 0) {
+ ALOGE("cannot setfilecon dir '%s': %s\n", pkgpath, strerror(errno));
+ return -1;
+ }
+#endif
+
return 0;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7242029..b7e0683 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4728,13 +4728,14 @@
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
- if (sMainThreadHandler == null) {
- sMainThreadHandler = new Handler();
- }
ActivityThread thread = new ActivityThread();
thread.attach(false);
+ if (sMainThreadHandler == null) {
+ sMainThreadHandler = thread.getHandler();
+ }
+
AsyncTask.init();
if (false) {
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index dd9ea26..3a67cec 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -64,11 +64,12 @@
}
/**
- * Called when the application is starting, before any other application
- * objects have been created. Implementations should be as quick as
- * possible (for example using lazy initialization of state) since the time
- * spent in this function directly impacts the performance of starting the
- * first activity, service, or receiver in a process.
+ * Called when the application is starting, before any activity, service,
+ * or receiver objects (excluding content providers) have been created.
+ * Implementations should be as quick as possible (for example using
+ * lazy initialization of state) since the time spent in this function
+ * directly impacts the performance of starting the first activity,
+ * service, or receiver in a process.
* If you override this method, be sure to call super.onCreate().
*/
public void onCreate() {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 3e726e0..8e6278d 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -385,6 +385,7 @@
case SCHEDULE_LOW_MEMORY_TRANSACTION:
{
+ data.enforceInterface(IApplicationThread.descriptor);
scheduleLowMemory();
return true;
}
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 17700f9..0b1c524 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -344,6 +344,13 @@
*/
public static final int NETWORK_WIFI = 1 << 1;
+ /**
+ * Bit flag for {@link #setAllowedNetworkTypes} corresponding to
+ * {@link ConnectivityManager#TYPE_BLUETOOTH}.
+ * @hide
+ */
+ public static final int NETWORK_BLUETOOTH = 1 << 2;
+
private Uri mUri;
private Uri mDestinationUri;
private List<Pair<String, String>> mRequestHeaders = new ArrayList<Pair<String, String>>();
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 615e8ce..201d7b2 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -17,7 +17,6 @@
package android.app;
import android.content.SharedPreferences;
-import android.os.FileUtils.FileStatus;
import android.os.FileUtils;
import android.os.Looper;
import android.util.Log;
@@ -45,6 +44,11 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
+import libcore.io.ErrnoException;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import libcore.io.StructStat;
+
final class SharedPreferencesImpl implements SharedPreferences {
private static final String TAG = "SharedPreferencesImpl";
private static final boolean DEBUG = false;
@@ -105,26 +109,32 @@
}
Map map = null;
- FileStatus stat = new FileStatus();
- if (FileUtils.getFileStatus(mFile.getPath(), stat) && mFile.canRead()) {
- try {
- BufferedInputStream str = new BufferedInputStream(
- new FileInputStream(mFile), 16*1024);
- map = XmlUtils.readMapXml(str);
- str.close();
- } catch (XmlPullParserException e) {
- Log.w(TAG, "getSharedPreferences", e);
- } catch (FileNotFoundException e) {
- Log.w(TAG, "getSharedPreferences", e);
- } catch (IOException e) {
- Log.w(TAG, "getSharedPreferences", e);
+ StructStat stat = null;
+ try {
+ stat = Libcore.os.stat(mFile.getPath());
+ if (mFile.canRead()) {
+ BufferedInputStream str = null;
+ try {
+ str = new BufferedInputStream(
+ new FileInputStream(mFile), 16*1024);
+ map = XmlUtils.readMapXml(str);
+ } catch (XmlPullParserException e) {
+ Log.w(TAG, "getSharedPreferences", e);
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "getSharedPreferences", e);
+ } catch (IOException e) {
+ Log.w(TAG, "getSharedPreferences", e);
+ } finally {
+ IoUtils.closeQuietly(str);
+ }
}
+ } catch (ErrnoException e) {
}
mLoaded = true;
if (map != null) {
mMap = map;
- mStatTimestamp = stat.mtime;
- mStatSize = stat.size;
+ mStatTimestamp = stat.st_mtime;
+ mStatSize = stat.st_size;
} else {
mMap = new HashMap<String, Object>();
}
@@ -155,12 +165,21 @@
return false;
}
}
- FileStatus stat = new FileStatus();
- if (!FileUtils.getFileStatus(mFile.getPath(), stat)) {
+
+ final StructStat stat;
+ try {
+ /*
+ * Metadata operations don't usually count as a block guard
+ * violation, but we explicitly want this one.
+ */
+ BlockGuard.getThreadPolicy().onReadFromDisk();
+ stat = Libcore.os.stat(mFile.getPath());
+ } catch (ErrnoException e) {
return true;
}
+
synchronized (this) {
- return mStatTimestamp != stat.mtime || mStatSize != stat.size;
+ return mStatTimestamp != stat.st_mtime || mStatSize != stat.st_size;
}
}
@@ -577,12 +596,14 @@
FileUtils.sync(str);
str.close();
ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
- FileStatus stat = new FileStatus();
- if (FileUtils.getFileStatus(mFile.getPath(), stat)) {
+ try {
+ final StructStat stat = Libcore.os.stat(mFile.getPath());
synchronized (this) {
- mStatTimestamp = stat.mtime;
- mStatSize = stat.size;
+ mStatTimestamp = stat.st_mtime;
+ mStatSize = stat.st_size;
}
+ } catch (ErrnoException e) {
+ // Do nothing
}
// Writing was successful, delete the backup file if there is one.
mBackupFile.delete();
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
old mode 100644
new mode 100755
index 4ed0766..0b58396
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1008,13 +1008,15 @@
/**
* Ask the user date be wiped. This will cause the device to reboot,
* erasing all user data while next booting up. External storage such
- * as SD cards will not be erased.
+ * as SD cards will be also erased if the flag {@link #WIPE_EXTERNAL_STORAGE}
+ * is set.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA} to be able to call
* this method; if it has not, a security exception will be thrown.
*
- * @param flags Bit mask of additional options: currently must be 0.
+ * @param flags Bit mask of additional options: currently 0 and
+ * {@link #WIPE_EXTERNAL_STORAGE} are supported.
*/
public void wipeData(int flags) {
if (mService != null) {
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index c9603bf..020f051 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -304,6 +304,25 @@
}
}
+ @Override
+ protected void onQuitting() {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ mBroadcastReceiver = null;
+ mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
+ mBluetoothProfileServiceListener = null;
+ mOutgoingHandsfree = null;
+ mPbap = null;
+ mPbapService.close();
+ mPbapService = null;
+ mIncomingHid = null;
+ mOutgoingHid = null;
+ mIncomingHandsfree = null;
+ mOutgoingHandsfree = null;
+ mIncomingA2dp = null;
+ mOutgoingA2dp = null;
+ mBondedDevice = null;
+ }
+
private class BondedDevice extends State {
@Override
public void enter() {
@@ -416,26 +435,6 @@
case TRANSITION_TO_STABLE:
// ignore.
break;
- case SM_QUIT_CMD:
- mContext.unregisterReceiver(mBroadcastReceiver);
- mBroadcastReceiver = null;
- mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
- mBluetoothProfileServiceListener = null;
- mOutgoingHandsfree = null;
- mPbap = null;
- mPbapService.close();
- mPbapService = null;
- mIncomingHid = null;
- mOutgoingHid = null;
- mIncomingHandsfree = null;
- mOutgoingHandsfree = null;
- mIncomingA2dp = null;
- mOutgoingA2dp = null;
- mBondedDevice = null;
- // There is a problem in the State Machine code
- // where things are not cleaned up properly, when quit message
- // is handled so return NOT_HANDLED as a workaround.
- return NOT_HANDLED;
default:
return NOT_HANDLED;
}
@@ -1341,6 +1340,15 @@
return mDevice;
}
+ /**
+ * Quit the state machine, only to be called by BluetoothService.
+ *
+ * @hide
+ */
+ public void doQuit() {
+ this.quit();
+ }
+
private void log(String message) {
if (DBG) {
Log.i(TAG, "Device:" + mDevice + " Message:" + message);
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 226e107..7a9fc65 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -26,6 +26,7 @@
import android.accounts.Account;
import android.accounts.AccountAndUser;
+import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
@@ -337,6 +338,7 @@
private int mNextHistoryId = 0;
private SparseArray<Boolean> mMasterSyncAutomatically = new SparseArray<Boolean>();
+ private boolean mDefaultMasterSyncAutomatically;
private OnSyncRequestListener mSyncRequestListener;
@@ -346,6 +348,9 @@
mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
+ mDefaultMasterSyncAutomatically = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_syncstorageengine_masterSyncAutomatically);
+
File systemDir = new File(dataDir, "system");
File syncDir = new File(systemDir, "sync");
syncDir.mkdirs();
@@ -781,7 +786,7 @@
public boolean getMasterSyncAutomatically(int userId) {
synchronized (mAuthorities) {
Boolean auto = mMasterSyncAutomatically.get(userId);
- return auto == null ? true : auto;
+ return auto == null ? mDefaultMasterSyncAutomatically : auto;
}
}
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index fb04817..e7ff92d 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -424,6 +424,9 @@
if (mSelfObserver != null && mSelfObserverRegistered == true) {
mContentResolver.unregisterContentObserver(mSelfObserver);
}
+ try {
+ if (!mClosed) close();
+ } catch(Exception e) { }
}
/**
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 4d9077f..829620b 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -26,6 +26,7 @@
import android.os.Looper;
import android.os.Message;
import android.util.Log;
+import android.text.TextUtils;
import android.view.Surface;
import android.view.SurfaceHolder;
@@ -34,7 +35,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.StringTokenizer;
import java.util.concurrent.locks.ReentrantLock;
/**
@@ -1905,7 +1905,7 @@
private HashMap<String, String> mMap;
private Parameters() {
- mMap = new HashMap<String, String>();
+ mMap = new HashMap<String, String>(64);
}
/**
@@ -1929,7 +1929,7 @@
* semi-colon delimited key-value pairs
*/
public String flatten() {
- StringBuilder flattened = new StringBuilder();
+ StringBuilder flattened = new StringBuilder(128);
for (String k : mMap.keySet()) {
flattened.append(k);
flattened.append("=");
@@ -1952,9 +1952,9 @@
public void unflatten(String flattened) {
mMap.clear();
- StringTokenizer tokenizer = new StringTokenizer(flattened, ";");
- while (tokenizer.hasMoreElements()) {
- String kv = tokenizer.nextToken();
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(';');
+ splitter.setString(flattened);
+ for (String kv : splitter) {
int pos = kv.indexOf('=');
if (pos == -1) {
continue;
@@ -3488,11 +3488,11 @@
private ArrayList<String> split(String str) {
if (str == null) return null;
- // Use StringTokenizer because it is faster than split.
- StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(str);
ArrayList<String> substrings = new ArrayList<String>();
- while (tokenizer.hasMoreElements()) {
- substrings.add(tokenizer.nextToken());
+ for (String s : splitter) {
+ substrings.add(s);
}
return substrings;
}
@@ -3502,11 +3502,11 @@
private ArrayList<Integer> splitInt(String str) {
if (str == null) return null;
- StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(str);
ArrayList<Integer> substrings = new ArrayList<Integer>();
- while (tokenizer.hasMoreElements()) {
- String token = tokenizer.nextToken();
- substrings.add(Integer.parseInt(token));
+ for (String s : splitter) {
+ substrings.add(Integer.parseInt(s));
}
if (substrings.size() == 0) return null;
return substrings;
@@ -3515,11 +3515,11 @@
private void splitInt(String str, int[] output) {
if (str == null) return;
- StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(str);
int index = 0;
- while (tokenizer.hasMoreElements()) {
- String token = tokenizer.nextToken();
- output[index++] = Integer.parseInt(token);
+ for (String s : splitter) {
+ output[index++] = Integer.parseInt(s);
}
}
@@ -3527,11 +3527,11 @@
private void splitFloat(String str, float[] output) {
if (str == null) return;
- StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(str);
int index = 0;
- while (tokenizer.hasMoreElements()) {
- String token = tokenizer.nextToken();
- output[index++] = Float.parseFloat(token);
+ for (String s : splitter) {
+ output[index++] = Float.parseFloat(s);
}
}
@@ -3558,10 +3558,11 @@
private ArrayList<Size> splitSize(String str) {
if (str == null) return null;
- StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(str);
ArrayList<Size> sizeList = new ArrayList<Size>();
- while (tokenizer.hasMoreElements()) {
- Size size = strToSize(tokenizer.nextToken());
+ for (String s : splitter) {
+ Size size = strToSize(s);
if (size != null) sizeList.add(size);
}
if (sizeList.size() == 0) return null;
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 397a12a..cc3e34f 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -163,8 +163,21 @@
mRegisteredForPreDhcpNotification = true;
}
+ /**
+ * Quit the DhcpStateMachine.
+ *
+ * @hide
+ */
+ public void doQuit() {
+ quit();
+ }
+
class DefaultState extends State {
@Override
+ public void exit() {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ }
+ @Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
switch (message.what) {
@@ -172,10 +185,6 @@
Log.e(TAG, "Error! Failed to handle a DHCP renewal on " + mInterfaceName);
mDhcpRenewWakeLock.release();
break;
- case SM_QUIT_CMD:
- mContext.unregisterReceiver(mBroadcastReceiver);
- //let parent kill the state machine
- return NOT_HANDLED;
default:
Log.e(TAG, "Error! unhandled message " + message);
break;
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index 28bd289..0cc78c9 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -223,7 +223,7 @@
mIface = iface;
mNMService.setInterfaceUp(iface);
InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
- mLinkUp = config.isActive();
+ mLinkUp = config.hasFlag("up");
if (config != null && mHwAddr == null) {
mHwAddr = config.getHardwareAddress();
if (mHwAddr != null) {
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 57f8d48..d59fa6a 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -16,11 +16,6 @@
package android.net;
-import static com.android.internal.telephony.DataConnectionTracker.CMD_SET_POLICY_DATA_ENABLE;
-import static com.android.internal.telephony.DataConnectionTracker.CMD_SET_USER_DATA_ENABLE;
-import static com.android.internal.telephony.DataConnectionTracker.DISABLED;
-import static com.android.internal.telephony.DataConnectionTracker.ENABLED;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -37,9 +32,9 @@
import android.text.TextUtils;
import android.util.Slog;
-import com.android.internal.telephony.DataConnectionTracker;
+import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.AsyncChannel;
@@ -59,7 +54,7 @@
private static final boolean DBG = false;
private static final boolean VDBG = false;
- private Phone.DataState mMobileDataState;
+ private PhoneConstants.DataState mMobileDataState;
private ITelephony mPhoneService;
private String mApnType;
@@ -108,10 +103,10 @@
IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
- filter.addAction(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
+ filter.addAction(DctConstants.ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
mContext.registerReceiver(new MobileDataStateReceiver(), filter);
- mMobileDataState = Phone.DataState.DISCONNECTED;
+ mMobileDataState = PhoneConstants.DataState.DISCONNECTED;
}
static class MdstHandler extends Handler {
@@ -180,7 +175,7 @@
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(TelephonyIntents.
ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
- String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY);
+ String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
if (VDBG) {
log(String.format("Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED"
+ "mApnType=%s %s received apnType=%s", mApnType,
@@ -189,20 +184,29 @@
if (!TextUtils.equals(apnType, mApnType)) {
return;
}
- mNetworkInfo.setSubtype(TelephonyManager.getDefault().getNetworkType(),
- TelephonyManager.getDefault().getNetworkTypeName());
- Phone.DataState state = Enum.valueOf(Phone.DataState.class,
- intent.getStringExtra(Phone.STATE_KEY));
- String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY);
- String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
- mNetworkInfo.setRoaming(intent.getBooleanExtra(Phone.DATA_NETWORK_ROAMING_KEY,
- false));
+
+ int oldSubtype = mNetworkInfo.getSubtype();
+ int newSubType = TelephonyManager.getDefault().getNetworkType();
+ String subTypeName = TelephonyManager.getDefault().getNetworkTypeName();
+ mNetworkInfo.setSubtype(newSubType, subTypeName);
+ if (newSubType != oldSubtype && mNetworkInfo.isConnected()) {
+ Message msg = mTarget.obtainMessage(EVENT_NETWORK_SUBTYPE_CHANGED,
+ oldSubtype, 0, mNetworkInfo);
+ msg.sendToTarget();
+ }
+
+ PhoneConstants.DataState state = Enum.valueOf(PhoneConstants.DataState.class,
+ intent.getStringExtra(PhoneConstants.STATE_KEY));
+ String reason = intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY);
+ String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
+ mNetworkInfo.setRoaming(intent.getBooleanExtra(
+ PhoneConstants.DATA_NETWORK_ROAMING_KEY, false));
if (VDBG) {
log(mApnType + " setting isAvailable to " +
- intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,false));
+ intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY,false));
}
- mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY,
- false));
+ mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(
+ PhoneConstants.NETWORK_UNAVAILABLE_KEY, false));
if (DBG) {
log("Received state=" + state + ", old=" + mMobileDataState +
@@ -232,13 +236,13 @@
break;
case CONNECTED:
mLinkProperties = intent.getParcelableExtra(
- Phone.DATA_LINK_PROPERTIES_KEY);
+ PhoneConstants.DATA_LINK_PROPERTIES_KEY);
if (mLinkProperties == null) {
loge("CONNECTED event did not supply link properties.");
mLinkProperties = new LinkProperties();
}
mLinkCapabilities = intent.getParcelableExtra(
- Phone.DATA_LINK_CAPABILITIES_KEY);
+ PhoneConstants.DATA_LINK_CAPABILITIES_KEY);
if (mLinkCapabilities == null) {
loge("CONNECTED event did not supply link capabilities.");
mLinkCapabilities = new LinkCapabilities();
@@ -248,8 +252,9 @@
}
} else {
// There was no state change. Check if LinkProperties has been updated.
- if (TextUtils.equals(reason, Phone.REASON_LINK_PROPERTIES_CHANGED)) {
- mLinkProperties = intent.getParcelableExtra(Phone.DATA_LINK_PROPERTIES_KEY);
+ if (TextUtils.equals(reason, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
+ mLinkProperties = intent.getParcelableExtra(
+ PhoneConstants.DATA_LINK_PROPERTIES_KEY);
if (mLinkProperties == null) {
loge("No link property in LINK_PROPERTIES change event.");
mLinkProperties = new LinkProperties();
@@ -264,7 +269,7 @@
}
} else if (intent.getAction().
equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
- String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY);
+ String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
if (!TextUtils.equals(apnType, mApnType)) {
if (DBG) {
log(String.format(
@@ -273,17 +278,18 @@
}
return;
}
- String reason = intent.getStringExtra(Phone.FAILURE_REASON_KEY);
- String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
+ String reason = intent.getStringExtra(PhoneConstants.FAILURE_REASON_KEY);
+ String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
if (DBG) {
log("Received " + intent.getAction() +
" broadcast" + reason == null ? "" : "(" + reason + ")");
}
setDetailedState(DetailedState.FAILED, reason, apnName);
- } else if (intent.getAction().
- equals(DataConnectionTracker.ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) {
+ } else if (intent.getAction().equals(DctConstants
+ .ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) {
if (VDBG) log(mApnType + " got ACTION_DATA_CONNECTION_TRACKER_MESSENGER");
- mMessenger = intent.getParcelableExtra(DataConnectionTracker.EXTRA_MESSENGER);
+ mMessenger =
+ intent.getParcelableExtra(DctConstants.EXTRA_MESSENGER);
AsyncChannel ac = new AsyncChannel();
ac.connect(mContext, MobileDataStateTracker.this.mHandler, mMessenger);
} else {
@@ -332,6 +338,9 @@
case TelephonyManager.NETWORK_TYPE_HSPA:
networkTypeStr = "hspa";
break;
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ networkTypeStr = "hspap";
+ break;
case TelephonyManager.NETWORK_TYPE_CDMA:
networkTypeStr = "cdma";
break;
@@ -369,7 +378,7 @@
*/
public boolean teardown() {
setTeardownRequested(true);
- return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
+ return (setEnableApn(mApnType, false) != PhoneConstants.APN_REQUEST_FAILED);
}
/**
@@ -418,17 +427,17 @@
boolean retValue = false; //connected or expect to be?
setTeardownRequested(false);
switch (setEnableApn(mApnType, true)) {
- case Phone.APN_ALREADY_ACTIVE:
+ case PhoneConstants.APN_ALREADY_ACTIVE:
// need to set self to CONNECTING so the below message is handled.
retValue = true;
break;
- case Phone.APN_REQUEST_STARTED:
+ case PhoneConstants.APN_REQUEST_STARTED:
// set IDLE here , avoid the following second FAILED not sent out
mNetworkInfo.setDetailedState(DetailedState.IDLE, null, null);
retValue = true;
break;
- case Phone.APN_REQUEST_FAILED:
- case Phone.APN_TYPE_NOT_AVAILABLE:
+ case PhoneConstants.APN_REQUEST_FAILED:
+ case PhoneConstants.APN_TYPE_NOT_AVAILABLE:
break;
default:
loge("Error in reconnect - unexpected response.");
@@ -470,7 +479,8 @@
if (DBG) log("setUserDataEnable: E enabled=" + enabled);
final AsyncChannel channel = mDataConnectionTrackerAc;
if (channel != null) {
- channel.sendMessage(CMD_SET_USER_DATA_ENABLE, enabled ? ENABLED : DISABLED);
+ channel.sendMessage(DctConstants.CMD_SET_USER_DATA_ENABLE,
+ enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
mUserDataEnabled = enabled;
}
if (VDBG) log("setUserDataEnable: X enabled=" + enabled);
@@ -481,7 +491,8 @@
if (DBG) log("setPolicyDataEnable(enabled=" + enabled + ")");
final AsyncChannel channel = mDataConnectionTrackerAc;
if (channel != null) {
- channel.sendMessage(CMD_SET_POLICY_DATA_ENABLE, enabled ? ENABLED : DISABLED);
+ channel.sendMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE,
+ enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
mPolicyDataEnabled = enabled;
}
}
@@ -491,12 +502,12 @@
* @param met
*/
public void setDependencyMet(boolean met) {
- Bundle bundle = Bundle.forPair(DataConnectionTracker.APN_TYPE_KEY, mApnType);
+ Bundle bundle = Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType);
try {
if (DBG) log("setDependencyMet: E met=" + met);
Message msg = Message.obtain();
- msg.what = DataConnectionTracker.CMD_SET_DEPENDENCY_MET;
- msg.arg1 = (met ? DataConnectionTracker.ENABLED : DataConnectionTracker.DISABLED);
+ msg.what = DctConstants.CMD_SET_DEPENDENCY_MET;
+ msg.arg1 = (met ? DctConstants.ENABLED : DctConstants.DISABLED);
msg.setData(bundle);
mDataConnectionTrackerAc.sendMessage(msg);
if (VDBG) log("setDependencyMet: X met=" + met);
@@ -546,27 +557,27 @@
}
loge("Could not " + (enable ? "enable" : "disable") + " APN type \"" + apnType + "\"");
- return Phone.APN_REQUEST_FAILED;
+ return PhoneConstants.APN_REQUEST_FAILED;
}
public static String networkTypeToApnType(int netType) {
switch(netType) {
case ConnectivityManager.TYPE_MOBILE:
- return Phone.APN_TYPE_DEFAULT; // TODO - use just one of these
+ return PhoneConstants.APN_TYPE_DEFAULT; // TODO - use just one of these
case ConnectivityManager.TYPE_MOBILE_MMS:
- return Phone.APN_TYPE_MMS;
+ return PhoneConstants.APN_TYPE_MMS;
case ConnectivityManager.TYPE_MOBILE_SUPL:
- return Phone.APN_TYPE_SUPL;
+ return PhoneConstants.APN_TYPE_SUPL;
case ConnectivityManager.TYPE_MOBILE_DUN:
- return Phone.APN_TYPE_DUN;
+ return PhoneConstants.APN_TYPE_DUN;
case ConnectivityManager.TYPE_MOBILE_HIPRI:
- return Phone.APN_TYPE_HIPRI;
+ return PhoneConstants.APN_TYPE_HIPRI;
case ConnectivityManager.TYPE_MOBILE_FOTA:
- return Phone.APN_TYPE_FOTA;
+ return PhoneConstants.APN_TYPE_FOTA;
case ConnectivityManager.TYPE_MOBILE_IMS:
- return Phone.APN_TYPE_IMS;
+ return PhoneConstants.APN_TYPE_IMS;
case ConnectivityManager.TYPE_MOBILE_CBS:
- return Phone.APN_TYPE_CBS;
+ return PhoneConstants.APN_TYPE_CBS;
default:
sloge("Error mapping networkType " + netType + " to apnType.");
return null;
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 7df0193..0d6dcd6 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -69,6 +69,12 @@
public static final int EVENT_RESTORE_DEFAULT_NETWORK = 6;
/**
+ * msg.what = EVENT_NETWORK_SUBTYPE_CHANGED
+ * msg.obj = NetworkInfo object
+ */
+ public static final int EVENT_NETWORK_SUBTYPE_CHANGED = 7;
+
+ /**
* -------------------------------------------------------------
* Control Interface
* -------------------------------------------------------------
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index fb5263d..65d3f2b 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -329,7 +329,7 @@
throw new IllegalArgumentException("Bad address");
}
- mAddresses.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
+ mAddresses.append(' ' + address.getHostAddress() + '/' + prefixLength);
return this;
}
diff --git a/core/java/android/net/arp/ArpPeer.java b/core/java/android/net/arp/ArpPeer.java
index 8e666bc..6ba1e7c 100644
--- a/core/java/android/net/arp/ArpPeer.java
+++ b/core/java/android/net/arp/ArpPeer.java
@@ -53,9 +53,11 @@
mInterfaceName = interfaceName;
mMyAddr = myAddr;
- for (int i = 0; i < MAC_ADDR_LENGTH; i++) {
- mMyMac[i] = (byte) Integer.parseInt(mac.substring(
- i*3, (i*3) + 2), 16);
+ if (mac != null) {
+ for (int i = 0; i < MAC_ADDR_LENGTH; i++) {
+ mMyMac[i] = (byte) Integer.parseInt(mac.substring(
+ i*3, (i*3) + 2), 16);
+ }
}
if (myAddr instanceof Inet6Address || peer instanceof Inet6Address) {
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 6c1445d..0941d71 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -28,9 +28,6 @@
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
-import libcore.io.Os;
-import libcore.io.StructStat;
-
/**
* Tools for managing files. Not for public consumption.
* @hide
@@ -50,60 +47,12 @@
public static final int S_IROTH = 00004;
public static final int S_IWOTH = 00002;
public static final int S_IXOTH = 00001;
-
-
- /**
- * File status information. This class maps directly to the POSIX stat structure.
- * @deprecated use {@link StructStat} instead.
- * @hide
- */
- @Deprecated
- public static final class FileStatus {
- public int dev;
- public int ino;
- public int mode;
- public int nlink;
- public int uid;
- public int gid;
- public int rdev;
- public long size;
- public int blksize;
- public long blocks;
- public long atime;
- public long mtime;
- public long ctime;
- }
-
- /**
- * Get the status for the given path. This is equivalent to the POSIX stat(2) system call.
- * @param path The path of the file to be stat'd.
- * @param status Optional argument to fill in. It will only fill in the status if the file
- * exists.
- * @return true if the file exists and false if it does not exist. If you do not have
- * permission to stat the file, then this method will return false.
- * @deprecated use {@link Os#stat(String)} instead.
- */
- @Deprecated
- public static boolean getFileStatus(String path, FileStatus status) {
- StrictMode.noteDiskRead();
- return getFileStatusNative(path, status);
- }
-
- private static native boolean getFileStatusNative(String path, FileStatus status);
/** Regular expression for safe filenames: no spaces or metacharacters */
private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");
public static native int setPermissions(String file, int mode, int uid, int gid);
- /**
- * @deprecated use {@link Os#stat(String)} instead.
- */
- @Deprecated
- public static native int getPermissions(String file, int[] outPermissions);
-
- public static native int setUMask(int mask);
-
/** returns the FAT file system volume ID for the volume mounted
* at the given mount point, or -1 for failure
* @param mountPoint point for FAT volume
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 8eaeb1d..6ab4dc1 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -359,6 +359,7 @@
* @param gids Additional group-ids associated with the process.
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
+ * @param seInfo null-ok SE Android information for the new process.
* @param zygoteArgs Additional arguments to supply to the zygote process.
*
* @return An object that describes the result of the attempt to start the process.
@@ -370,10 +371,11 @@
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int targetSdkVersion,
+ String seInfo,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
- debugFlags, targetSdkVersion, zygoteArgs);
+ debugFlags, targetSdkVersion, seInfo, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -536,6 +538,7 @@
* new process should setgroup() to.
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
+ * @param seInfo null-ok SE Android information for the new process.
* @param extraArgs Additional arguments to supply to the zygote process.
* @return An object that describes the result of the attempt to start the process.
* @throws ZygoteStartFailedEx if process start failed for any reason
@@ -545,6 +548,7 @@
final int uid, final int gid,
final int[] gids,
int debugFlags, int targetSdkVersion,
+ String seInfo,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
@@ -595,6 +599,10 @@
argsForZygote.add("--nice-name=" + niceName);
}
+ if (seInfo != null) {
+ argsForZygote.add("--seinfo=" + seInfo);
+ }
+
argsForZygote.add(processClass);
if (extraArgs != null) {
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
new file mode 100644
index 0000000..c05a974
--- /dev/null
+++ b/core/java/android/os/SELinux.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.util.Slog;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.FileDescriptor;
+
+/**
+ * This class provides access to the centralized jni bindings for
+ * SELinux interaction.
+ * {@hide}
+ */
+public class SELinux {
+
+ private static final String TAG = "SELinux";
+
+ /**
+ * Determine whether SELinux is disabled or enabled.
+ * @return a boolean indicating whether SELinux is enabled.
+ */
+ public static final native boolean isSELinuxEnabled();
+
+ /**
+ * Determine whether SELinux is permissive or enforcing.
+ * @return a boolean indicating whether SELinux is enforcing.
+ */
+ public static final native boolean isSELinuxEnforced();
+
+ /**
+ * Set whether SELinux is permissive or enforcing.
+ * @param boolean representing whether to set SELinux to enforcing
+ * @return a boolean representing whether the desired mode was set
+ */
+ public static final native boolean setSELinuxEnforce(boolean value);
+
+ /**
+ * Sets the security context for newly created file objects.
+ * @param context a security context given as a String.
+ * @return a boolean indicating whether the operation succeeded.
+ */
+ public static final native boolean setFSCreateContext(String context);
+
+ /**
+ * Change the security context of an existing file object.
+ * @param path representing the path of file object to relabel.
+ * @param con new security context given as a String.
+ * @return a boolean indicating whether the operation succeeded.
+ */
+ public static final native boolean setFileContext(String path, String context);
+
+ /**
+ * Get the security context of a file object.
+ * @param path the pathname of the file object.
+ * @return a security context given as a String.
+ */
+ public static final native String getFileContext(String path);
+
+ /**
+ * Get the security context of a peer socket.
+ * @param fd FileDescriptor class of the peer socket.
+ * @return a String representing the peer socket security context.
+ */
+ public static final native String getPeerContext(FileDescriptor fd);
+
+ /**
+ * Gets the security context of the current process.
+ * @return a String representing the security context of the current process.
+ */
+ public static final native String getContext();
+
+ /**
+ * Gets the security context of a given process id.
+ * Use of this function is discouraged for Binder transactions.
+ * Use Binder.getCallingSecctx() instead.
+ * @param pid an int representing the process id to check.
+ * @return a String representing the security context of the given pid.
+ */
+ public static final native String getPidContext(int pid);
+
+ /**
+ * Gets a list of the SELinux boolean names.
+ * @return an array of strings containing the SELinux boolean names.
+ */
+ public static final native String[] getBooleanNames();
+
+ /**
+ * Gets the value for the given SELinux boolean name.
+ * @param String The name of the SELinux boolean.
+ * @return a boolean indicating whether the SELinux boolean is set.
+ */
+ public static final native boolean getBooleanValue(String name);
+
+ /**
+ * Sets the value for the given SELinux boolean name.
+ * @param String The name of the SELinux boolean.
+ * @param Boolean The new value of the SELinux boolean.
+ * @return a boolean indicating whether or not the operation succeeded.
+ */
+ public static final native boolean setBooleanValue(String name, boolean value);
+
+ /**
+ * Check permissions between two security contexts.
+ * @param scon The source or subject security context.
+ * @param tcon The target or object security context.
+ * @param tclass The object security class name.
+ * @param perm The permission name.
+ * @return a boolean indicating whether permission was granted.
+ */
+ public static final native boolean checkSELinuxAccess(String scon, String tcon, String tclass, String perm);
+
+ /**
+ * Restores a file to its default SELinux security context.
+ * If the system is not compiled with SELinux, then {@code true}
+ * is automatically returned.
+ * If SELinux is compiled in, but disabled, then {@code true} is
+ * returned.
+ *
+ * @param pathname The pathname of the file to be relabeled.
+ * @return a boolean indicating whether the relabeling succeeded.
+ * @exception NullPointerException if the pathname is a null object.
+ */
+ public static boolean restorecon(String pathname) throws NullPointerException {
+ if (pathname == null) { throw new NullPointerException(); }
+ return native_restorecon(pathname);
+ }
+
+ /**
+ * Restores a file to its default SELinux security context.
+ * If the system is not compiled with SELinux, then {@code true}
+ * is automatically returned.
+ * If SELinux is compiled in, but disabled, then {@code true} is
+ * returned.
+ *
+ * @param pathname The pathname of the file to be relabeled.
+ * @return a boolean indicating whether the relabeling succeeded.
+ */
+ private static native boolean native_restorecon(String pathname);
+
+ /**
+ * Restores a file to its default SELinux security context.
+ * If the system is not compiled with SELinux, then {@code true}
+ * is automatically returned.
+ * If SELinux is compiled in, but disabled, then {@code true} is
+ * returned.
+ *
+ * @param file The File object representing the path to be relabeled.
+ * @return a boolean indicating whether the relabeling succeeded.
+ * @exception NullPointerException if the file is a null object.
+ */
+ public static boolean restorecon(File file) throws NullPointerException {
+ try {
+ return native_restorecon(file.getCanonicalPath());
+ } catch (IOException e) {
+ Slog.e(TAG, "Error getting canonical path. Restorecon failed for " +
+ file.getPath(), e);
+ return false;
+ }
+ }
+}
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 912bfdf..ca7fdba 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -16,59 +16,77 @@
package android.os;
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.StructStatFs;
+
/**
- * Retrieve overall information about the space on a filesystem. This is a
- * Wrapper for Unix statfs().
+ * Retrieve overall information about the space on a filesystem. This is a
+ * wrapper for Unix statfs().
*/
public class StatFs {
- /**
- * Construct a new StatFs for looking at the stats of the
- * filesystem at <var>path</var>. Upon construction, the stat of
- * the file system will be performed, and the values retrieved available
- * from the methods on this class.
- *
- * @param path A path in the desired file system to state.
- */
- public StatFs(String path) { native_setup(path); }
-
- /**
- * Perform a restat of the file system referenced by this object. This
- * is the same as re-constructing the object with the same file system
- * path, and the new stat values are available upon return.
- */
- public void restat(String path) { native_restat(path); }
-
- @Override
- protected void finalize() { native_finalize(); }
+ private StructStatFs mStat;
/**
- * The size, in bytes, of a block on the file system. This corresponds
- * to the Unix statfs.f_bsize field.
+ * Construct a new StatFs for looking at the stats of the filesystem at
+ * {@code path}. Upon construction, the stat of the file system will be
+ * performed, and the values retrieved available from the methods on this
+ * class.
+ *
+ * @param path path in the desired file system to stat.
*/
- public native int getBlockSize();
+ public StatFs(String path) {
+ mStat = doStat(path);
+ }
+
+ private static StructStatFs doStat(String path) {
+ try {
+ return Libcore.os.statfs(path);
+ } catch (ErrnoException e) {
+ throw new IllegalArgumentException("Invalid path: " + path, e);
+ }
+ }
/**
- * The total number of blocks on the file system. This corresponds
- * to the Unix statfs.f_blocks field.
+ * Perform a restat of the file system referenced by this object. This is
+ * the same as re-constructing the object with the same file system path,
+ * and the new stat values are available upon return.
*/
- public native int getBlockCount();
+ public void restat(String path) {
+ mStat = doStat(path);
+ }
+
+ /**
+ * The size, in bytes, of a block on the file system. This corresponds to
+ * the Unix {@code statfs.f_bsize} field.
+ */
+ public int getBlockSize() {
+ return (int) mStat.f_bsize;
+ }
+
+ /**
+ * The total number of blocks on the file system. This corresponds to the
+ * Unix {@code statfs.f_blocks} field.
+ */
+ public int getBlockCount() {
+ return (int) mStat.f_blocks;
+ }
/**
* The total number of blocks that are free on the file system, including
- * reserved blocks (that are not available to normal applications). This
- * corresponds to the Unix statfs.f_bfree field. Most applications will
- * want to use {@link #getAvailableBlocks()} instead.
+ * reserved blocks (that are not available to normal applications). This
+ * corresponds to the Unix {@code statfs.f_bfree} field. Most applications
+ * will want to use {@link #getAvailableBlocks()} instead.
*/
- public native int getFreeBlocks();
+ public int getFreeBlocks() {
+ return (int) mStat.f_bfree;
+ }
/**
* The number of blocks that are free on the file system and available to
- * applications. This corresponds to the Unix statfs.f_bavail field.
+ * applications. This corresponds to the Unix {@code statfs.f_bavail} field.
*/
- public native int getAvailableBlocks();
-
- private int mNativeContext;
- private native void native_restat(String path);
- private native void native_setup(String path);
- private native void native_finalize();
+ public int getAvailableBlocks() {
+ return (int) mStat.f_bavail;
+ }
}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index ce213fb..f682abe 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -407,17 +407,17 @@
}
/**
- * Enable detection of disk reads.
+ * Enable detection of slow calls.
*/
public Builder detectCustomSlowCalls() {
return enable(DETECT_CUSTOM);
}
/**
- * Enable detection of disk reads.
+ * Disable detection of slow calls.
*/
public Builder permitCustomSlowCalls() {
- return enable(DETECT_CUSTOM);
+ return disable(DETECT_CUSTOM);
}
/**
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index cb6c1dc..8a20a6e 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -56,7 +56,7 @@
/*
* Our internal MountService binder reference
*/
- private IMountService mMountService;
+ final private IMountService mMountService;
/*
* The looper target for callbacks
@@ -304,8 +304,6 @@
return;
}
mTgtLooper = tgtLooper;
- mBinderListener = new MountServiceBinderListener();
- mMountService.registerListener(mBinderListener);
}
@@ -322,6 +320,15 @@
}
synchronized (mListeners) {
+ if (mBinderListener == null ) {
+ try {
+ mBinderListener = new MountServiceBinderListener();
+ mMountService.registerListener(mBinderListener);
+ } catch (RemoteException rex) {
+ Log.e(TAG, "Register mBinderListener failed");
+ return;
+ }
+ }
mListeners.add(new ListenerDelegate(listener));
}
}
@@ -347,7 +354,15 @@
break;
}
}
- }
+ if (mListeners.size() == 0 && mBinderListener != null) {
+ try {
+ mMountService.unregisterListener(mBinderListener);
+ } catch (RemoteException rex) {
+ Log.e(TAG, "Unregister mBinderListener failed");
+ return;
+ }
+ }
+ }
}
/**
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 7824724..22b68bc 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -18,7 +18,7 @@
package android.provider;
import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.PhoneConstants;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -267,14 +267,14 @@
// If this is a private number then set the number to Private, otherwise check
// if the number field is empty and set the number to Unavailable
- if (presentation == Connection.PRESENTATION_RESTRICTED) {
+ if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
number = CallerInfo.PRIVATE_NUMBER;
if (ci != null) ci.name = "";
- } else if (presentation == Connection.PRESENTATION_PAYPHONE) {
+ } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
number = CallerInfo.PAYPHONE_NUMBER;
if (ci != null) ci.name = "";
} else if (TextUtils.isEmpty(number)
- || presentation == Connection.PRESENTATION_UNKNOWN) {
+ || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
number = CallerInfo.UNKNOWN_NUMBER;
if (ci != null) ci.name = "";
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
old mode 100644
new mode 100755
index 8e123ac..e7b0579
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8362,7 +8362,7 @@
// Line contains the query string - now search for it at the start of tokens.
List<String> lineTokens = new ArrayList<String>();
List<Integer> tokenOffsets = new ArrayList<Integer>();
- split(contentLine.trim(), lineTokens, tokenOffsets);
+ split(contentLine, lineTokens, tokenOffsets);
// As we find matches against the query, we'll populate this list with the marked
// (or unchanged) tokens.
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
deleted file mode 100755
index 19d8d5c..0000000
--- a/core/java/android/provider/Telephony.java
+++ /dev/null
@@ -1,2037 +0,0 @@
-/*
- * 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.provider;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.sqlite.SqliteWrapper;
-import android.net.Uri;
-import android.os.Environment;
-import android.telephony.SmsMessage;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Patterns;
-
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The Telephony provider contains data related to phone operation.
- *
- * @hide
- */
-public final class Telephony {
- private static final String TAG = "Telephony";
- private static final boolean DEBUG = true;
- private static final boolean LOCAL_LOGV = false;
-
- // Constructor
- public Telephony() {
- }
-
- /**
- * Base columns for tables that contain text based SMSs.
- */
- public interface TextBasedSmsColumns {
- /**
- * The type of the message
- * <P>Type: INTEGER</P>
- */
- public static final String TYPE = "type";
-
- public static final int MESSAGE_TYPE_ALL = 0;
- public static final int MESSAGE_TYPE_INBOX = 1;
- public static final int MESSAGE_TYPE_SENT = 2;
- public static final int MESSAGE_TYPE_DRAFT = 3;
- public static final int MESSAGE_TYPE_OUTBOX = 4;
- public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages
- public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send later
-
-
- /**
- * The thread ID of the message
- * <P>Type: INTEGER</P>
- */
- public static final String THREAD_ID = "thread_id";
-
- /**
- * The address of the other party
- * <P>Type: TEXT</P>
- */
- public static final String ADDRESS = "address";
-
- /**
- * The person ID of the sender
- * <P>Type: INTEGER (long)</P>
- */
- public static final String PERSON_ID = "person";
-
- /**
- * The date the message was received
- * <P>Type: INTEGER (long)</P>
- */
- public static final String DATE = "date";
-
- /**
- * The date the message was sent
- * <P>Type: INTEGER (long)</P>
- */
- public static final String DATE_SENT = "date_sent";
-
- /**
- * Has the message been read
- * <P>Type: INTEGER (boolean)</P>
- */
- public static final String READ = "read";
-
- /**
- * Indicates whether this message has been seen by the user. The "seen" flag will be
- * used to figure out whether we need to throw up a statusbar notification or not.
- */
- public static final String SEEN = "seen";
-
- /**
- * The TP-Status value for the message, or -1 if no status has
- * been received
- */
- public static final String STATUS = "status";
-
- public static final int STATUS_NONE = -1;
- public static final int STATUS_COMPLETE = 0;
- public static final int STATUS_PENDING = 32;
- public static final int STATUS_FAILED = 64;
-
- /**
- * The subject of the message, if present
- * <P>Type: TEXT</P>
- */
- public static final String SUBJECT = "subject";
-
- /**
- * The body of the message
- * <P>Type: TEXT</P>
- */
- public static final String BODY = "body";
-
- /**
- * The id of the sender of the conversation, if present
- * <P>Type: INTEGER (reference to item in content://contacts/people)</P>
- */
- public static final String PERSON = "person";
-
- /**
- * The protocol identifier code
- * <P>Type: INTEGER</P>
- */
- public static final String PROTOCOL = "protocol";
-
- /**
- * Whether the <code>TP-Reply-Path</code> bit was set on this message
- * <P>Type: BOOLEAN</P>
- */
- public static final String REPLY_PATH_PRESENT = "reply_path_present";
-
- /**
- * The service center (SC) through which to send the message, if present
- * <P>Type: TEXT</P>
- */
- public static final String SERVICE_CENTER = "service_center";
-
- /**
- * Has the message been locked?
- * <P>Type: INTEGER (boolean)</P>
- */
- public static final String LOCKED = "locked";
-
- /**
- * Error code associated with sending or receiving this message
- * <P>Type: INTEGER</P>
- */
- public static final String ERROR_CODE = "error_code";
-
- /**
- * Meta data used externally.
- * <P>Type: TEXT</P>
- */
- public static final String META_DATA = "meta_data";
-}
-
- /**
- * Contains all text based SMS messages.
- */
- public static final class Sms implements BaseColumns, TextBasedSmsColumns {
- public static final Cursor query(ContentResolver cr, String[] projection) {
- return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
- }
-
- public static final Cursor query(ContentResolver cr, String[] projection,
- String where, String orderBy) {
- return cr.query(CONTENT_URI, projection, where,
- null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
- }
-
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://sms");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
-
- /**
- * Add an SMS to the given URI.
- *
- * @param resolver the content resolver to use
- * @param uri the URI to add the message to
- * @param address the address of the sender
- * @param body the body of the message
- * @param subject the psuedo-subject of the message
- * @param date the timestamp for the message
- * @param read true if the message has been read, false if not
- * @param deliveryReport true if a delivery report was requested, false if not
- * @return the URI for the new message
- */
- public static Uri addMessageToUri(ContentResolver resolver,
- Uri uri, String address, String body, String subject,
- Long date, boolean read, boolean deliveryReport) {
- return addMessageToUri(resolver, uri, address, body, subject,
- date, read, deliveryReport, -1L);
- }
-
- /**
- * Add an SMS to the given URI with thread_id specified.
- *
- * @param resolver the content resolver to use
- * @param uri the URI to add the message to
- * @param address the address of the sender
- * @param body the body of the message
- * @param subject the psuedo-subject of the message
- * @param date the timestamp for the message
- * @param read true if the message has been read, false if not
- * @param deliveryReport true if a delivery report was requested, false if not
- * @param threadId the thread_id of the message
- * @return the URI for the new message
- */
- public static Uri addMessageToUri(ContentResolver resolver,
- Uri uri, String address, String body, String subject,
- Long date, boolean read, boolean deliveryReport, long threadId) {
- ContentValues values = new ContentValues(7);
-
- values.put(ADDRESS, address);
- if (date != null) {
- values.put(DATE, date);
- }
- values.put(READ, read ? Integer.valueOf(1) : Integer.valueOf(0));
- values.put(SUBJECT, subject);
- values.put(BODY, body);
- if (deliveryReport) {
- values.put(STATUS, STATUS_PENDING);
- }
- if (threadId != -1L) {
- values.put(THREAD_ID, threadId);
- }
- return resolver.insert(uri, values);
- }
-
- /**
- * Move a message to the given folder.
- *
- * @param context the context to use
- * @param uri the message to move
- * @param folder the folder to move to
- * @return true if the operation succeeded
- */
- public static boolean moveMessageToFolder(Context context,
- Uri uri, int folder, int error) {
- if (uri == null) {
- return false;
- }
-
- boolean markAsUnread = false;
- boolean markAsRead = false;
- switch(folder) {
- case MESSAGE_TYPE_INBOX:
- case MESSAGE_TYPE_DRAFT:
- break;
- case MESSAGE_TYPE_OUTBOX:
- case MESSAGE_TYPE_SENT:
- markAsRead = true;
- break;
- case MESSAGE_TYPE_FAILED:
- case MESSAGE_TYPE_QUEUED:
- markAsUnread = true;
- break;
- default:
- return false;
- }
-
- ContentValues values = new ContentValues(3);
-
- values.put(TYPE, folder);
- if (markAsUnread) {
- values.put(READ, Integer.valueOf(0));
- } else if (markAsRead) {
- values.put(READ, Integer.valueOf(1));
- }
- values.put(ERROR_CODE, error);
-
- return 1 == SqliteWrapper.update(context, context.getContentResolver(),
- uri, values, null, null);
- }
-
- /**
- * Returns true iff the folder (message type) identifies an
- * outgoing message.
- */
- public static boolean isOutgoingFolder(int messageType) {
- return (messageType == MESSAGE_TYPE_FAILED)
- || (messageType == MESSAGE_TYPE_OUTBOX)
- || (messageType == MESSAGE_TYPE_SENT)
- || (messageType == MESSAGE_TYPE_QUEUED);
- }
-
- /**
- * Contains all text based SMS messages in the SMS app's inbox.
- */
- public static final class Inbox implements BaseColumns, TextBasedSmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://sms/inbox");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
-
- /**
- * Add an SMS to the Draft box.
- *
- * @param resolver the content resolver to use
- * @param address the address of the sender
- * @param body the body of the message
- * @param subject the psuedo-subject of the message
- * @param date the timestamp for the message
- * @param read true if the message has been read, false if not
- * @return the URI for the new message
- */
- public static Uri addMessage(ContentResolver resolver,
- String address, String body, String subject, Long date,
- boolean read) {
- return addMessageToUri(resolver, CONTENT_URI, address, body,
- subject, date, read, false);
- }
- }
-
- /**
- * Contains all sent text based SMS messages in the SMS app's.
- */
- public static final class Sent implements BaseColumns, TextBasedSmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://sms/sent");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
-
- /**
- * Add an SMS to the Draft box.
- *
- * @param resolver the content resolver to use
- * @param address the address of the sender
- * @param body the body of the message
- * @param subject the psuedo-subject of the message
- * @param date the timestamp for the message
- * @return the URI for the new message
- */
- public static Uri addMessage(ContentResolver resolver,
- String address, String body, String subject, Long date) {
- return addMessageToUri(resolver, CONTENT_URI, address, body,
- subject, date, true, false);
- }
- }
-
- /**
- * Contains all sent text based SMS messages in the SMS app's.
- */
- public static final class Draft implements BaseColumns, TextBasedSmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://sms/draft");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
-
- /**
- * Add an SMS to the Draft box.
- *
- * @param resolver the content resolver to use
- * @param address the address of the sender
- * @param body the body of the message
- * @param subject the psuedo-subject of the message
- * @param date the timestamp for the message
- * @return the URI for the new message
- */
- public static Uri addMessage(ContentResolver resolver,
- String address, String body, String subject, Long date) {
- return addMessageToUri(resolver, CONTENT_URI, address, body,
- subject, date, true, false);
- }
-
- /**
- * Save over an existing draft message.
- *
- * @param resolver the content resolver to use
- * @param uri of existing message
- * @param body the new body for the draft message
- * @return true is successful, false otherwise
- */
- public static boolean saveMessage(ContentResolver resolver,
- Uri uri, String body) {
- ContentValues values = new ContentValues(2);
- values.put(BODY, body);
- values.put(DATE, System.currentTimeMillis());
- return resolver.update(uri, values, null, null) == 1;
- }
- }
-
- /**
- * Contains all pending outgoing text based SMS messages.
- */
- public static final class Outbox implements BaseColumns, TextBasedSmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://sms/outbox");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
-
- /**
- * Add an SMS to the Out box.
- *
- * @param resolver the content resolver to use
- * @param address the address of the sender
- * @param body the body of the message
- * @param subject the psuedo-subject of the message
- * @param date the timestamp for the message
- * @param deliveryReport whether a delivery report was requested for the message
- * @return the URI for the new message
- */
- public static Uri addMessage(ContentResolver resolver,
- String address, String body, String subject, Long date,
- boolean deliveryReport, long threadId) {
- return addMessageToUri(resolver, CONTENT_URI, address, body,
- subject, date, true, deliveryReport, threadId);
- }
- }
-
- /**
- * Contains all sent text-based SMS messages in the SMS app's.
- */
- public static final class Conversations
- implements BaseColumns, TextBasedSmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://sms/conversations");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
-
- /**
- * The first 45 characters of the body of the message
- * <P>Type: TEXT</P>
- */
- public static final String SNIPPET = "snippet";
-
- /**
- * The number of messages in the conversation
- * <P>Type: INTEGER</P>
- */
- public static final String MESSAGE_COUNT = "msg_count";
- }
-
- /**
- * Contains info about SMS related Intents that are broadcast.
- */
- public static final class Intents {
- /**
- * Set by BroadcastReceiver. Indicates the message was handled
- * successfully.
- */
- public static final int RESULT_SMS_HANDLED = 1;
-
- /**
- * Set by BroadcastReceiver. Indicates a generic error while
- * processing the message.
- */
- public static final int RESULT_SMS_GENERIC_ERROR = 2;
-
- /**
- * Set by BroadcastReceiver. Indicates insufficient memory to store
- * the message.
- */
- public static final int RESULT_SMS_OUT_OF_MEMORY = 3;
-
- /**
- * Set by BroadcastReceiver. Indicates the message, while
- * possibly valid, is of a format or encoding that is not
- * supported.
- */
- public static final int RESULT_SMS_UNSUPPORTED = 4;
-
- /**
- * Broadcast Action: A new text based SMS message has been received
- * by the device. The intent will have the following extra
- * values:</p>
- *
- * <ul>
- * <li><em>pdus</em> - An Object[] od byte[]s containing the PDUs
- * that make up the message.</li>
- * </ul>
- *
- * <p>The extra values can be extracted using
- * {@link #getMessagesFromIntent(Intent)}.</p>
- *
- * <p>If a BroadcastReceiver encounters an error while processing
- * this intent it should set the result code appropriately.</p>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SMS_RECEIVED_ACTION =
- "android.provider.Telephony.SMS_RECEIVED";
-
- /**
- * Broadcast Action: A new data based SMS message has been received
- * by the device. The intent will have the following extra
- * values:</p>
- *
- * <ul>
- * <li><em>pdus</em> - An Object[] of byte[]s containing the PDUs
- * that make up the message.</li>
- * </ul>
- *
- * <p>The extra values can be extracted using
- * {@link #getMessagesFromIntent(Intent)}.</p>
- *
- * <p>If a BroadcastReceiver encounters an error while processing
- * this intent it should set the result code appropriately.</p>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String DATA_SMS_RECEIVED_ACTION =
- "android.intent.action.DATA_SMS_RECEIVED";
-
- /**
- * Broadcast Action: A new WAP PUSH message has been received by the
- * device. The intent will have the following extra
- * values:</p>
- *
- * <ul>
- * <li><em>transactionId (Integer)</em> - The WAP transaction ID</li>
- * <li><em>pduType (Integer)</em> - The WAP PDU type</li>
- * <li><em>header (byte[])</em> - The header of the message</li>
- * <li><em>data (byte[])</em> - The data payload of the message</li>
- * <li><em>contentTypeParameters (HashMap<String,String>)</em>
- * - Any parameters associated with the content type
- * (decoded from the WSP Content-Type header)</li>
- * </ul>
- *
- * <p>If a BroadcastReceiver encounters an error while processing
- * this intent it should set the result code appropriately.</p>
- *
- * <p>The contentTypeParameters extra value is map of content parameters keyed by
- * their names.</p>
- *
- * <p>If any unassigned well-known parameters are encountered, the key of the map will
- * be 'unassigned/0x...', where '...' is the hex value of the unassigned parameter. If
- * a parameter has No-Value the value in the map will be null.</p>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String WAP_PUSH_RECEIVED_ACTION =
- "android.provider.Telephony.WAP_PUSH_RECEIVED";
-
- /**
- * Broadcast Action: A new Cell Broadcast message has been received
- * by the device. The intent will have the following extra
- * values:</p>
- *
- * <ul>
- * <li><em>message</em> - An SmsCbMessage object containing the broadcast message
- * data. This is not an emergency alert, so ETWS and CMAS data will be null.</li>
- * </ul>
- *
- * <p>The extra values can be extracted using
- * {@link #getMessagesFromIntent(Intent)}.</p>
- *
- * <p>If a BroadcastReceiver encounters an error while processing
- * this intent it should set the result code appropriately.</p>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SMS_CB_RECEIVED_ACTION =
- "android.provider.Telephony.SMS_CB_RECEIVED";
-
- /**
- * Broadcast Action: A new Emergency Broadcast message has been received
- * by the device. The intent will have the following extra
- * values:</p>
- *
- * <ul>
- * <li><em>message</em> - An SmsCbMessage object containing the broadcast message
- * data, including ETWS or CMAS warning notification info if present.</li>
- * </ul>
- *
- * <p>The extra values can be extracted using
- * {@link #getMessagesFromIntent(Intent)}.</p>
- *
- * <p>If a BroadcastReceiver encounters an error while processing
- * this intent it should set the result code appropriately.</p>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
- "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
-
- /**
- * Broadcast Action: A new CDMA SMS has been received containing Service Category
- * Program Data (updates the list of enabled broadcast channels). The intent will
- * have the following extra values:</p>
- *
- * <ul>
- * <li><em>operations</em> - An array of CdmaSmsCbProgramData objects containing
- * the service category operations (add/delete/clear) to perform.</li>
- * </ul>
- *
- * <p>The extra values can be extracted using
- * {@link #getMessagesFromIntent(Intent)}.</p>
- *
- * <p>If a BroadcastReceiver encounters an error while processing
- * this intent it should set the result code appropriately.</p>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION =
- "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED";
-
- /**
- * Broadcast Action: The SIM storage for SMS messages is full. If
- * space is not freed, messages targeted for the SIM (class 2) may
- * not be saved.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SIM_FULL_ACTION =
- "android.provider.Telephony.SIM_FULL";
-
- /**
- * Broadcast Action: An incoming SMS has been rejected by the
- * telephony framework. This intent is sent in lieu of any
- * of the RECEIVED_ACTION intents. The intent will have the
- * following extra value:</p>
- *
- * <ul>
- * <li><em>result</em> - An int result code, eg,
- * <code>{@link #RESULT_SMS_OUT_OF_MEMORY}</code>,
- * indicating the error returned to the network.</li>
- * </ul>
-
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SMS_REJECTED_ACTION =
- "android.provider.Telephony.SMS_REJECTED";
-
- /**
- * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
- * {@link #DATA_SMS_RECEIVED_ACTION} intent.
- *
- * @param intent the intent to read from
- * @return an array of SmsMessages for the PDUs
- */
- public static SmsMessage[] getMessagesFromIntent(
- Intent intent) {
- Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
- String format = intent.getStringExtra("format");
- byte[][] pduObjs = new byte[messages.length][];
-
- for (int i = 0; i < messages.length; i++) {
- pduObjs[i] = (byte[]) messages[i];
- }
- byte[][] pdus = new byte[pduObjs.length][];
- int pduCount = pdus.length;
- SmsMessage[] msgs = new SmsMessage[pduCount];
- for (int i = 0; i < pduCount; i++) {
- pdus[i] = pduObjs[i];
- msgs[i] = SmsMessage.createFromPdu(pdus[i], format);
- }
- return msgs;
- }
- }
- }
-
- /**
- * Base columns for tables that contain MMSs.
- */
- public interface BaseMmsColumns extends BaseColumns {
-
- public static final int MESSAGE_BOX_ALL = 0;
- public static final int MESSAGE_BOX_INBOX = 1;
- public static final int MESSAGE_BOX_SENT = 2;
- public static final int MESSAGE_BOX_DRAFTS = 3;
- public static final int MESSAGE_BOX_OUTBOX = 4;
-
- /**
- * The date the message was received.
- * <P>Type: INTEGER (long)</P>
- */
- public static final String DATE = "date";
-
- /**
- * The date the message was sent.
- * <P>Type: INTEGER (long)</P>
- */
- public static final String DATE_SENT = "date_sent";
-
- /**
- * The box which the message belong to, for example, MESSAGE_BOX_INBOX.
- * <P>Type: INTEGER</P>
- */
- public static final String MESSAGE_BOX = "msg_box";
-
- /**
- * Has the message been read.
- * <P>Type: INTEGER (boolean)</P>
- */
- public static final String READ = "read";
-
- /**
- * Indicates whether this message has been seen by the user. The "seen" flag will be
- * used to figure out whether we need to throw up a statusbar notification or not.
- */
- public static final String SEEN = "seen";
-
- /**
- * The Message-ID of the message.
- * <P>Type: TEXT</P>
- */
- public static final String MESSAGE_ID = "m_id";
-
- /**
- * The subject of the message, if present.
- * <P>Type: TEXT</P>
- */
- public static final String SUBJECT = "sub";
-
- /**
- * The character set of the subject, if present.
- * <P>Type: INTEGER</P>
- */
- public static final String SUBJECT_CHARSET = "sub_cs";
-
- /**
- * The Content-Type of the message.
- * <P>Type: TEXT</P>
- */
- public static final String CONTENT_TYPE = "ct_t";
-
- /**
- * The Content-Location of the message.
- * <P>Type: TEXT</P>
- */
- public static final String CONTENT_LOCATION = "ct_l";
-
- /**
- * The address of the sender.
- * <P>Type: TEXT</P>
- */
- public static final String FROM = "from";
-
- /**
- * The address of the recipients.
- * <P>Type: TEXT</P>
- */
- public static final String TO = "to";
-
- /**
- * The address of the cc. recipients.
- * <P>Type: TEXT</P>
- */
- public static final String CC = "cc";
-
- /**
- * The address of the bcc. recipients.
- * <P>Type: TEXT</P>
- */
- public static final String BCC = "bcc";
-
- /**
- * The expiry time of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String EXPIRY = "exp";
-
- /**
- * The class of the message.
- * <P>Type: TEXT</P>
- */
- public static final String MESSAGE_CLASS = "m_cls";
-
- /**
- * The type of the message defined by MMS spec.
- * <P>Type: INTEGER</P>
- */
- public static final String MESSAGE_TYPE = "m_type";
-
- /**
- * The version of specification that this message conform.
- * <P>Type: INTEGER</P>
- */
- public static final String MMS_VERSION = "v";
-
- /**
- * The size of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String MESSAGE_SIZE = "m_size";
-
- /**
- * The priority of the message.
- * <P>Type: TEXT</P>
- */
- public static final String PRIORITY = "pri";
-
- /**
- * The read-report of the message.
- * <P>Type: TEXT</P>
- */
- public static final String READ_REPORT = "rr";
-
- /**
- * Whether the report is allowed.
- * <P>Type: TEXT</P>
- */
- public static final String REPORT_ALLOWED = "rpt_a";
-
- /**
- * The response-status of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String RESPONSE_STATUS = "resp_st";
-
- /**
- * The status of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String STATUS = "st";
-
- /**
- * The transaction-id of the message.
- * <P>Type: TEXT</P>
- */
- public static final String TRANSACTION_ID = "tr_id";
-
- /**
- * The retrieve-status of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String RETRIEVE_STATUS = "retr_st";
-
- /**
- * The retrieve-text of the message.
- * <P>Type: TEXT</P>
- */
- public static final String RETRIEVE_TEXT = "retr_txt";
-
- /**
- * The character set of the retrieve-text.
- * <P>Type: TEXT</P>
- */
- public static final String RETRIEVE_TEXT_CHARSET = "retr_txt_cs";
-
- /**
- * The read-status of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String READ_STATUS = "read_status";
-
- /**
- * The content-class of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String CONTENT_CLASS = "ct_cls";
-
- /**
- * The delivery-report of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String DELIVERY_REPORT = "d_rpt";
-
- /**
- * The delivery-time-token of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String DELIVERY_TIME_TOKEN = "d_tm_tok";
-
- /**
- * The delivery-time of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String DELIVERY_TIME = "d_tm";
-
- /**
- * The response-text of the message.
- * <P>Type: TEXT</P>
- */
- public static final String RESPONSE_TEXT = "resp_txt";
-
- /**
- * The sender-visibility of the message.
- * <P>Type: TEXT</P>
- */
- public static final String SENDER_VISIBILITY = "s_vis";
-
- /**
- * The reply-charging of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String REPLY_CHARGING = "r_chg";
-
- /**
- * The reply-charging-deadline-token of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String REPLY_CHARGING_DEADLINE_TOKEN = "r_chg_dl_tok";
-
- /**
- * The reply-charging-deadline of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String REPLY_CHARGING_DEADLINE = "r_chg_dl";
-
- /**
- * The reply-charging-id of the message.
- * <P>Type: TEXT</P>
- */
- public static final String REPLY_CHARGING_ID = "r_chg_id";
-
- /**
- * The reply-charging-size of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String REPLY_CHARGING_SIZE = "r_chg_sz";
-
- /**
- * The previously-sent-by of the message.
- * <P>Type: TEXT</P>
- */
- public static final String PREVIOUSLY_SENT_BY = "p_s_by";
-
- /**
- * The previously-sent-date of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String PREVIOUSLY_SENT_DATE = "p_s_d";
-
- /**
- * The store of the message.
- * <P>Type: TEXT</P>
- */
- public static final String STORE = "store";
-
- /**
- * The mm-state of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String MM_STATE = "mm_st";
-
- /**
- * The mm-flags-token of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String MM_FLAGS_TOKEN = "mm_flg_tok";
-
- /**
- * The mm-flags of the message.
- * <P>Type: TEXT</P>
- */
- public static final String MM_FLAGS = "mm_flg";
-
- /**
- * The store-status of the message.
- * <P>Type: TEXT</P>
- */
- public static final String STORE_STATUS = "store_st";
-
- /**
- * The store-status-text of the message.
- * <P>Type: TEXT</P>
- */
- public static final String STORE_STATUS_TEXT = "store_st_txt";
-
- /**
- * The stored of the message.
- * <P>Type: TEXT</P>
- */
- public static final String STORED = "stored";
-
- /**
- * The totals of the message.
- * <P>Type: TEXT</P>
- */
- public static final String TOTALS = "totals";
-
- /**
- * The mbox-totals of the message.
- * <P>Type: TEXT</P>
- */
- public static final String MBOX_TOTALS = "mb_t";
-
- /**
- * The mbox-totals-token of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String MBOX_TOTALS_TOKEN = "mb_t_tok";
-
- /**
- * The quotas of the message.
- * <P>Type: TEXT</P>
- */
- public static final String QUOTAS = "qt";
-
- /**
- * The mbox-quotas of the message.
- * <P>Type: TEXT</P>
- */
- public static final String MBOX_QUOTAS = "mb_qt";
-
- /**
- * The mbox-quotas-token of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String MBOX_QUOTAS_TOKEN = "mb_qt_tok";
-
- /**
- * The message-count of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String MESSAGE_COUNT = "m_cnt";
-
- /**
- * The start of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String START = "start";
-
- /**
- * The distribution-indicator of the message.
- * <P>Type: TEXT</P>
- */
- public static final String DISTRIBUTION_INDICATOR = "d_ind";
-
- /**
- * The element-descriptor of the message.
- * <P>Type: TEXT</P>
- */
- public static final String ELEMENT_DESCRIPTOR = "e_des";
-
- /**
- * The limit of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String LIMIT = "limit";
-
- /**
- * The recommended-retrieval-mode of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String RECOMMENDED_RETRIEVAL_MODE = "r_r_mod";
-
- /**
- * The recommended-retrieval-mode-text of the message.
- * <P>Type: TEXT</P>
- */
- public static final String RECOMMENDED_RETRIEVAL_MODE_TEXT = "r_r_mod_txt";
-
- /**
- * The status-text of the message.
- * <P>Type: TEXT</P>
- */
- public static final String STATUS_TEXT = "st_txt";
-
- /**
- * The applic-id of the message.
- * <P>Type: TEXT</P>
- */
- public static final String APPLIC_ID = "apl_id";
-
- /**
- * The reply-applic-id of the message.
- * <P>Type: TEXT</P>
- */
- public static final String REPLY_APPLIC_ID = "r_apl_id";
-
- /**
- * The aux-applic-id of the message.
- * <P>Type: TEXT</P>
- */
- public static final String AUX_APPLIC_ID = "aux_apl_id";
-
- /**
- * The drm-content of the message.
- * <P>Type: TEXT</P>
- */
- public static final String DRM_CONTENT = "drm_c";
-
- /**
- * The adaptation-allowed of the message.
- * <P>Type: TEXT</P>
- */
- public static final String ADAPTATION_ALLOWED = "adp_a";
-
- /**
- * The replace-id of the message.
- * <P>Type: TEXT</P>
- */
- public static final String REPLACE_ID = "repl_id";
-
- /**
- * The cancel-id of the message.
- * <P>Type: TEXT</P>
- */
- public static final String CANCEL_ID = "cl_id";
-
- /**
- * The cancel-status of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String CANCEL_STATUS = "cl_st";
-
- /**
- * The thread ID of the message
- * <P>Type: INTEGER</P>
- */
- public static final String THREAD_ID = "thread_id";
-
- /**
- * Has the message been locked?
- * <P>Type: INTEGER (boolean)</P>
- */
- public static final String LOCKED = "locked";
-
- /**
- * Meta data used externally.
- * <P>Type: TEXT</P>
- */
- public static final String META_DATA = "meta_data";
- }
-
- /**
- * Columns for the "canonical_addresses" table used by MMS and
- * SMS."
- */
- public interface CanonicalAddressesColumns extends BaseColumns {
- /**
- * An address used in MMS or SMS. Email addresses are
- * converted to lower case and are compared by string
- * equality. Other addresses are compared using
- * PHONE_NUMBERS_EQUAL.
- * <P>Type: TEXT</P>
- */
- public static final String ADDRESS = "address";
- }
-
- /**
- * Columns for the "threads" table used by MMS and SMS.
- */
- public interface ThreadsColumns extends BaseColumns {
- /**
- * The date at which the thread was created.
- *
- * <P>Type: INTEGER (long)</P>
- */
- public static final String DATE = "date";
-
- /**
- * A string encoding of the recipient IDs of the recipients of
- * the message, in numerical order and separated by spaces.
- * <P>Type: TEXT</P>
- */
- public static final String RECIPIENT_IDS = "recipient_ids";
-
- /**
- * The message count of the thread.
- * <P>Type: INTEGER</P>
- */
- public static final String MESSAGE_COUNT = "message_count";
- /**
- * Indicates whether all messages of the thread have been read.
- * <P>Type: INTEGER</P>
- */
- public static final String READ = "read";
-
- /**
- * The snippet of the latest message in the thread.
- * <P>Type: TEXT</P>
- */
- public static final String SNIPPET = "snippet";
- /**
- * The charset of the snippet.
- * <P>Type: INTEGER</P>
- */
- public static final String SNIPPET_CHARSET = "snippet_cs";
- /**
- * Type of the thread, either Threads.COMMON_THREAD or
- * Threads.BROADCAST_THREAD.
- * <P>Type: INTEGER</P>
- */
- public static final String TYPE = "type";
- /**
- * Indicates whether there is a transmission error in the thread.
- * <P>Type: INTEGER</P>
- */
- public static final String ERROR = "error";
- /**
- * Indicates whether this thread contains any attachments.
- * <P>Type: INTEGER</P>
- */
- public static final String HAS_ATTACHMENT = "has_attachment";
- }
-
- /**
- * Helper functions for the "threads" table used by MMS and SMS.
- */
- public static final class Threads implements ThreadsColumns {
- private static final String[] ID_PROJECTION = { BaseColumns._ID };
- private static final String STANDARD_ENCODING = "UTF-8";
- private static final Uri THREAD_ID_CONTENT_URI = Uri.parse(
- "content://mms-sms/threadID");
- public static final Uri CONTENT_URI = Uri.withAppendedPath(
- MmsSms.CONTENT_URI, "conversations");
- public static final Uri OBSOLETE_THREADS_URI = Uri.withAppendedPath(
- CONTENT_URI, "obsolete");
-
- public static final int COMMON_THREAD = 0;
- public static final int BROADCAST_THREAD = 1;
-
- // No one should construct an instance of this class.
- private Threads() {
- }
-
- /**
- * This is a single-recipient version of
- * getOrCreateThreadId. It's convenient for use with SMS
- * messages.
- */
- public static long getOrCreateThreadId(Context context, String recipient) {
- Set<String> recipients = new HashSet<String>();
-
- recipients.add(recipient);
- return getOrCreateThreadId(context, recipients);
- }
-
- /**
- * Given the recipients list and subject of an unsaved message,
- * return its thread ID. If the message starts a new thread,
- * allocate a new thread ID. Otherwise, use the appropriate
- * existing thread ID.
- *
- * Find the thread ID of the same set of recipients (in
- * any order, without any additions). If one
- * is found, return it. Otherwise, return a unique thread ID.
- */
- public static long getOrCreateThreadId(
- Context context, Set<String> recipients) {
- Uri.Builder uriBuilder = THREAD_ID_CONTENT_URI.buildUpon();
-
- for (String recipient : recipients) {
- if (Mms.isEmailAddress(recipient)) {
- recipient = Mms.extractAddrSpec(recipient);
- }
-
- uriBuilder.appendQueryParameter("recipient", recipient);
- }
-
- Uri uri = uriBuilder.build();
- //if (DEBUG) Log.v(TAG, "getOrCreateThreadId uri: " + uri);
-
- Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
- uri, ID_PROJECTION, null, null, null);
- if (cursor != null) {
- try {
- if (cursor.moveToFirst()) {
- return cursor.getLong(0);
- } else {
- Log.e(TAG, "getOrCreateThreadId returned no rows!");
- }
- } finally {
- cursor.close();
- }
- }
-
- Log.e(TAG, "getOrCreateThreadId failed with uri " + uri.toString());
- throw new IllegalArgumentException("Unable to find or allocate a thread ID.");
- }
- }
-
- /**
- * Contains all MMS messages.
- */
- public static final class Mms implements BaseMmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI = Uri.parse("content://mms");
-
- public static final Uri REPORT_REQUEST_URI = Uri.withAppendedPath(
- CONTENT_URI, "report-request");
-
- public static final Uri REPORT_STATUS_URI = Uri.withAppendedPath(
- CONTENT_URI, "report-status");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
-
- /**
- * mailbox = name-addr
- * name-addr = [display-name] angle-addr
- * angle-addr = [CFWS] "<" addr-spec ">" [CFWS]
- */
- public static final Pattern NAME_ADDR_EMAIL_PATTERN =
- Pattern.compile("\\s*(\"[^\"]*\"|[^<>\"]+)\\s*<([^<>]+)>\\s*");
-
- /**
- * quoted-string = [CFWS]
- * DQUOTE *([FWS] qcontent) [FWS] DQUOTE
- * [CFWS]
- */
- public static final Pattern QUOTED_STRING_PATTERN =
- Pattern.compile("\\s*\"([^\"]*)\"\\s*");
-
- public static final Cursor query(
- ContentResolver cr, String[] projection) {
- return cr.query(CONTENT_URI, projection, null, null, DEFAULT_SORT_ORDER);
- }
-
- public static final Cursor query(
- ContentResolver cr, String[] projection,
- String where, String orderBy) {
- return cr.query(CONTENT_URI, projection,
- where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
- }
-
- public static final String getMessageBoxName(int msgBox) {
- switch (msgBox) {
- case MESSAGE_BOX_ALL:
- return "all";
- case MESSAGE_BOX_INBOX:
- return "inbox";
- case MESSAGE_BOX_SENT:
- return "sent";
- case MESSAGE_BOX_DRAFTS:
- return "drafts";
- case MESSAGE_BOX_OUTBOX:
- return "outbox";
- default:
- throw new IllegalArgumentException("Invalid message box: " + msgBox);
- }
- }
-
- public static String extractAddrSpec(String address) {
- Matcher match = NAME_ADDR_EMAIL_PATTERN.matcher(address);
-
- if (match.matches()) {
- return match.group(2);
- }
- return address;
- }
-
- /**
- * Returns true if the address is an email address
- *
- * @param address the input address to be tested
- * @return true if address is an email address
- */
- public static boolean isEmailAddress(String address) {
- if (TextUtils.isEmpty(address)) {
- return false;
- }
-
- String s = extractAddrSpec(address);
- Matcher match = Patterns.EMAIL_ADDRESS.matcher(s);
- return match.matches();
- }
-
- /**
- * Returns true if the number is a Phone number
- *
- * @param number the input number to be tested
- * @return true if number is a Phone number
- */
- public static boolean isPhoneNumber(String number) {
- if (TextUtils.isEmpty(number)) {
- return false;
- }
-
- Matcher match = Patterns.PHONE.matcher(number);
- return match.matches();
- }
-
- /**
- * Contains all MMS messages in the MMS app's inbox.
- */
- public static final class Inbox implements BaseMmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri
- CONTENT_URI = Uri.parse("content://mms/inbox");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
- }
-
- /**
- * Contains all MMS messages in the MMS app's sent box.
- */
- public static final class Sent implements BaseMmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri
- CONTENT_URI = Uri.parse("content://mms/sent");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
- }
-
- /**
- * Contains all MMS messages in the MMS app's drafts box.
- */
- public static final class Draft implements BaseMmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri
- CONTENT_URI = Uri.parse("content://mms/drafts");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
- }
-
- /**
- * Contains all MMS messages in the MMS app's outbox.
- */
- public static final class Outbox implements BaseMmsColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri
- CONTENT_URI = Uri.parse("content://mms/outbox");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "date DESC";
- }
-
- public static final class Addr implements BaseColumns {
- /**
- * The ID of MM which this address entry belongs to.
- */
- public static final String MSG_ID = "msg_id";
-
- /**
- * The ID of contact entry in Phone Book.
- */
- public static final String CONTACT_ID = "contact_id";
-
- /**
- * The address text.
- */
- public static final String ADDRESS = "address";
-
- /**
- * Type of address, must be one of PduHeaders.BCC,
- * PduHeaders.CC, PduHeaders.FROM, PduHeaders.TO.
- */
- public static final String TYPE = "type";
-
- /**
- * Character set of this entry.
- */
- public static final String CHARSET = "charset";
- }
-
- public static final class Part implements BaseColumns {
- /**
- * The identifier of the message which this part belongs to.
- * <P>Type: INTEGER</P>
- */
- public static final String MSG_ID = "mid";
-
- /**
- * The order of the part.
- * <P>Type: INTEGER</P>
- */
- public static final String SEQ = "seq";
-
- /**
- * The content type of the part.
- * <P>Type: TEXT</P>
- */
- public static final String CONTENT_TYPE = "ct";
-
- /**
- * The name of the part.
- * <P>Type: TEXT</P>
- */
- public static final String NAME = "name";
-
- /**
- * The charset of the part.
- * <P>Type: TEXT</P>
- */
- public static final String CHARSET = "chset";
-
- /**
- * The file name of the part.
- * <P>Type: TEXT</P>
- */
- public static final String FILENAME = "fn";
-
- /**
- * The content disposition of the part.
- * <P>Type: TEXT</P>
- */
- public static final String CONTENT_DISPOSITION = "cd";
-
- /**
- * The content ID of the part.
- * <P>Type: INTEGER</P>
- */
- public static final String CONTENT_ID = "cid";
-
- /**
- * The content location of the part.
- * <P>Type: INTEGER</P>
- */
- public static final String CONTENT_LOCATION = "cl";
-
- /**
- * The start of content-type of the message.
- * <P>Type: INTEGER</P>
- */
- public static final String CT_START = "ctt_s";
-
- /**
- * The type of content-type of the message.
- * <P>Type: TEXT</P>
- */
- public static final String CT_TYPE = "ctt_t";
-
- /**
- * The location(on filesystem) of the binary data of the part.
- * <P>Type: INTEGER</P>
- */
- public static final String _DATA = "_data";
-
- public static final String TEXT = "text";
-
- }
-
- public static final class Rate {
- public static final Uri CONTENT_URI = Uri.withAppendedPath(
- Mms.CONTENT_URI, "rate");
- /**
- * When a message was successfully sent.
- * <P>Type: INTEGER</P>
- */
- public static final String SENT_TIME = "sent_time";
- }
-
- public static final class Intents {
- private Intents() {
- // Non-instantiatable.
- }
-
- /**
- * The extra field to store the contents of the Intent,
- * which should be an array of Uri.
- */
- public static final String EXTRA_CONTENTS = "contents";
- /**
- * The extra field to store the type of the contents,
- * which should be an array of String.
- */
- public static final String EXTRA_TYPES = "types";
- /**
- * The extra field to store the 'Cc' addresses.
- */
- public static final String EXTRA_CC = "cc";
- /**
- * The extra field to store the 'Bcc' addresses;
- */
- public static final String EXTRA_BCC = "bcc";
- /**
- * The extra field to store the 'Subject'.
- */
- public static final String EXTRA_SUBJECT = "subject";
- /**
- * Indicates that the contents of specified URIs were changed.
- * The application which is showing or caching these contents
- * should be updated.
- */
- public static final String
- CONTENT_CHANGED_ACTION = "android.intent.action.CONTENT_CHANGED";
- /**
- * An extra field which stores the URI of deleted contents.
- */
- public static final String DELETED_CONTENTS = "deleted_contents";
- }
- }
-
- /**
- * Contains all MMS and SMS messages.
- */
- public static final class MmsSms implements BaseColumns {
- /**
- * The column to distinguish SMS & MMS messages in query results.
- */
- public static final String TYPE_DISCRIMINATOR_COLUMN =
- "transport_type";
-
- public static final Uri CONTENT_URI = Uri.parse("content://mms-sms/");
-
- public static final Uri CONTENT_CONVERSATIONS_URI = Uri.parse(
- "content://mms-sms/conversations");
-
- public static final Uri CONTENT_FILTER_BYPHONE_URI = Uri.parse(
- "content://mms-sms/messages/byphone");
-
- public static final Uri CONTENT_UNDELIVERED_URI = Uri.parse(
- "content://mms-sms/undelivered");
-
- public static final Uri CONTENT_DRAFT_URI = Uri.parse(
- "content://mms-sms/draft");
-
- public static final Uri CONTENT_LOCKED_URI = Uri.parse(
- "content://mms-sms/locked");
-
- /***
- * Pass in a query parameter called "pattern" which is the text
- * to search for.
- * The sort order is fixed to be thread_id ASC,date DESC.
- */
- public static final Uri SEARCH_URI = Uri.parse(
- "content://mms-sms/search");
-
- // Constants for message protocol types.
- public static final int SMS_PROTO = 0;
- public static final int MMS_PROTO = 1;
-
- // Constants for error types of pending messages.
- public static final int NO_ERROR = 0;
- public static final int ERR_TYPE_GENERIC = 1;
- public static final int ERR_TYPE_SMS_PROTO_TRANSIENT = 2;
- public static final int ERR_TYPE_MMS_PROTO_TRANSIENT = 3;
- public static final int ERR_TYPE_TRANSPORT_FAILURE = 4;
- public static final int ERR_TYPE_GENERIC_PERMANENT = 10;
- public static final int ERR_TYPE_SMS_PROTO_PERMANENT = 11;
- public static final int ERR_TYPE_MMS_PROTO_PERMANENT = 12;
-
- public static final class PendingMessages implements BaseColumns {
- public static final Uri CONTENT_URI = Uri.withAppendedPath(
- MmsSms.CONTENT_URI, "pending");
- /**
- * The type of transport protocol(MMS or SMS).
- * <P>Type: INTEGER</P>
- */
- public static final String PROTO_TYPE = "proto_type";
- /**
- * The ID of the message to be sent or downloaded.
- * <P>Type: INTEGER</P>
- */
- public static final String MSG_ID = "msg_id";
- /**
- * The type of the message to be sent or downloaded.
- * This field is only valid for MM. For SM, its value is always
- * set to 0.
- */
- public static final String MSG_TYPE = "msg_type";
- /**
- * The type of the error code.
- * <P>Type: INTEGER</P>
- */
- public static final String ERROR_TYPE = "err_type";
- /**
- * The error code of sending/retrieving process.
- * <P>Type: INTEGER</P>
- */
- public static final String ERROR_CODE = "err_code";
- /**
- * How many times we tried to send or download the message.
- * <P>Type: INTEGER</P>
- */
- public static final String RETRY_INDEX = "retry_index";
- /**
- * The time to do next retry.
- */
- public static final String DUE_TIME = "due_time";
- /**
- * The time we last tried to send or download the message.
- */
- public static final String LAST_TRY = "last_try";
- }
-
- public static final class WordsTable {
- public static final String ID = "_id";
- public static final String SOURCE_ROW_ID = "source_id";
- public static final String TABLE_ID = "table_to_use";
- public static final String INDEXED_TEXT = "index_text";
- }
- }
-
- public static final class Carriers implements BaseColumns {
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://telephony/carriers");
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = "name ASC";
-
- public static final String NAME = "name";
-
- public static final String APN = "apn";
-
- public static final String PROXY = "proxy";
-
- public static final String PORT = "port";
-
- public static final String MMSPROXY = "mmsproxy";
-
- public static final String MMSPORT = "mmsport";
-
- public static final String SERVER = "server";
-
- public static final String USER = "user";
-
- public static final String PASSWORD = "password";
-
- public static final String MMSC = "mmsc";
-
- public static final String MCC = "mcc";
-
- public static final String MNC = "mnc";
-
- public static final String NUMERIC = "numeric";
-
- public static final String AUTH_TYPE = "authtype";
-
- public static final String TYPE = "type";
-
- public static final String INACTIVE_TIMER = "inactivetimer";
-
- // Only if enabled try Data Connection.
- public static final String ENABLED = "enabled";
-
- // Rules apply based on class.
- public static final String CLASS = "class";
-
- /**
- * The protocol to be used to connect to this APN.
- *
- * One of the PDP_type values in TS 27.007 section 10.1.1.
- * For example, "IP", "IPV6", "IPV4V6", or "PPP".
- */
- public static final String PROTOCOL = "protocol";
-
- /**
- * The protocol to be used to connect to this APN when roaming.
- *
- * The syntax is the same as protocol.
- */
- public static final String ROAMING_PROTOCOL = "roaming_protocol";
-
- public static final String CURRENT = "current";
-
- /**
- * Current status of APN
- * true : enabled APN, false : disabled APN.
- */
- public static final String CARRIER_ENABLED = "carrier_enabled";
-
- /**
- * Radio Access Technology info
- * To check what values can hold, refer to ServiceState.java.
- * This should be spread to other technologies,
- * but currently only used for LTE(14) and EHRPD(13).
- */
- public static final String BEARER = "bearer";
- }
-
- /**
- * Contains received SMS cell broadcast messages.
- */
- public static final class CellBroadcasts implements BaseColumns {
-
- /** Not instantiable. */
- private CellBroadcasts() {}
-
- /**
- * The content:// style URL for this table
- */
- public static final Uri CONTENT_URI =
- Uri.parse("content://cellbroadcasts");
-
- /**
- * Message geographical scope.
- * <P>Type: INTEGER</P>
- */
- public static final String GEOGRAPHICAL_SCOPE = "geo_scope";
-
- /**
- * Message serial number.
- * <P>Type: INTEGER</P>
- */
- public static final String SERIAL_NUMBER = "serial_number";
-
- /**
- * PLMN of broadcast sender. (SERIAL_NUMBER + PLMN + LAC + CID) uniquely identifies a
- * broadcast for duplicate detection purposes.
- * <P>Type: TEXT</P>
- */
- public static final String PLMN = "plmn";
-
- /**
- * Location Area (GSM) or Service Area (UMTS) of broadcast sender. Unused for CDMA.
- * Only included if Geographical Scope of message is not PLMN wide (01).
- * <P>Type: INTEGER</P>
- */
- public static final String LAC = "lac";
-
- /**
- * Cell ID of message sender (GSM/UMTS). Unused for CDMA. Only included when the
- * Geographical Scope of message is cell wide (00 or 11).
- * <P>Type: INTEGER</P>
- */
- public static final String CID = "cid";
-
- /**
- * Message code (OBSOLETE: merged into SERIAL_NUMBER).
- * <P>Type: INTEGER</P>
- */
- public static final String V1_MESSAGE_CODE = "message_code";
-
- /**
- * Message identifier (OBSOLETE: renamed to SERVICE_CATEGORY).
- * <P>Type: INTEGER</P>
- */
- public static final String V1_MESSAGE_IDENTIFIER = "message_id";
-
- /**
- * Service category (GSM/UMTS message identifier, CDMA service category).
- * <P>Type: INTEGER</P>
- */
- public static final String SERVICE_CATEGORY = "service_category";
-
- /**
- * Message language code.
- * <P>Type: TEXT</P>
- */
- public static final String LANGUAGE_CODE = "language";
-
- /**
- * Message body.
- * <P>Type: TEXT</P>
- */
- public static final String MESSAGE_BODY = "body";
-
- /**
- * Message delivery time.
- * <P>Type: INTEGER (long)</P>
- */
- public static final String DELIVERY_TIME = "date";
-
- /**
- * Has the message been viewed?
- * <P>Type: INTEGER (boolean)</P>
- */
- public static final String MESSAGE_READ = "read";
-
- /**
- * Message format (3GPP or 3GPP2).
- * <P>Type: INTEGER</P>
- */
- public static final String MESSAGE_FORMAT = "format";
-
- /**
- * Message priority (including emergency).
- * <P>Type: INTEGER</P>
- */
- public static final String MESSAGE_PRIORITY = "priority";
-
- /**
- * ETWS warning type (ETWS alerts only).
- * <P>Type: INTEGER</P>
- */
- public static final String ETWS_WARNING_TYPE = "etws_warning_type";
-
- /**
- * CMAS message class (CMAS alerts only).
- * <P>Type: INTEGER</P>
- */
- public static final String CMAS_MESSAGE_CLASS = "cmas_message_class";
-
- /**
- * CMAS category (CMAS alerts only).
- * <P>Type: INTEGER</P>
- */
- public static final String CMAS_CATEGORY = "cmas_category";
-
- /**
- * CMAS response type (CMAS alerts only).
- * <P>Type: INTEGER</P>
- */
- public static final String CMAS_RESPONSE_TYPE = "cmas_response_type";
-
- /**
- * CMAS severity (CMAS alerts only).
- * <P>Type: INTEGER</P>
- */
- public static final String CMAS_SEVERITY = "cmas_severity";
-
- /**
- * CMAS urgency (CMAS alerts only).
- * <P>Type: INTEGER</P>
- */
- public static final String CMAS_URGENCY = "cmas_urgency";
-
- /**
- * CMAS certainty (CMAS alerts only).
- * <P>Type: INTEGER</P>
- */
- public static final String CMAS_CERTAINTY = "cmas_certainty";
-
- /**
- * The default sort order for this table
- */
- public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";
-
- /**
- * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
- */
- public static final String[] QUERY_COLUMNS = {
- _ID,
- GEOGRAPHICAL_SCOPE,
- PLMN,
- LAC,
- CID,
- SERIAL_NUMBER,
- SERVICE_CATEGORY,
- LANGUAGE_CODE,
- MESSAGE_BODY,
- DELIVERY_TIME,
- MESSAGE_READ,
- MESSAGE_FORMAT,
- MESSAGE_PRIORITY,
- ETWS_WARNING_TYPE,
- CMAS_MESSAGE_CLASS,
- CMAS_CATEGORY,
- CMAS_RESPONSE_TYPE,
- CMAS_SEVERITY,
- CMAS_URGENCY,
- CMAS_CERTAINTY
- };
- }
-
- public static final class Intents {
- private Intents() {
- // Not instantiable
- }
-
- /**
- * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are
- * of the form *#*#<code>#*#*. The intent will have the data URI:</p>
- *
- * <p><code>android_secret_code://<code></code></p>
- */
- public static final String SECRET_CODE_ACTION =
- "android.provider.Telephony.SECRET_CODE";
-
- /**
- * Broadcast Action: The Service Provider string(s) have been updated. Activities or
- * services that use these strings should update their display.
- * The intent will have the following extra values:</p>
- * <ul>
- * <li><em>showPlmn</em> - Boolean that indicates whether the PLMN should be shown.</li>
- * <li><em>plmn</em> - The operator name of the registered network, as a string.</li>
- * <li><em>showSpn</em> - Boolean that indicates whether the SPN should be shown.</li>
- * <li><em>spn</em> - The service provider name, as a string.</li>
- * </ul>
- * Note that <em>showPlmn</em> may indicate that <em>plmn</em> should be displayed, even
- * though the value for <em>plmn</em> is null. This can happen, for example, if the phone
- * has not registered to a network yet. In this case the receiver may substitute an
- * appropriate placeholder string (eg, "No service").
- *
- * It is recommended to display <em>plmn</em> before / above <em>spn</em> if
- * both are displayed.
- *
- * <p>Note this is a protected intent that can only be sent
- * by the system.
- */
- public static final String SPN_STRINGS_UPDATED_ACTION =
- "android.provider.Telephony.SPN_STRINGS_UPDATED";
-
- public static final String EXTRA_SHOW_PLMN = "showPlmn";
- public static final String EXTRA_PLMN = "plmn";
- public static final String EXTRA_SHOW_SPN = "showSpn";
- public static final String EXTRA_SPN = "spn";
- }
-}
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 97c0209..6296b11 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -2448,7 +2448,7 @@
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
if (state == null) return;
- state.quit();
+ state.doQuit();
mDeviceProfileState.remove(address);
}
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index da10311..2e962a0 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -161,12 +161,17 @@
public static final int FORMAT_NO_YEAR = 0x00008;
public static final int FORMAT_SHOW_DATE = 0x00010;
public static final int FORMAT_NO_MONTH_DAY = 0x00020;
+ @Deprecated
public static final int FORMAT_12HOUR = 0x00040;
+ @Deprecated
public static final int FORMAT_24HOUR = 0x00080;
+ @Deprecated
public static final int FORMAT_CAP_AMPM = 0x00100;
public static final int FORMAT_NO_NOON = 0x00200;
+ @Deprecated
public static final int FORMAT_CAP_NOON = 0x00400;
public static final int FORMAT_NO_MIDNIGHT = 0x00800;
+ @Deprecated
public static final int FORMAT_CAP_MIDNIGHT = 0x01000;
/**
* @deprecated Use
@@ -181,19 +186,25 @@
public static final int FORMAT_NUMERIC_DATE = 0x20000;
public static final int FORMAT_ABBREV_RELATIVE = 0x40000;
public static final int FORMAT_ABBREV_ALL = 0x80000;
+ @Deprecated
public static final int FORMAT_CAP_NOON_MIDNIGHT = (FORMAT_CAP_NOON | FORMAT_CAP_MIDNIGHT);
+ @Deprecated
public static final int FORMAT_NO_NOON_MIDNIGHT = (FORMAT_NO_NOON | FORMAT_NO_MIDNIGHT);
// Date and time format strings that are constant and don't need to be
// translated.
/**
* This is not actually the preferred 24-hour date format in all locales.
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static final String HOUR_MINUTE_24 = "%H:%M";
public static final String MONTH_FORMAT = "%B";
/**
* This is not actually a useful month name in all locales.
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static final String ABBREV_MONTH_FORMAT = "%b";
public static final String NUMERIC_MONTH_FORMAT = "%m";
public static final String MONTH_DAY_FORMAT = "%-d";
@@ -207,6 +218,7 @@
// The index is constructed from a bit-wise OR of the boolean values:
// {showTime, showYear, showWeekDay}. For example, if showYear and
// showWeekDay are both true, then the index would be 3.
+ /** @deprecated do not use. */
public static final int sameYearTable[] = {
com.android.internal.R.string.same_year_md1_md2,
com.android.internal.R.string.same_year_wday1_md1_wday2_md2,
@@ -233,6 +245,7 @@
// The index is constructed from a bit-wise OR of the boolean values:
// {showTime, showYear, showWeekDay}. For example, if showYear and
// showWeekDay are both true, then the index would be 3.
+ /** @deprecated do not use. */
public static final int sameMonthTable[] = {
com.android.internal.R.string.same_month_md1_md2,
com.android.internal.R.string.same_month_wday1_md1_wday2_md2,
@@ -259,7 +272,9 @@
*
* @more <p>
* e.g. "Sunday" or "January"
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static final int LENGTH_LONG = 10;
/**
@@ -268,7 +283,9 @@
*
* @more <p>
* e.g. "Sun" or "Jan"
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static final int LENGTH_MEDIUM = 20;
/**
@@ -278,14 +295,18 @@
* <p>e.g. "Su" or "Jan"
* <p>In most languages, the results returned for LENGTH_SHORT will be the same as
* the results returned for {@link #LENGTH_MEDIUM}.
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static final int LENGTH_SHORT = 30;
/**
* Request an even shorter abbreviated version of the name.
* Do not use this. Currently this will always return the same result
* as {@link #LENGTH_SHORT}.
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static final int LENGTH_SHORTER = 40;
/**
@@ -295,7 +316,9 @@
* <p>e.g. "S", "T", "T" or "J"
* <p>In some languages, the results returned for LENGTH_SHORTEST will be the same as
* the results returned for {@link #LENGTH_SHORT}.
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static final int LENGTH_SHORTEST = 50;
/**
@@ -309,7 +332,9 @@
* Undefined lengths will return {@link #LENGTH_MEDIUM}
* but may return something different in the future.
* @throws IndexOutOfBoundsException if the dayOfWeek is out of bounds.
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static String getDayOfWeekString(int dayOfWeek, int abbrev) {
int[] list;
switch (abbrev) {
@@ -330,7 +355,9 @@
* @param ampm Either {@link Calendar#AM Calendar.AM} or {@link Calendar#PM Calendar.PM}.
* @throws IndexOutOfBoundsException if the ampm is out of bounds.
* @return Localized version of "AM" or "PM".
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static String getAMPMString(int ampm) {
Resources r = Resources.getSystem();
return r.getString(sAmPm[ampm - Calendar.AM]);
@@ -345,7 +372,9 @@
* Undefined lengths will return {@link #LENGTH_MEDIUM}
* but may return something different in the future.
* @return Localized month of the year.
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static String getMonthString(int month, int abbrev) {
// Note that here we use sMonthsMedium for MEDIUM, SHORT and SHORTER.
// This is a shortcut to not spam the translators with too many variations
@@ -378,7 +407,9 @@
* but may return something different in the future.
* @return Localized month of the year.
* @hide Pending API council approval
+ * @deprecated use {@link java.text.SimpleDateFormat} instead.
*/
+ @Deprecated
public static String getStandaloneMonthString(int month, int abbrev) {
// Note that here we use sMonthsMedium for MEDIUM, SHORT and SHORTER.
// This is a shortcut to not spam the translators with too many variations
@@ -1618,7 +1649,7 @@
String result;
long now = System.currentTimeMillis();
- long span = now - millis;
+ long span = Math.abs(now - millis);
synchronized (DateUtils.class) {
if (sNowTime == null) {
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 9063cea..31a9f05 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -250,8 +250,8 @@
// only interested in other non-root views
if (focusable == focused || focusable == root) continue;
- // get visible bounds of other view in same coordinate system
- focusable.getDrawingRect(mOtherRect);
+ // get focus bounds of other view in same coordinate system
+ focusable.getFocusRect(mOtherRect);
root.offsetDescendantRectToMyCoords(focusable, mOtherRect);
if (isBetterCandidate(direction, focusedRect, mOtherRect, mBestCandidateRect)) {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index fd302dc..ed4c75c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -531,7 +531,7 @@
mSurface.transferFrom(mNewSurface);
- if (visible) {
+ if (visible && mSurface.isValid()) {
if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
mSurfaceCreated = true;
mIsCreating = true;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f0ca302..f2a80d0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8737,6 +8737,18 @@
}
/**
+ * When searching for a view to focus this rectangle is used when considering if this view is
+ * a good candidate for receiving focus.
+ *
+ * By default, the rectangle is the {@link #getDrawingRect}) of the view.
+ *
+ * @param r The rectangle to fill in, in this view's coordinates.
+ */
+ public void getFocusRect(Rect r) {
+ getDrawingRect(r);
+ }
+
+ /**
* Utility method to retrieve the inverse of the current mMatrix property.
* We cache the matrix to avoid recalculating it when transform properties
* have not changed.
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index d1d867c..c624a87 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -686,6 +686,10 @@
// It's used to dismiss the dialog in destroy if not done before.
private AlertDialog mListBoxDialog = null;
+ // Reference to the save password dialog so it can be dimissed in
+ // destroy if not done before.
+ private AlertDialog mSavePasswordDialog = null;
+
static final String LOGTAG = "webview";
private ZoomManager mZoomManager;
@@ -1826,7 +1830,7 @@
neverRemember.getData().putString("password", password);
neverRemember.obj = resumeMsg;
- new AlertDialog.Builder(mContext)
+ mSavePasswordDialog = new AlertDialog.Builder(mContext)
.setTitle(com.android.internal.R.string.save_password_label)
.setMessage(com.android.internal.R.string.save_password_message)
.setPositiveButton(com.android.internal.R.string.save_password_notnow,
@@ -1837,6 +1841,7 @@
resumeMsg.sendToTarget();
mResumeMsg = null;
}
+ mSavePasswordDialog = null;
}
})
.setNeutralButton(com.android.internal.R.string.save_password_remember,
@@ -1847,6 +1852,7 @@
remember.sendToTarget();
mResumeMsg = null;
}
+ mSavePasswordDialog = null;
}
})
.setNegativeButton(com.android.internal.R.string.save_password_never,
@@ -1857,6 +1863,7 @@
neverRemember.sendToTarget();
mResumeMsg = null;
}
+ mSavePasswordDialog = null;
}
})
.setOnCancelListener(new OnCancelListener() {
@@ -1866,6 +1873,7 @@
resumeMsg.sendToTarget();
mResumeMsg = null;
}
+ mSavePasswordDialog = null;
}
}).show();
// Return true so that WebViewCore will pause while the dialog is
@@ -2105,6 +2113,10 @@
mListBoxDialog.dismiss();
mListBoxDialog = null;
}
+ if (mSavePasswordDialog != null) {
+ mSavePasswordDialog.dismiss();
+ mSavePasswordDialog = null;
+ }
if (mWebViewCore != null) {
// Tell WebViewCore to destroy itself
synchronized (this) {
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 323fcf0..b72b8cb 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -1192,15 +1192,15 @@
case KeyEvent.KEYCODE_DPAD_LEFT:
if (movePrevious()) {
playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
+ return true;
}
- return true;
-
+ break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (moveNext()) {
playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
+ return true;
}
- return true;
-
+ break;
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
mReceivedInvokeKeyDown = true;
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index ff8c0a1..37e0b90 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -2207,8 +2207,13 @@
int height = view.getHeight();
if (height > 0) {
final int numColumns = mNumColumns;
- final int whichRow = mFirstPosition / numColumns;
final int rowCount = (mItemCount + numColumns - 1) / numColumns;
+ // In case of stackFromBottom the calculation of whichRow needs
+ // to take into account that counting from the top the first row
+ // might not be entirely filled.
+ final int oddItemsOnFirstRow = isStackFromBottom() ? ((rowCount * numColumns) -
+ mItemCount) : 0;
+ final int whichRow = (mFirstPosition + oddItemsOnFirstRow) / numColumns;
return Math.max(whichRow * 100 - (top * 100) / height +
(int) ((float) mScrollY / getHeight() * rowCount * 100), 0);
}
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 18c4fe6..ff0579c 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -22,6 +22,7 @@
import android.graphics.Rect;
import android.os.Bundle;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.FocusFinder;
import android.view.InputDevice;
import android.view.KeyEvent;
@@ -62,6 +63,7 @@
private static final float MAX_SCROLL_FACTOR = ScrollView.MAX_SCROLL_FACTOR;
+ private static final String TAG = "HorizontalScrollView";
private long mLastScroll;
@@ -456,6 +458,12 @@
}
final int pointerIndex = ev.findPointerIndex(activePointerId);
+ if (pointerIndex == -1) {
+ Log.e(TAG, "Invalid pointerId=" + activePointerId
+ + " in onInterceptTouchEvent");
+ break;
+ }
+
final int x = (int) ev.getX(pointerIndex);
final int xDiff = (int) Math.abs(x - mLastMotionX);
if (xDiff > mTouchSlop) {
@@ -557,6 +565,11 @@
}
case MotionEvent.ACTION_MOVE:
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (activePointerIndex == -1) {
+ Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
+ break;
+ }
+
final int x = (int) ev.getX(activePointerIndex);
int deltaX = mLastMotionX - x;
if (!mIsBeingDragged && Math.abs(deltaX) > mTouchSlop) {
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index fc35f05..f76ab2b 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -477,7 +477,8 @@
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_UP
- || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
+ || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE
+ || keyCode == KeyEvent.KEYCODE_CAMERA) {
// don't show the controls for volume adjustment
return super.dispatchKeyEvent(event);
} else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index ebc54f4..8747dc3 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -25,6 +25,7 @@
import android.os.Bundle;
import android.os.StrictMode;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.FocusFinder;
import android.view.InputDevice;
import android.view.KeyEvent;
@@ -69,6 +70,8 @@
static final float MAX_SCROLL_FACTOR = 0.5f;
+ private static final String TAG = "ScrollView";
+
private long mLastScroll;
private final Rect mTempRect = new Rect();
@@ -478,6 +481,12 @@
}
final int pointerIndex = ev.findPointerIndex(activePointerId);
+ if (pointerIndex == -1) {
+ Log.e(TAG, "Invalid pointerId=" + activePointerId
+ + " in onInterceptTouchEvent");
+ break;
+ }
+
final int y = (int) ev.getY(pointerIndex);
final int yDiff = Math.abs(y - mLastMotionY);
if (yDiff > mTouchSlop) {
@@ -585,6 +594,11 @@
}
case MotionEvent.ACTION_MOVE:
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (activePointerIndex == -1) {
+ Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
+ break;
+ }
+
final int y = (int) ev.getY(activePointerIndex);
int deltaY = mLastMotionY - y;
if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index a0e961f..86433d4 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -1506,6 +1506,9 @@
// because the voice search activity will always need to insert "QUERY" into
// it anyway.
Bundle queryExtras = new Bundle();
+ if (mAppSearchData != null) {
+ queryExtras.putParcelable(SearchManager.APP_DATA, mAppSearchData);
+ }
// Now build the intent to launch the voice search. Add all necessary
// extras to launch the voice recognizer, and then all the necessary extras
@@ -1595,8 +1598,8 @@
} catch (RuntimeException e2 ) {
rowNum = -1;
}
- Log.w(LOG_TAG, "Search Suggestions cursor at row " + rowNum +
- " returned exception" + e.toString());
+ Log.w(LOG_TAG, "Search suggestions cursor at row " + rowNum +
+ " returned exception.", e);
return null;
}
}
diff --git a/core/java/android/widget/SimpleExpandableListAdapter.java b/core/java/android/widget/SimpleExpandableListAdapter.java
index 015c169..f514374 100644
--- a/core/java/android/widget/SimpleExpandableListAdapter.java
+++ b/core/java/android/widget/SimpleExpandableListAdapter.java
@@ -38,6 +38,8 @@
*/
public class SimpleExpandableListAdapter extends BaseExpandableListAdapter {
private List<? extends Map<String, ?>> mGroupData;
+ // Keeps track of if a group is currently expanded or not
+ private boolean[] mIsGroupExpanded;
private int mExpandedGroupLayout;
private int mCollapsedGroupLayout;
private String[] mGroupFrom;
@@ -196,6 +198,8 @@
int childLayout, int lastChildLayout, String[] childFrom,
int[] childTo) {
mGroupData = groupData;
+ // Initially all groups are not expanded
+ mIsGroupExpanded = new boolean[groupData.size()];
mExpandedGroupLayout = expandedGroupLayout;
mCollapsedGroupLayout = collapsedGroupLayout;
mGroupFrom = groupFrom;
@@ -298,4 +302,52 @@
return true;
}
+ /**
+ * {@inheritDoc}
+ * @return 1 for the last child in a group, 0 for the other children.
+ */
+ @Override
+ public int getChildType(int groupPosition, int childPosition) {
+ final int childrenInGroup = getChildrenCount(groupPosition);
+ return childPosition == childrenInGroup - 1 ? 1 : 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return 2, one type for the last child in a group, one for the other children.
+ */
+ @Override
+ public int getChildTypeCount() {
+ return 2;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return 1 for an expanded group view, 0 for a collapsed one.
+ */
+ @Override
+ public int getGroupType(int groupPosition) {
+ return mIsGroupExpanded[groupPosition] ? 1 : 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return 2, one for a collapsed group view, one for an expanded one.
+ */
+ @Override
+ public int getGroupTypeCount() {
+ return 2;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void onGroupCollapsed(int groupPosition) {
+ mIsGroupExpanded[groupPosition] = false;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void onGroupExpanded(int groupPosition) {
+ mIsGroupExpanded[groupPosition] = true;
+ }
}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 56f6651..cea613f 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -686,7 +686,7 @@
@Override
public void setChecked(boolean checked) {
super.setChecked(checked);
- mThumbPosition = checked ? getThumbScrollRange() : 0;
+ mThumbPosition = isChecked() ? getThumbScrollRange() : 0;
invalidate();
}
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 8bb9348..238dc55 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -48,6 +48,10 @@
*/
public class TabHost extends FrameLayout implements ViewTreeObserver.OnTouchModeChangeListener {
+ private static final int TABWIDGET_LOCATION_LEFT = 0;
+ private static final int TABWIDGET_LOCATION_TOP = 1;
+ private static final int TABWIDGET_LOCATION_RIGHT = 2;
+ private static final int TABWIDGET_LOCATION_BOTTOM = 3;
private TabWidget mTabWidget;
private FrameLayout mTabContent;
private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2);
@@ -293,22 +297,73 @@
return mTabContent;
}
+ /**
+ * Get the location of the TabWidget.
+ *
+ * @return The TabWidget location.
+ */
+ private int getTabWidgetLocation() {
+ int location = TABWIDGET_LOCATION_TOP;
+
+ switch (mTabWidget.getOrientation()) {
+ case LinearLayout.VERTICAL:
+ location = (mTabContent.getLeft() < mTabWidget.getLeft()) ? TABWIDGET_LOCATION_RIGHT
+ : TABWIDGET_LOCATION_LEFT;
+ break;
+ case LinearLayout.HORIZONTAL:
+ default:
+ location = (mTabContent.getTop() < mTabWidget.getTop()) ? TABWIDGET_LOCATION_BOTTOM
+ : TABWIDGET_LOCATION_TOP;
+ break;
+ }
+ return location;
+ }
+
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
final boolean handled = super.dispatchKeyEvent(event);
- // unhandled key ups change focus to tab indicator for embedded activities
- // when there is nothing that will take focus from default focus searching
+ // unhandled key events change focus to tab indicator for embedded
+ // activities when there is nothing that will take focus from default
+ // focus searching
if (!handled
&& (event.getAction() == KeyEvent.ACTION_DOWN)
- && (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP)
&& (mCurrentView != null)
&& (mCurrentView.isRootNamespace())
- && (mCurrentView.hasFocus())
- && (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null)) {
- mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
- playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
- return true;
+ && (mCurrentView.hasFocus())) {
+ int keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
+ int directionShouldChangeFocus = View.FOCUS_UP;
+ int soundEffect = SoundEffectConstants.NAVIGATION_UP;
+
+ switch (getTabWidgetLocation()) {
+ case TABWIDGET_LOCATION_LEFT:
+ keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_LEFT;
+ directionShouldChangeFocus = View.FOCUS_LEFT;
+ soundEffect = SoundEffectConstants.NAVIGATION_LEFT;
+ break;
+ case TABWIDGET_LOCATION_RIGHT:
+ keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_RIGHT;
+ directionShouldChangeFocus = View.FOCUS_RIGHT;
+ soundEffect = SoundEffectConstants.NAVIGATION_RIGHT;
+ break;
+ case TABWIDGET_LOCATION_BOTTOM:
+ keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_DOWN;
+ directionShouldChangeFocus = View.FOCUS_DOWN;
+ soundEffect = SoundEffectConstants.NAVIGATION_DOWN;
+ break;
+ case TABWIDGET_LOCATION_TOP:
+ default:
+ keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
+ directionShouldChangeFocus = View.FOCUS_UP;
+ soundEffect = SoundEffectConstants.NAVIGATION_UP;
+ break;
+ }
+ if (event.getKeyCode() == keyCodeShouldChangeFocus
+ && mCurrentView.findFocus().focusSearch(directionShouldChangeFocus) == null) {
+ mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
+ playSoundEffect(soundEffect);
+ return true;
+ }
}
return handled;
}
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 2061c90..56b5937 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -347,6 +347,18 @@
}
}
+ /**
+ * @param attrId the attributeId of the theme-specific drawable
+ * to resolve the resourceId for.
+ *
+ * @return resId the resourceId of the theme-specific drawable
+ */
+ public int getIconAttributeResId(int attrId) {
+ TypedValue out = new TypedValue();
+ mContext.getTheme().resolveAttribute(attrId, out, true);
+ return out.resourceId;
+ }
+
public void setInverseBackgroundForced(boolean forceInverseBackground) {
mForceInverseBackground = forceInverseBackground;
}
@@ -740,6 +752,7 @@
public int mIconId = 0;
public Drawable mIcon;
+ public int mIconAttrId = 0;
public CharSequence mTitle;
public View mCustomTitleView;
public CharSequence mMessage;
@@ -806,6 +819,9 @@
if (mIconId >= 0) {
dialog.setIcon(mIconId);
}
+ if (mIconAttrId > 0) {
+ dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
+ }
}
if (mMessage != null) {
dialog.setMessage(mMessage);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5157385..db752e9 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -2302,8 +2302,8 @@
batteryRealtime, which);
}
- @Override public int getPhoneSignalStrengthCount(int dataType, int which) {
- return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
+ @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
+ return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
}
@Override public long getPhoneDataConnectionTime(int dataType,
diff --git a/core/java/com/android/internal/os/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java
index 1923b86..b1bb8c1 100644
--- a/core/java/com/android/internal/os/ProcessStats.java
+++ b/core/java/com/android/internal/os/ProcessStats.java
@@ -154,7 +154,7 @@
private boolean mFirst = true;
- private byte[] mBuffer = new byte[256];
+ private byte[] mBuffer = new byte[4096];
/**
* The time in microseconds that the CPU has been running at each speed.
@@ -556,7 +556,7 @@
private long[] getCpuSpeedTimes(long[] out) {
long[] tempTimes = out;
long[] tempSpeeds = mCpuSpeeds;
- final int MAX_SPEEDS = 20;
+ final int MAX_SPEEDS = 60;
if (out == null) {
tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that
tempSpeeds = new long[MAX_SPEEDS];
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 9af7e96..b016e99 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -26,6 +26,8 @@
import dalvik.system.PathClassLoader;
import dalvik.system.Zygote;
+import android.os.SELinux;
+
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -73,6 +75,7 @@
private final DataOutputStream mSocketOutStream;
private final BufferedReader mSocketReader;
private final Credentials peer;
+ private final String peerSecurityContext;
/**
* A long-lived reference to the original command socket used to launch
@@ -109,6 +112,8 @@
Log.e(TAG, "Cannot read peer credentials", ex);
throw ex;
}
+
+ peerSecurityContext = SELinux.getPeerContext(mSocket.getFileDescriptor());
}
/**
@@ -207,10 +212,11 @@
try {
parsedArgs = new Arguments(args);
- applyUidSecurityPolicy(parsedArgs, peer);
- applyRlimitSecurityPolicy(parsedArgs, peer);
- applyCapabilitiesSecurityPolicy(parsedArgs, peer);
- applyInvokeWithSecurityPolicy(parsedArgs, peer);
+ applyUidSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+ applyRlimitSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+ applyCapabilitiesSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+ applyInvokeWithSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+ applyseInfoSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyDebuggerSystemProperty(parsedArgs);
applyInvokeWithSystemProperty(parsedArgs);
@@ -229,7 +235,8 @@
}
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
+ parsedArgs.gids, parsedArgs.debugFlags, rlimits,
+ parsedArgs.seInfo, parsedArgs.niceName);
} catch (IOException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (ErrnoException ex) {
@@ -352,6 +359,10 @@
long permittedCapabilities;
long effectiveCapabilities;
+ /** from --seinfo */
+ boolean seInfoSpecified;
+ String seInfo;
+
/** from all --rlimit=r,c,m */
ArrayList<int[]> rlimits;
@@ -429,6 +440,13 @@
peerWait = true;
} else if (arg.equals("--runtime-init")) {
runtimeInit = true;
+ } else if (arg.startsWith("--seinfo=")) {
+ if (seInfoSpecified) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+ seInfoSpecified = true;
+ seInfo = arg.substring(arg.indexOf('=') + 1);
} else if (arg.startsWith("--capabilities=")) {
if (capabilitiesSpecified) {
throw new IllegalArgumentException(
@@ -591,7 +609,8 @@
* @param peer non-null; peer credentials
* @throws ZygoteSecurityException
*/
- private static void applyUidSecurityPolicy(Arguments args, Credentials peer)
+ private static void applyUidSecurityPolicy(Arguments args, Credentials peer,
+ String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
@@ -624,6 +643,17 @@
}
}
+ if (args.uidSpecified || args.gidSpecified || args.gids != null) {
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifyids");
+ if (!allowed) {
+ throw new ZygoteSecurityException(
+ "Peer may not specify uid's or gid's");
+ }
+ }
+
// If not otherwise specified, uid and gid are inherited from peer
if (!args.uidSpecified) {
args.uid = peer.getUid();
@@ -664,7 +694,7 @@
* @throws ZygoteSecurityException
*/
private static void applyRlimitSecurityPolicy(
- Arguments args, Credentials peer)
+ Arguments args, Credentials peer, String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
@@ -676,6 +706,17 @@
"This UID may not specify rlimits.");
}
}
+
+ if (args.rlimits != null) {
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifyrlimits");
+ if (!allowed) {
+ throw new ZygoteSecurityException(
+ "Peer may not specify rlimits");
+ }
+ }
}
/**
@@ -689,7 +730,7 @@
* @throws ZygoteSecurityException
*/
private static void applyCapabilitiesSecurityPolicy(
- Arguments args, Credentials peer)
+ Arguments args, Credentials peer, String peerSecurityContext)
throws ZygoteSecurityException {
if (args.permittedCapabilities == 0
@@ -698,6 +739,15 @@
return;
}
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifycapabilities");
+ if (!allowed) {
+ throw new ZygoteSecurityException(
+ "Peer may not specify capabilities");
+ }
+
if (peer.getUid() == 0) {
// root may specify anything
return;
@@ -747,7 +797,8 @@
* @param peer non-null; peer credentials
* @throws ZygoteSecurityException
*/
- private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer)
+ private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer,
+ String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
@@ -755,6 +806,52 @@
throw new ZygoteSecurityException("Peer is not permitted to specify "
+ "an explicit invoke-with wrapper command");
}
+
+ if (args.invokeWith != null) {
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifyinvokewith");
+ if (!allowed) {
+ throw new ZygoteSecurityException("Peer is not permitted to specify "
+ + "an explicit invoke-with wrapper command");
+ }
+ }
+ }
+
+ /**
+ * Applies zygote security policy for SEAndroid information.
+ *
+ * @param args non-null; zygote spawner arguments
+ * @param peer non-null; peer credentials
+ * @throws ZygoteSecurityException
+ */
+ private static void applyseInfoSecurityPolicy(
+ Arguments args, Credentials peer, String peerSecurityContext)
+ throws ZygoteSecurityException {
+ int peerUid = peer.getUid();
+
+ if (args.seInfo == null) {
+ // nothing to check
+ return;
+ }
+
+ if (!(peerUid == 0 || peerUid == Process.SYSTEM_UID)) {
+ // All peers with UID other than root or SYSTEM_UID
+ throw new ZygoteSecurityException(
+ "This UID may not specify SEAndroid info.");
+ }
+
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifyseinfo");
+ if (!allowed) {
+ throw new ZygoteSecurityException(
+ "Peer may not specify SEAndroid info");
+ }
+
+ return;
}
/**
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 998c037..4924326 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -16,16 +16,17 @@
package com.android.internal.os;
+import static libcore.io.OsConstants.S_IRWXG;
+import static libcore.io.OsConstants.S_IRWXO;
+
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.LocalServerSocket;
import android.os.Debug;
-import android.os.FileUtils;
import android.os.Process;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.util.EventLog;
import android.util.Log;
@@ -33,6 +34,7 @@
import dalvik.system.Zygote;
import libcore.io.IoUtils;
+import libcore.io.Libcore;
import java.io.BufferedReader;
import java.io.FileDescriptor;
@@ -447,7 +449,7 @@
closeServerSocket();
// set umask to 0077 so new files and directories will default to owner-only permissions.
- FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO);
+ Libcore.os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index d1c2d2e..5093b4d 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -444,6 +444,16 @@
if ((mConnection != null) && (mSrcContext != null)) {
mSrcContext.unbindService(mConnection);
}
+ try {
+ // Send the DISCONNECTED, although it may not be received
+ // but its the best we can do.
+ Message msg = Message.obtain();
+ msg.what = CMD_CHANNEL_DISCONNECTED;
+ msg.replyTo = mSrcMessenger;
+ mDstMessenger.send(msg);
+ } catch(Exception e) {
+ }
+ // Tell source we're disconnected.
if (mSrcHandler != null) {
replyDisconnected(STATUS_SUCCESSFUL);
}
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 1391ac3..0ea7b83 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -80,9 +80,9 @@
* and invoke <code>halting</code>. Any message subsequently received by the state
* machine will cause <code>haltedProcessMessage</code> to be invoked.</p>
*
- * <p>If it is desirable to completely stop the state machine call <code>quit</code>. This
- * will exit the current state and its parent and then exit from the controlling thread
- * and no further messages will be processed.</p>
+ * <p>If it is desirable to completely stop the state machine call <code>quit</code> or
+ * <code>abort</code>. These will call <code>exit</code> of the current state and its parents, call
+ * <code>onQuiting</code> and then exit Thread/Loopers.</p>
*
* <p>In addition to <code>processMessage</code> each <code>State</code> has
* an <code>enter</code> method and <code>exit</exit> method which may be overridden.</p>
@@ -362,7 +362,7 @@
}
@Override
- void halting() {
+ void onHalting() {
Log.d(TAG, "halting");
synchronized (this) {
this.notifyAll();
@@ -423,10 +423,10 @@
private String mName;
/** Message.what value when quitting */
- public static final int SM_QUIT_CMD = -1;
+ private static final int SM_QUIT_CMD = -1;
/** Message.what value when initializing */
- public static final int SM_INIT_CMD = -2;
+ private static final int SM_INIT_CMD = -2;
/**
* Convenience constant that maybe returned by processMessage
@@ -443,11 +443,10 @@
public static final boolean NOT_HANDLED = false;
/**
+ * StateMachine logging record.
* {@hide}
- *
- * The information maintained for a processed message.
*/
- public static class ProcessedMessageInfo {
+ public static class LogRec {
private long mTime;
private int mWhat;
private String mInfo;
@@ -456,12 +455,13 @@
/**
* Constructor
- * @param message
+ *
+ * @param msg
* @param state that handled the message
* @param orgState is the first state the received the message but
* did not processes the message.
*/
- ProcessedMessageInfo(Message msg, String info, State state, State orgState) {
+ LogRec(Message msg, String info, State state, State orgState) {
update(msg, info, state, orgState);
}
@@ -473,7 +473,7 @@
*/
public void update(Message msg, String info, State state, State orgState) {
mTime = System.currentTimeMillis();
- mWhat = msg.what;
+ mWhat = (msg != null) ? msg.what : 0;
mInfo = info;
mState = state;
mOrgState = orgState;
@@ -517,8 +517,7 @@
/**
* @return as string
*/
- @Override
- public String toString() {
+ public String toString(StateMachine sm) {
StringBuilder sb = new StringBuilder();
sb.append("time=");
Calendar c = Calendar.getInstance();
@@ -529,10 +528,15 @@
sb.append(" orgState=");
sb.append(mOrgState == null ? "<null>" : mOrgState.getName());
sb.append(" what=");
- sb.append(mWhat);
- sb.append("(0x");
- sb.append(Integer.toHexString(mWhat));
- sb.append(")");
+ String what = sm.getWhatToString(mWhat);
+ if (TextUtils.isEmpty(what)) {
+ sb.append(mWhat);
+ sb.append("(0x");
+ sb.append(Integer.toHexString(mWhat));
+ sb.append(")");
+ } else {
+ sb.append(what);
+ }
if ( ! TextUtils.isEmpty(mInfo)) {
sb.append(" ");
sb.append(mInfo);
@@ -542,21 +546,21 @@
}
/**
- * A list of messages recently processed by the state machine.
+ * A list of log records including messages recently processed by the state machine.
*
- * The class maintains a list of messages that have been most
+ * The class maintains a list of log records including messages
* recently processed. The list is finite and may be set in the
* constructor or by calling setSize. The public interface also
- * includes size which returns the number of recent messages,
- * count which is the number of message processed since the
- * the last setSize, get which returns a processed message and
- * add which adds a processed messaged.
+ * includes size which returns the number of recent records,
+ * count which is the number of records processed since the
+ * the last setSize, get which returns a record and
+ * add which adds a record.
*/
- private static class ProcessedMessages {
+ private static class LogRecords {
private static final int DEFAULT_SIZE = 20;
- private Vector<ProcessedMessageInfo> mMessages = new Vector<ProcessedMessageInfo>();
+ private Vector<LogRec> mLogRecords = new Vector<LogRec>();
private int mMaxSize = DEFAULT_SIZE;
private int mOldestIndex = 0;
private int mCount = 0;
@@ -564,39 +568,39 @@
/**
* private constructor use add
*/
- private ProcessedMessages() {
+ private LogRecords() {
}
/**
- * Set size of messages to maintain and clears all current messages.
+ * Set size of messages to maintain and clears all current records.
*
- * @param maxSize number of messages to maintain at anyone time.
+ * @param maxSize number of records to maintain at anyone time.
*/
- void setSize(int maxSize) {
+ synchronized void setSize(int maxSize) {
mMaxSize = maxSize;
mCount = 0;
- mMessages.clear();
+ mLogRecords.clear();
}
/**
- * @return the number of recent messages.
+ * @return the number of recent records.
*/
- int size() {
- return mMessages.size();
+ synchronized int size() {
+ return mLogRecords.size();
}
/**
- * @return the total number of messages processed since size was set.
+ * @return the total number of records processed since size was set.
*/
- int count() {
+ synchronized int count() {
return mCount;
}
/**
- * Clear the list of Processed Message Info.
+ * Clear the list of records.
*/
- void cleanup() {
- mMessages.clear();
+ synchronized void cleanup() {
+ mLogRecords.clear();
}
/**
@@ -604,7 +608,7 @@
* record and size()-1 is the newest record. If the index is to
* large null is returned.
*/
- ProcessedMessageInfo get(int index) {
+ synchronized LogRec get(int index) {
int nextIndex = mOldestIndex + index;
if (nextIndex >= mMaxSize) {
nextIndex -= mMaxSize;
@@ -612,7 +616,7 @@
if (nextIndex >= size()) {
return null;
} else {
- return mMessages.get(nextIndex);
+ return mLogRecords.get(nextIndex);
}
}
@@ -625,12 +629,12 @@
* @param orgState is the first state the received the message but
* did not processes the message.
*/
- void add(Message msg, String messageInfo, State state, State orgState) {
+ synchronized void add(Message msg, String messageInfo, State state, State orgState) {
mCount += 1;
- if (mMessages.size() < mMaxSize) {
- mMessages.add(new ProcessedMessageInfo(msg, messageInfo, state, orgState));
+ if (mLogRecords.size() < mMaxSize) {
+ mLogRecords.add(new LogRec(msg, messageInfo, state, orgState));
} else {
- ProcessedMessageInfo pmi = mMessages.get(mOldestIndex);
+ LogRec pmi = mLogRecords.get(mOldestIndex);
mOldestIndex += 1;
if (mOldestIndex >= mMaxSize) {
mOldestIndex = 0;
@@ -652,8 +656,8 @@
/** The current message */
private Message mMsg;
- /** A list of messages that this state machine has processed */
- private ProcessedMessages mProcessedMessages = new ProcessedMessages();
+ /** A list of log records including messages this state machine has processed */
+ private LogRecords mLogRecords = new LogRecords();
/** true if construction of the state machine has not been completed */
private boolean mIsConstructionCompleted;
@@ -814,15 +818,18 @@
*/
if (destState != null) {
if (destState == mQuittingState) {
+ /**
+ * Call onQuitting to let subclasses cleanup.
+ */
+ mSm.onQuitting();
cleanupAfterQuitting();
-
} else if (destState == mHaltingState) {
/**
- * Call halting() if we've transitioned to the halting
+ * Call onHalting() if we've transitioned to the halting
* state. All subsequent messages will be processed in
* in the halting state which invokes haltedProcessMessage(msg);
*/
- mSm.halting();
+ mSm.onHalting();
}
}
}
@@ -831,7 +838,6 @@
* Cleanup all the static variables and the looper after the SM has been quit.
*/
private final void cleanupAfterQuitting() {
- mSm.quitting();
if (mSm.mSmThread != null) {
// If we made the thread then quit looper which stops the thread.
getLooper().quit();
@@ -841,7 +847,7 @@
mSm.mSmHandler = null;
mSm = null;
mMsg = null;
- mProcessedMessages.cleanup();
+ mLogRecords.cleanup();
mStateStack = null;
mTempStateStack = null;
mStateInfo.clear();
@@ -892,36 +898,38 @@
if (mDbg) {
Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
}
- while (!curStateInfo.state.processMessage(msg)) {
- /**
- * Not processed
- */
- curStateInfo = curStateInfo.parentStateInfo;
- if (curStateInfo == null) {
- /**
- * No parents left so it's not handled
- */
- mSm.unhandledMessage(msg);
- if (isQuit(msg)) {
- transitionTo(mQuittingState);
- }
- break;
- }
- if (mDbg) {
- Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
- }
- }
- /**
- * Record that we processed the message
- */
- if (mSm.recordProcessedMessage(msg)) {
- if (curStateInfo != null) {
- State orgState = mStateStack[mStateStackTopIndex].state;
- mProcessedMessages.add(msg, mSm.getMessageInfo(msg), curStateInfo.state,
- orgState);
- } else {
- mProcessedMessages.add(msg, mSm.getMessageInfo(msg), null, null);
+ if (isQuit(msg)) {
+ transitionTo(mQuittingState);
+ } else {
+ while (!curStateInfo.state.processMessage(msg)) {
+ /**
+ * Not processed
+ */
+ curStateInfo = curStateInfo.parentStateInfo;
+ if (curStateInfo == null) {
+ /**
+ * No parents left so it's not handled
+ */
+ mSm.unhandledMessage(msg);
+ break;
+ }
+ if (mDbg) {
+ Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
+ }
+ }
+
+ /**
+ * Record that we processed the message
+ */
+ if (mSm.recordLogRec(msg)) {
+ if (curStateInfo != null) {
+ State orgState = mStateStack[mStateStackTopIndex].state;
+ mLogRecords.add(msg, mSm.getLogRecString(msg), curStateInfo.state,
+ orgState);
+ } else {
+ mLogRecords.add(msg, mSm.getLogRecString(msg), null, null);
+ }
}
}
}
@@ -1141,13 +1149,19 @@
mDeferredMessages.add(newMsg);
}
- /** @see StateMachine#deferMessage(Message) */
+ /** @see StateMachine#quit() */
private final void quit() {
if (mDbg) Log.d(TAG, "quit:");
sendMessage(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
}
- /** @see StateMachine#isQuit(Message) */
+ /** @see StateMachine#quitNow() */
+ private final void quitNow() {
+ if (mDbg) Log.d(TAG, "abort:");
+ sendMessageAtFrontOfQueue(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
+ }
+
+ /** Validate that the message was sent by quit or abort. */
private final boolean isQuit(Message msg) {
return (msg.what == SM_QUIT_CMD) && (msg.obj == mSmHandlerObj);
}
@@ -1162,26 +1176,6 @@
mDbg = dbg;
}
- /** @see StateMachine#setProcessedMessagesSize(int) */
- private final void setProcessedMessagesSize(int maxSize) {
- mProcessedMessages.setSize(maxSize);
- }
-
- /** @see StateMachine#getProcessedMessagesSize() */
- private final int getProcessedMessagesSize() {
- return mProcessedMessages.size();
- }
-
- /** @see StateMachine#getProcessedMessagesCount() */
- private final int getProcessedMessagesCount() {
- return mProcessedMessages.count();
- }
-
- /** @see StateMachine#getProcessedMessageInfo(int) */
- private final ProcessedMessageInfo getProcessedMessageInfo(int index) {
- return mProcessedMessages.get(index);
- }
-
}
private SmHandler mSmHandler;
@@ -1282,8 +1276,8 @@
/**
* transition to halt state. Upon returning
* from processMessage we will exit all current
- * states, execute the halting() method and then
- * all subsequent messages haltedProcessMesage
+ * states, execute the onHalting() method and then
+ * for all subsequent messages haltedProcessMessage
* will be called.
*/
protected final void transitionToHaltingState() {
@@ -1303,7 +1297,6 @@
mSmHandler.deferMessage(msg);
}
-
/**
* Called when message wasn't handled
*
@@ -1325,7 +1318,7 @@
* transitionToHalting. All subsequent messages will invoke
* {@link StateMachine#haltedProcessMessage(Message)}
*/
- protected void halting() {
+ protected void onHalting() {
}
/**
@@ -1334,7 +1327,7 @@
* ignored. In addition, if this StateMachine created the thread, the thread will
* be stopped after this method returns.
*/
- protected void quitting() {
+ protected void onQuitting() {
}
/**
@@ -1345,33 +1338,77 @@
}
/**
- * Set size of messages to maintain and clears all current messages.
+ * Set number of log records to maintain and clears all current records.
*
* @param maxSize number of messages to maintain at anyone time.
*/
- public final void setProcessedMessagesSize(int maxSize) {
- mSmHandler.setProcessedMessagesSize(maxSize);
+ public final void setLogRecSize(int maxSize) {
+ mSmHandler.mLogRecords.setSize(maxSize);
}
/**
- * @return number of messages processed
+ * @return number of log records
*/
- public final int getProcessedMessagesSize() {
- return mSmHandler.getProcessedMessagesSize();
+ public final int getLogRecSize() {
+ return mSmHandler.mLogRecords.size();
}
/**
- * @return the total number of messages processed
+ * @return the total number of records processed
*/
- public final int getProcessedMessagesCount() {
- return mSmHandler.getProcessedMessagesCount();
+ public final int getLogRecCount() {
+ return mSmHandler.mLogRecords.count();
}
/**
- * @return a processed message information
+ * @return a log record
*/
- public final ProcessedMessageInfo getProcessedMessageInfo(int index) {
- return mSmHandler.getProcessedMessageInfo(index);
+ public final LogRec getLogRec(int index) {
+ return mSmHandler.mLogRecords.get(index);
+ }
+
+ /**
+ * Add the string to LogRecords.
+ *
+ * @param string
+ */
+ protected void addLogRec(String string) {
+ mSmHandler.mLogRecords.add(null, string, null, null);
+ }
+
+ /**
+ * Add the string and state to LogRecords
+ *
+ * @param string
+ * @param state current state
+ */
+ protected void addLogRec(String string, State state) {
+ mSmHandler.mLogRecords.add(null, string, state, null);
+ }
+
+ /**
+ * @return true if msg should be saved in the log, default is true.
+ */
+ protected boolean recordLogRec(Message msg) {
+ return true;
+ }
+
+ /**
+ * Return a string to be logged by LogRec, default
+ * is an empty string. Override if additional information is desired.
+ *
+ * @param msg that was processed
+ * @return information to be logged as a String
+ */
+ protected String getLogRecString(Message msg) {
+ return "";
+ }
+
+ /**
+ * @return the string for msg.what
+ */
+ protected String getWhatToString(int what) {
+ return null;
}
/**
@@ -1548,43 +1585,23 @@
}
/**
- * Conditionally quit the looper and stop execution.
- *
- * This sends the SM_QUIT_MSG to the state machine and
- * if not handled by any state's processMessage then the
- * state machine will be stopped and no further messages
- * will be processed.
+ * Quit the state machine after all currently queued up messages are processed.
*/
- public final void quit() {
- // mSmHandler can be null if the state machine has quit.
+ protected final void quit() {
+ // mSmHandler can be null if the state machine is already stopped.
if (mSmHandler == null) return;
mSmHandler.quit();
}
/**
- * @return ture if msg is quit
+ * Quit the state machine immediately all currently queued messages will be discarded.
*/
- protected final boolean isQuit(Message msg) {
- return mSmHandler.isQuit(msg);
- }
+ protected final void quitNow() {
+ // mSmHandler can be null if the state machine is already stopped.
+ if (mSmHandler == null) return;
- /**
- * @return true if msg should be saved in ProcessedMessage, default is true.
- */
- protected boolean recordProcessedMessage(Message msg) {
- return true;
- }
-
- /**
- * Return message info to be logged by ProcessedMessageInfo, default
- * is an empty string. Override if additional information is desired.
- *
- * @param msg that was processed
- * @return information to be logged as a String
- */
- protected String getMessageInfo(Message msg) {
- return "";
+ mSmHandler.quitNow();
}
/**
@@ -1629,9 +1646,9 @@
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(getName() + ":");
- pw.println(" total messages=" + getProcessedMessagesCount());
- for (int i=0; i < getProcessedMessagesSize(); i++) {
- pw.printf(" msg[%d]: %s\n", i, getProcessedMessageInfo(i));
+ pw.println(" total records=" + getLogRecCount());
+ for (int i=0; i < getLogRecSize(); i++) {
+ pw.printf(" rec[%d]: %s\n", i, getLogRec(i).toString(this));
pw.flush();
}
pw.println("curState=" + getCurrentState().getName());
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 73324c0..cf6029e 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -278,7 +278,7 @@
*/
public boolean showOverflowMenu() {
if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null &&
- mPostedOpenRunnable == null) {
+ mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) {
OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true);
mPostedOpenRunnable = new OpenOverflowRunnable(popup);
// Post this for later; we might still need a layout for the anchor to be right.
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index f54575b..cef6a8f 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -524,6 +524,9 @@
@Override
protected boolean hasDividerBeforeChildAt(int childIndex) {
+ if (childIndex == 0) {
+ return false;
+ }
final View childBefore = getChildAt(childIndex - 1);
final View child = getChildAt(childIndex);
boolean result = false;
diff --git a/core/java/com/google/android/mms/ContentType.java b/core/java/com/google/android/mms/ContentType.java
deleted file mode 100644
index 12a1343..0000000
--- a/core/java/com/google/android/mms/ContentType.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms;
-
-import java.util.ArrayList;
-
-public class ContentType {
- public static final String MMS_MESSAGE = "application/vnd.wap.mms-message";
- // The phony content type for generic PDUs (e.g. ReadOrig.ind,
- // Notification.ind, Delivery.ind).
- public static final String MMS_GENERIC = "application/vnd.wap.mms-generic";
- public static final String MULTIPART_MIXED = "application/vnd.wap.multipart.mixed";
- public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related";
- public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative";
-
- public static final String TEXT_PLAIN = "text/plain";
- public static final String TEXT_HTML = "text/html";
- public static final String TEXT_VCALENDAR = "text/x-vCalendar";
- public static final String TEXT_VCARD = "text/x-vCard";
-
- public static final String IMAGE_UNSPECIFIED = "image/*";
- public static final String IMAGE_JPEG = "image/jpeg";
- public static final String IMAGE_JPG = "image/jpg";
- public static final String IMAGE_GIF = "image/gif";
- public static final String IMAGE_WBMP = "image/vnd.wap.wbmp";
- public static final String IMAGE_PNG = "image/png";
- public static final String IMAGE_X_MS_BMP = "image/x-ms-bmp";
-
- public static final String AUDIO_UNSPECIFIED = "audio/*";
- public static final String AUDIO_AAC = "audio/aac";
- public static final String AUDIO_AMR = "audio/amr";
- public static final String AUDIO_IMELODY = "audio/imelody";
- public static final String AUDIO_MID = "audio/mid";
- public static final String AUDIO_MIDI = "audio/midi";
- public static final String AUDIO_MP3 = "audio/mp3";
- public static final String AUDIO_MPEG3 = "audio/mpeg3";
- public static final String AUDIO_MPEG = "audio/mpeg";
- public static final String AUDIO_MPG = "audio/mpg";
- public static final String AUDIO_MP4 = "audio/mp4";
- public static final String AUDIO_X_MID = "audio/x-mid";
- public static final String AUDIO_X_MIDI = "audio/x-midi";
- public static final String AUDIO_X_MP3 = "audio/x-mp3";
- public static final String AUDIO_X_MPEG3 = "audio/x-mpeg3";
- public static final String AUDIO_X_MPEG = "audio/x-mpeg";
- public static final String AUDIO_X_MPG = "audio/x-mpg";
- public static final String AUDIO_3GPP = "audio/3gpp";
- public static final String AUDIO_X_WAV = "audio/x-wav";
- public static final String AUDIO_OGG = "application/ogg";
-
- public static final String VIDEO_UNSPECIFIED = "video/*";
- public static final String VIDEO_3GPP = "video/3gpp";
- public static final String VIDEO_3G2 = "video/3gpp2";
- public static final String VIDEO_H263 = "video/h263";
- public static final String VIDEO_MP4 = "video/mp4";
-
- public static final String APP_SMIL = "application/smil";
- public static final String APP_WAP_XHTML = "application/vnd.wap.xhtml+xml";
- public static final String APP_XHTML = "application/xhtml+xml";
-
- public static final String APP_DRM_CONTENT = "application/vnd.oma.drm.content";
- public static final String APP_DRM_MESSAGE = "application/vnd.oma.drm.message";
-
- private static final ArrayList<String> sSupportedContentTypes = new ArrayList<String>();
- private static final ArrayList<String> sSupportedImageTypes = new ArrayList<String>();
- private static final ArrayList<String> sSupportedAudioTypes = new ArrayList<String>();
- private static final ArrayList<String> sSupportedVideoTypes = new ArrayList<String>();
-
- static {
- sSupportedContentTypes.add(TEXT_PLAIN);
- sSupportedContentTypes.add(TEXT_HTML);
- sSupportedContentTypes.add(TEXT_VCALENDAR);
- sSupportedContentTypes.add(TEXT_VCARD);
-
- sSupportedContentTypes.add(IMAGE_JPEG);
- sSupportedContentTypes.add(IMAGE_GIF);
- sSupportedContentTypes.add(IMAGE_WBMP);
- sSupportedContentTypes.add(IMAGE_PNG);
- sSupportedContentTypes.add(IMAGE_JPG);
- sSupportedContentTypes.add(IMAGE_X_MS_BMP);
- //supportedContentTypes.add(IMAGE_SVG); not yet supported.
-
- sSupportedContentTypes.add(AUDIO_AAC);
- sSupportedContentTypes.add(AUDIO_AMR);
- sSupportedContentTypes.add(AUDIO_IMELODY);
- sSupportedContentTypes.add(AUDIO_MID);
- sSupportedContentTypes.add(AUDIO_MIDI);
- sSupportedContentTypes.add(AUDIO_MP3);
- sSupportedContentTypes.add(AUDIO_MPEG3);
- sSupportedContentTypes.add(AUDIO_MPEG);
- sSupportedContentTypes.add(AUDIO_MPG);
- sSupportedContentTypes.add(AUDIO_X_MID);
- sSupportedContentTypes.add(AUDIO_X_MIDI);
- sSupportedContentTypes.add(AUDIO_X_MP3);
- sSupportedContentTypes.add(AUDIO_X_MPEG3);
- sSupportedContentTypes.add(AUDIO_X_MPEG);
- sSupportedContentTypes.add(AUDIO_X_MPG);
- sSupportedContentTypes.add(AUDIO_X_WAV);
- sSupportedContentTypes.add(AUDIO_3GPP);
- sSupportedContentTypes.add(AUDIO_OGG);
-
- sSupportedContentTypes.add(VIDEO_3GPP);
- sSupportedContentTypes.add(VIDEO_3G2);
- sSupportedContentTypes.add(VIDEO_H263);
- sSupportedContentTypes.add(VIDEO_MP4);
-
- sSupportedContentTypes.add(APP_SMIL);
- sSupportedContentTypes.add(APP_WAP_XHTML);
- sSupportedContentTypes.add(APP_XHTML);
-
- sSupportedContentTypes.add(APP_DRM_CONTENT);
- sSupportedContentTypes.add(APP_DRM_MESSAGE);
-
- // add supported image types
- sSupportedImageTypes.add(IMAGE_JPEG);
- sSupportedImageTypes.add(IMAGE_GIF);
- sSupportedImageTypes.add(IMAGE_WBMP);
- sSupportedImageTypes.add(IMAGE_PNG);
- sSupportedImageTypes.add(IMAGE_JPG);
- sSupportedImageTypes.add(IMAGE_X_MS_BMP);
-
- // add supported audio types
- sSupportedAudioTypes.add(AUDIO_AAC);
- sSupportedAudioTypes.add(AUDIO_AMR);
- sSupportedAudioTypes.add(AUDIO_IMELODY);
- sSupportedAudioTypes.add(AUDIO_MID);
- sSupportedAudioTypes.add(AUDIO_MIDI);
- sSupportedAudioTypes.add(AUDIO_MP3);
- sSupportedAudioTypes.add(AUDIO_MPEG3);
- sSupportedAudioTypes.add(AUDIO_MPEG);
- sSupportedAudioTypes.add(AUDIO_MPG);
- sSupportedAudioTypes.add(AUDIO_MP4);
- sSupportedAudioTypes.add(AUDIO_X_MID);
- sSupportedAudioTypes.add(AUDIO_X_MIDI);
- sSupportedAudioTypes.add(AUDIO_X_MP3);
- sSupportedAudioTypes.add(AUDIO_X_MPEG3);
- sSupportedAudioTypes.add(AUDIO_X_MPEG);
- sSupportedAudioTypes.add(AUDIO_X_MPG);
- sSupportedAudioTypes.add(AUDIO_X_WAV);
- sSupportedAudioTypes.add(AUDIO_3GPP);
- sSupportedAudioTypes.add(AUDIO_OGG);
-
- // add supported video types
- sSupportedVideoTypes.add(VIDEO_3GPP);
- sSupportedVideoTypes.add(VIDEO_3G2);
- sSupportedVideoTypes.add(VIDEO_H263);
- sSupportedVideoTypes.add(VIDEO_MP4);
- }
-
- // This class should never be instantiated.
- private ContentType() {
- }
-
- public static boolean isSupportedType(String contentType) {
- return (null != contentType) && sSupportedContentTypes.contains(contentType);
- }
-
- public static boolean isSupportedImageType(String contentType) {
- return isImageType(contentType) && isSupportedType(contentType);
- }
-
- public static boolean isSupportedAudioType(String contentType) {
- return isAudioType(contentType) && isSupportedType(contentType);
- }
-
- public static boolean isSupportedVideoType(String contentType) {
- return isVideoType(contentType) && isSupportedType(contentType);
- }
-
- public static boolean isTextType(String contentType) {
- return (null != contentType) && contentType.startsWith("text/");
- }
-
- public static boolean isImageType(String contentType) {
- return (null != contentType) && contentType.startsWith("image/");
- }
-
- public static boolean isAudioType(String contentType) {
- return (null != contentType) && contentType.startsWith("audio/");
- }
-
- public static boolean isVideoType(String contentType) {
- return (null != contentType) && contentType.startsWith("video/");
- }
-
- public static boolean isDrmType(String contentType) {
- return (null != contentType)
- && (contentType.equals(APP_DRM_CONTENT)
- || contentType.equals(APP_DRM_MESSAGE));
- }
-
- public static boolean isUnspecified(String contentType) {
- return (null != contentType) && contentType.endsWith("*");
- }
-
- @SuppressWarnings("unchecked")
- public static ArrayList<String> getImageTypes() {
- return (ArrayList<String>) sSupportedImageTypes.clone();
- }
-
- @SuppressWarnings("unchecked")
- public static ArrayList<String> getAudioTypes() {
- return (ArrayList<String>) sSupportedAudioTypes.clone();
- }
-
- @SuppressWarnings("unchecked")
- public static ArrayList<String> getVideoTypes() {
- return (ArrayList<String>) sSupportedVideoTypes.clone();
- }
-
- @SuppressWarnings("unchecked")
- public static ArrayList<String> getSupportedTypes() {
- return (ArrayList<String>) sSupportedContentTypes.clone();
- }
-}
diff --git a/core/java/com/google/android/mms/InvalidHeaderValueException.java b/core/java/com/google/android/mms/InvalidHeaderValueException.java
deleted file mode 100644
index 73d7832..0000000
--- a/core/java/com/google/android/mms/InvalidHeaderValueException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms;
-
-/**
- * Thrown when an invalid header value was set.
- */
-public class InvalidHeaderValueException extends MmsException {
- private static final long serialVersionUID = -2053384496042052262L;
-
- /**
- * Constructs an InvalidHeaderValueException with no detailed message.
- */
- public InvalidHeaderValueException() {
- super();
- }
-
- /**
- * Constructs an InvalidHeaderValueException with the specified detailed message.
- *
- * @param message the detailed message.
- */
- public InvalidHeaderValueException(String message) {
- super(message);
- }
-}
diff --git a/core/java/com/google/android/mms/MmsException.java b/core/java/com/google/android/mms/MmsException.java
deleted file mode 100644
index 6ca0c7e..0000000
--- a/core/java/com/google/android/mms/MmsException.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms;
-
-/**
- * A generic exception that is thrown by the Mms client.
- */
-public class MmsException extends Exception {
- private static final long serialVersionUID = -7323249827281485390L;
-
- /**
- * Creates a new MmsException.
- */
- public MmsException() {
- super();
- }
-
- /**
- * Creates a new MmsException with the specified detail message.
- *
- * @param message the detail message.
- */
- public MmsException(String message) {
- super(message);
- }
-
- /**
- * Creates a new MmsException with the specified cause.
- *
- * @param cause the cause.
- */
- public MmsException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Creates a new MmsException with the specified detail message and cause.
- *
- * @param message the detail message.
- * @param cause the cause.
- */
- public MmsException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/core/java/com/google/android/mms/package.html b/core/java/com/google/android/mms/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/com/google/android/mms/pdu/AcknowledgeInd.java b/core/java/com/google/android/mms/pdu/AcknowledgeInd.java
deleted file mode 100644
index 0e96c60..0000000
--- a/core/java/com/google/android/mms/pdu/AcknowledgeInd.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-Acknowledge.ind PDU.
- */
-public class AcknowledgeInd extends GenericPdu {
- /**
- * Constructor, used when composing a M-Acknowledge.ind pdu.
- *
- * @param mmsVersion current viersion of mms
- * @param transactionId the transaction-id value
- * @throws InvalidHeaderValueException if parameters are invalid.
- * NullPointerException if transactionId is null.
- */
- public AcknowledgeInd(int mmsVersion, byte[] transactionId)
- throws InvalidHeaderValueException {
- super();
-
- setMessageType(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND);
- setMmsVersion(mmsVersion);
- setTransactionId(transactionId);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- AcknowledgeInd(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Get X-Mms-Report-Allowed field value.
- *
- * @return the X-Mms-Report-Allowed value
- */
- public int getReportAllowed() {
- return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED);
- }
-
- /**
- * Set X-Mms-Report-Allowed field value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setReportAllowed(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED);
- }
-
- /**
- * Get X-Mms-Transaction-Id field value.
- *
- * @return the X-Mms-Report-Allowed value
- */
- public byte[] getTransactionId() {
- return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
- }
-
- /**
- * Set X-Mms-Transaction-Id field value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setTransactionId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/Base64.java b/core/java/com/google/android/mms/pdu/Base64.java
deleted file mode 100644
index 604bee0..0000000
--- a/core/java/com/google/android/mms/pdu/Base64.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-public class Base64 {
- /**
- * Used to get the number of Quadruples.
- */
- static final int FOURBYTE = 4;
-
- /**
- * Byte used to pad output.
- */
- static final byte PAD = (byte) '=';
-
- /**
- * The base length.
- */
- static final int BASELENGTH = 255;
-
- // Create arrays to hold the base64 characters
- private static byte[] base64Alphabet = new byte[BASELENGTH];
-
- // Populating the character arrays
- static {
- for (int i = 0; i < BASELENGTH; i++) {
- base64Alphabet[i] = (byte) -1;
- }
- for (int i = 'Z'; i >= 'A'; i--) {
- base64Alphabet[i] = (byte) (i - 'A');
- }
- for (int i = 'z'; i >= 'a'; i--) {
- base64Alphabet[i] = (byte) (i - 'a' + 26);
- }
- for (int i = '9'; i >= '0'; i--) {
- base64Alphabet[i] = (byte) (i - '0' + 52);
- }
-
- base64Alphabet['+'] = 62;
- base64Alphabet['/'] = 63;
- }
-
- /**
- * Decodes Base64 data into octects
- *
- * @param base64Data Byte array containing Base64 data
- * @return Array containing decoded data.
- */
- public static byte[] decodeBase64(byte[] base64Data) {
- // RFC 2045 requires that we discard ALL non-Base64 characters
- base64Data = discardNonBase64(base64Data);
-
- // handle the edge case, so we don't have to worry about it later
- if (base64Data.length == 0) {
- return new byte[0];
- }
-
- int numberQuadruple = base64Data.length / FOURBYTE;
- byte decodedData[] = null;
- byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
-
- // Throw away anything not in base64Data
-
- int encodedIndex = 0;
- int dataIndex = 0;
- {
- // this sizes the output array properly - rlw
- int lastData = base64Data.length;
- // ignore the '=' padding
- while (base64Data[lastData - 1] == PAD) {
- if (--lastData == 0) {
- return new byte[0];
- }
- }
- decodedData = new byte[lastData - numberQuadruple];
- }
-
- for (int i = 0; i < numberQuadruple; i++) {
- dataIndex = i * 4;
- marker0 = base64Data[dataIndex + 2];
- marker1 = base64Data[dataIndex + 3];
-
- b1 = base64Alphabet[base64Data[dataIndex]];
- b2 = base64Alphabet[base64Data[dataIndex + 1]];
-
- if (marker0 != PAD && marker1 != PAD) {
- //No PAD e.g 3cQl
- b3 = base64Alphabet[marker0];
- b4 = base64Alphabet[marker1];
-
- decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
- decodedData[encodedIndex + 1] =
- (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
- decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
- } else if (marker0 == PAD) {
- //Two PAD e.g. 3c[Pad][Pad]
- decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
- } else if (marker1 == PAD) {
- //One PAD e.g. 3cQ[Pad]
- b3 = base64Alphabet[marker0];
-
- decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
- decodedData[encodedIndex + 1] =
- (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
- }
- encodedIndex += 3;
- }
- return decodedData;
- }
-
- /**
- * Check octect wheter it is a base64 encoding.
- *
- * @param octect to be checked byte
- * @return ture if it is base64 encoding, false otherwise.
- */
- private static boolean isBase64(byte octect) {
- if (octect == PAD) {
- return true;
- } else if (base64Alphabet[octect] == -1) {
- return false;
- } else {
- return true;
- }
- }
-
- /**
- * Discards any characters outside of the base64 alphabet, per
- * the requirements on page 25 of RFC 2045 - "Any characters
- * outside of the base64 alphabet are to be ignored in base64
- * encoded data."
- *
- * @param data The base-64 encoded data to groom
- * @return The data, less non-base64 characters (see RFC 2045).
- */
- static byte[] discardNonBase64(byte[] data) {
- byte groomedData[] = new byte[data.length];
- int bytesCopied = 0;
-
- for (int i = 0; i < data.length; i++) {
- if (isBase64(data[i])) {
- groomedData[bytesCopied++] = data[i];
- }
- }
-
- byte packedData[] = new byte[bytesCopied];
-
- System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
-
- return packedData;
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/CharacterSets.java b/core/java/com/google/android/mms/pdu/CharacterSets.java
deleted file mode 100644
index 4e22ca5..0000000
--- a/core/java/com/google/android/mms/pdu/CharacterSets.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-
-public class CharacterSets {
- /**
- * IANA assigned MIB enum numbers.
- *
- * From wap-230-wsp-20010705-a.pdf
- * Any-charset = <Octet 128>
- * Equivalent to the special RFC2616 charset value "*"
- */
- public static final int ANY_CHARSET = 0x00;
- public static final int US_ASCII = 0x03;
- public static final int ISO_8859_1 = 0x04;
- public static final int ISO_8859_2 = 0x05;
- public static final int ISO_8859_3 = 0x06;
- public static final int ISO_8859_4 = 0x07;
- public static final int ISO_8859_5 = 0x08;
- public static final int ISO_8859_6 = 0x09;
- public static final int ISO_8859_7 = 0x0A;
- public static final int ISO_8859_8 = 0x0B;
- public static final int ISO_8859_9 = 0x0C;
- public static final int SHIFT_JIS = 0x11;
- public static final int UTF_8 = 0x6A;
- public static final int BIG5 = 0x07EA;
- public static final int UCS2 = 0x03E8;
- public static final int UTF_16 = 0x03F7;
-
- /**
- * If the encoding of given data is unsupported, use UTF_8 to decode it.
- */
- public static final int DEFAULT_CHARSET = UTF_8;
-
- /**
- * Array of MIB enum numbers.
- */
- private static final int[] MIBENUM_NUMBERS = {
- ANY_CHARSET,
- US_ASCII,
- ISO_8859_1,
- ISO_8859_2,
- ISO_8859_3,
- ISO_8859_4,
- ISO_8859_5,
- ISO_8859_6,
- ISO_8859_7,
- ISO_8859_8,
- ISO_8859_9,
- SHIFT_JIS,
- UTF_8,
- BIG5,
- UCS2,
- UTF_16,
- };
-
- /**
- * The Well-known-charset Mime name.
- */
- public static final String MIMENAME_ANY_CHARSET = "*";
- public static final String MIMENAME_US_ASCII = "us-ascii";
- public static final String MIMENAME_ISO_8859_1 = "iso-8859-1";
- public static final String MIMENAME_ISO_8859_2 = "iso-8859-2";
- public static final String MIMENAME_ISO_8859_3 = "iso-8859-3";
- public static final String MIMENAME_ISO_8859_4 = "iso-8859-4";
- public static final String MIMENAME_ISO_8859_5 = "iso-8859-5";
- public static final String MIMENAME_ISO_8859_6 = "iso-8859-6";
- public static final String MIMENAME_ISO_8859_7 = "iso-8859-7";
- public static final String MIMENAME_ISO_8859_8 = "iso-8859-8";
- public static final String MIMENAME_ISO_8859_9 = "iso-8859-9";
- public static final String MIMENAME_SHIFT_JIS = "shift_JIS";
- public static final String MIMENAME_UTF_8 = "utf-8";
- public static final String MIMENAME_BIG5 = "big5";
- public static final String MIMENAME_UCS2 = "iso-10646-ucs-2";
- public static final String MIMENAME_UTF_16 = "utf-16";
-
- public static final String DEFAULT_CHARSET_NAME = MIMENAME_UTF_8;
-
- /**
- * Array of the names of character sets.
- */
- private static final String[] MIME_NAMES = {
- MIMENAME_ANY_CHARSET,
- MIMENAME_US_ASCII,
- MIMENAME_ISO_8859_1,
- MIMENAME_ISO_8859_2,
- MIMENAME_ISO_8859_3,
- MIMENAME_ISO_8859_4,
- MIMENAME_ISO_8859_5,
- MIMENAME_ISO_8859_6,
- MIMENAME_ISO_8859_7,
- MIMENAME_ISO_8859_8,
- MIMENAME_ISO_8859_9,
- MIMENAME_SHIFT_JIS,
- MIMENAME_UTF_8,
- MIMENAME_BIG5,
- MIMENAME_UCS2,
- MIMENAME_UTF_16,
- };
-
- private static final HashMap<Integer, String> MIBENUM_TO_NAME_MAP;
- private static final HashMap<String, Integer> NAME_TO_MIBENUM_MAP;
-
- static {
- // Create the HashMaps.
- MIBENUM_TO_NAME_MAP = new HashMap<Integer, String>();
- NAME_TO_MIBENUM_MAP = new HashMap<String, Integer>();
- assert(MIBENUM_NUMBERS.length == MIME_NAMES.length);
- int count = MIBENUM_NUMBERS.length - 1;
- for(int i = 0; i <= count; i++) {
- MIBENUM_TO_NAME_MAP.put(MIBENUM_NUMBERS[i], MIME_NAMES[i]);
- NAME_TO_MIBENUM_MAP.put(MIME_NAMES[i], MIBENUM_NUMBERS[i]);
- }
- }
-
- private CharacterSets() {} // Non-instantiatable
-
- /**
- * Map an MIBEnum number to the name of the charset which this number
- * is assigned to by IANA.
- *
- * @param mibEnumValue An IANA assigned MIBEnum number.
- * @return The name string of the charset.
- * @throws UnsupportedEncodingException
- */
- public static String getMimeName(int mibEnumValue)
- throws UnsupportedEncodingException {
- String name = MIBENUM_TO_NAME_MAP.get(mibEnumValue);
- if (name == null) {
- throw new UnsupportedEncodingException();
- }
- return name;
- }
-
- /**
- * Map a well-known charset name to its assigned MIBEnum number.
- *
- * @param mimeName The charset name.
- * @return The MIBEnum number assigned by IANA for this charset.
- * @throws UnsupportedEncodingException
- */
- public static int getMibEnumValue(String mimeName)
- throws UnsupportedEncodingException {
- if(null == mimeName) {
- return -1;
- }
-
- Integer mibEnumValue = NAME_TO_MIBENUM_MAP.get(mimeName);
- if (mibEnumValue == null) {
- throw new UnsupportedEncodingException();
- }
- return mibEnumValue;
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/DeliveryInd.java b/core/java/com/google/android/mms/pdu/DeliveryInd.java
deleted file mode 100644
index dafa8d1..0000000
--- a/core/java/com/google/android/mms/pdu/DeliveryInd.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-Delivery.Ind Pdu.
- */
-public class DeliveryInd extends GenericPdu {
- /**
- * Empty constructor.
- * Since the Pdu corresponding to this class is constructed
- * by the Proxy-Relay server, this class is only instantiated
- * by the Pdu Parser.
- *
- * @throws InvalidHeaderValueException if error occurs.
- */
- public DeliveryInd() throws InvalidHeaderValueException {
- super();
- setMessageType(PduHeaders.MESSAGE_TYPE_DELIVERY_IND);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- DeliveryInd(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Get Date value.
- *
- * @return the value
- */
- public long getDate() {
- return mPduHeaders.getLongInteger(PduHeaders.DATE);
- }
-
- /**
- * Set Date value.
- *
- * @param value the value
- */
- public void setDate(long value) {
- mPduHeaders.setLongInteger(value, PduHeaders.DATE);
- }
-
- /**
- * Get Message-ID value.
- *
- * @return the value
- */
- public byte[] getMessageId() {
- return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Set Message-ID value.
- *
- * @param value the value, should not be null
- * @throws NullPointerException if the value is null.
- */
- public void setMessageId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Get Status value.
- *
- * @return the value
- */
- public int getStatus() {
- return mPduHeaders.getOctet(PduHeaders.STATUS);
- }
-
- /**
- * Set Status value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setStatus(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.STATUS);
- }
-
- /**
- * Get To value.
- *
- * @return the value
- */
- public EncodedStringValue[] getTo() {
- return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
- }
-
- /**
- * set To value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setTo(EncodedStringValue[] value) {
- mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
- }
-
- /*
- * Optional, not supported header fields:
- *
- * public byte[] getApplicId() {return null;}
- * public void setApplicId(byte[] value) {}
- *
- * public byte[] getAuxApplicId() {return null;}
- * public void getAuxApplicId(byte[] value) {}
- *
- * public byte[] getReplyApplicId() {return 0x00;}
- * public void setReplyApplicId(byte[] value) {}
- *
- * public EncodedStringValue getStatusText() {return null;}
- * public void setStatusText(EncodedStringValue value) {}
- */
-}
diff --git a/core/java/com/google/android/mms/pdu/EncodedStringValue.java b/core/java/com/google/android/mms/pdu/EncodedStringValue.java
deleted file mode 100644
index 9495c1c..0000000
--- a/core/java/com/google/android/mms/pdu/EncodedStringValue.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-
-/**
- * Encoded-string-value = Text-string | Value-length Char-set Text-string
- */
-public class EncodedStringValue implements Cloneable {
- private static final String TAG = "EncodedStringValue";
- private static final boolean DEBUG = false;
- private static final boolean LOCAL_LOGV = false;
-
- /**
- * The Char-set value.
- */
- private int mCharacterSet;
-
- /**
- * The Text-string value.
- */
- private byte[] mData;
-
- /**
- * Constructor.
- *
- * @param charset the Char-set value
- * @param data the Text-string value
- * @throws NullPointerException if Text-string value is null.
- */
- public EncodedStringValue(int charset, byte[] data) {
- // TODO: CharSet needs to be validated against MIBEnum.
- if(null == data) {
- throw new NullPointerException("EncodedStringValue: Text-string is null.");
- }
-
- mCharacterSet = charset;
- mData = new byte[data.length];
- System.arraycopy(data, 0, mData, 0, data.length);
- }
-
- /**
- * Constructor.
- *
- * @param data the Text-string value
- * @throws NullPointerException if Text-string value is null.
- */
- public EncodedStringValue(byte[] data) {
- this(CharacterSets.DEFAULT_CHARSET, data);
- }
-
- public EncodedStringValue(String data) {
- try {
- mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME);
- mCharacterSet = CharacterSets.DEFAULT_CHARSET;
- } catch (UnsupportedEncodingException e) {
- Log.e(TAG, "Default encoding must be supported.", e);
- }
- }
-
- /**
- * Get Char-set value.
- *
- * @return the value
- */
- public int getCharacterSet() {
- return mCharacterSet;
- }
-
- /**
- * Set Char-set value.
- *
- * @param charset the Char-set value
- */
- public void setCharacterSet(int charset) {
- // TODO: CharSet needs to be validated against MIBEnum.
- mCharacterSet = charset;
- }
-
- /**
- * Get Text-string value.
- *
- * @return the value
- */
- public byte[] getTextString() {
- byte[] byteArray = new byte[mData.length];
-
- System.arraycopy(mData, 0, byteArray, 0, mData.length);
- return byteArray;
- }
-
- /**
- * Set Text-string value.
- *
- * @param textString the Text-string value
- * @throws NullPointerException if Text-string value is null.
- */
- public void setTextString(byte[] textString) {
- if(null == textString) {
- throw new NullPointerException("EncodedStringValue: Text-string is null.");
- }
-
- mData = new byte[textString.length];
- System.arraycopy(textString, 0, mData, 0, textString.length);
- }
-
- /**
- * Convert this object to a {@link java.lang.String}. If the encoding of
- * the EncodedStringValue is null or unsupported, it will be
- * treated as iso-8859-1 encoding.
- *
- * @return The decoded String.
- */
- public String getString() {
- if (CharacterSets.ANY_CHARSET == mCharacterSet) {
- return new String(mData); // system default encoding.
- } else {
- try {
- String name = CharacterSets.getMimeName(mCharacterSet);
- return new String(mData, name);
- } catch (UnsupportedEncodingException e) {
- if (LOCAL_LOGV) {
- Log.v(TAG, e.getMessage(), e);
- }
- try {
- return new String(mData, CharacterSets.MIMENAME_ISO_8859_1);
- } catch (UnsupportedEncodingException _) {
- return new String(mData); // system default encoding.
- }
- }
- }
- }
-
- /**
- * Append to Text-string.
- *
- * @param textString the textString to append
- * @throws NullPointerException if the text String is null
- * or an IOException occured.
- */
- public void appendTextString(byte[] textString) {
- if(null == textString) {
- throw new NullPointerException("Text-string is null.");
- }
-
- if(null == mData) {
- mData = new byte[textString.length];
- System.arraycopy(textString, 0, mData, 0, textString.length);
- } else {
- ByteArrayOutputStream newTextString = new ByteArrayOutputStream();
- try {
- newTextString.write(mData);
- newTextString.write(textString);
- } catch (IOException e) {
- e.printStackTrace();
- throw new NullPointerException(
- "appendTextString: failed when write a new Text-string");
- }
-
- mData = newTextString.toByteArray();
- }
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Object#clone()
- */
- @Override
- public Object clone() throws CloneNotSupportedException {
- super.clone();
- int len = mData.length;
- byte[] dstBytes = new byte[len];
- System.arraycopy(mData, 0, dstBytes, 0, len);
-
- try {
- return new EncodedStringValue(mCharacterSet, dstBytes);
- } catch (Exception e) {
- Log.e(TAG, "failed to clone an EncodedStringValue: " + this);
- e.printStackTrace();
- throw new CloneNotSupportedException(e.getMessage());
- }
- }
-
- /**
- * Split this encoded string around matches of the given pattern.
- *
- * @param pattern the delimiting pattern
- * @return the array of encoded strings computed by splitting this encoded
- * string around matches of the given pattern
- */
- public EncodedStringValue[] split(String pattern) {
- String[] temp = getString().split(pattern);
- EncodedStringValue[] ret = new EncodedStringValue[temp.length];
- for (int i = 0; i < ret.length; ++i) {
- try {
- ret[i] = new EncodedStringValue(mCharacterSet,
- temp[i].getBytes());
- } catch (NullPointerException _) {
- // Can't arrive here
- return null;
- }
- }
- return ret;
- }
-
- /**
- * Extract an EncodedStringValue[] from a given String.
- */
- public static EncodedStringValue[] extract(String src) {
- String[] values = src.split(";");
-
- ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>();
- for (int i = 0; i < values.length; i++) {
- if (values[i].length() > 0) {
- list.add(new EncodedStringValue(values[i]));
- }
- }
-
- int len = list.size();
- if (len > 0) {
- return list.toArray(new EncodedStringValue[len]);
- } else {
- return null;
- }
- }
-
- /**
- * Concatenate an EncodedStringValue[] into a single String.
- */
- public static String concat(EncodedStringValue[] addr) {
- StringBuilder sb = new StringBuilder();
- int maxIndex = addr.length - 1;
- for (int i = 0; i <= maxIndex; i++) {
- sb.append(addr[i].getString());
- if (i < maxIndex) {
- sb.append(";");
- }
- }
-
- return sb.toString();
- }
-
- public static EncodedStringValue copy(EncodedStringValue value) {
- if (value == null) {
- return null;
- }
-
- return new EncodedStringValue(value.mCharacterSet, value.mData);
- }
-
- public static EncodedStringValue[] encodeStrings(String[] array) {
- int count = array.length;
- if (count > 0) {
- EncodedStringValue[] encodedArray = new EncodedStringValue[count];
- for (int i = 0; i < count; i++) {
- encodedArray[i] = new EncodedStringValue(array[i]);
- }
- return encodedArray;
- }
- return null;
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/GenericPdu.java b/core/java/com/google/android/mms/pdu/GenericPdu.java
deleted file mode 100644
index 705de6a..0000000
--- a/core/java/com/google/android/mms/pdu/GenericPdu.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class GenericPdu {
- /**
- * The headers of pdu.
- */
- PduHeaders mPduHeaders = null;
-
- /**
- * Constructor.
- */
- public GenericPdu() {
- mPduHeaders = new PduHeaders();
- }
-
- /**
- * Constructor.
- *
- * @param headers Headers for this PDU.
- */
- GenericPdu(PduHeaders headers) {
- mPduHeaders = headers;
- }
-
- /**
- * Get the headers of this PDU.
- *
- * @return A PduHeaders of this PDU.
- */
- PduHeaders getPduHeaders() {
- return mPduHeaders;
- }
-
- /**
- * Get X-Mms-Message-Type field value.
- *
- * @return the X-Mms-Report-Allowed value
- */
- public int getMessageType() {
- return mPduHeaders.getOctet(PduHeaders.MESSAGE_TYPE);
- }
-
- /**
- * Set X-Mms-Message-Type field value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- * RuntimeException if field's value is not Octet.
- */
- public void setMessageType(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.MESSAGE_TYPE);
- }
-
- /**
- * Get X-Mms-MMS-Version field value.
- *
- * @return the X-Mms-MMS-Version value
- */
- public int getMmsVersion() {
- return mPduHeaders.getOctet(PduHeaders.MMS_VERSION);
- }
-
- /**
- * Set X-Mms-MMS-Version field value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- * RuntimeException if field's value is not Octet.
- */
- public void setMmsVersion(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.MMS_VERSION);
- }
-
- /**
- * Get From value.
- * From-value = Value-length
- * (Address-present-token Encoded-string-value | Insert-address-token)
- *
- * @return the value
- */
- public EncodedStringValue getFrom() {
- return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
- }
-
- /**
- * Set From value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setFrom(EncodedStringValue value) {
- mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java b/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java
deleted file mode 100644
index 5a85e0e..0000000
--- a/core/java/com/google/android/mms/pdu/MultimediaMessagePdu.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * Multimedia message PDU.
- */
-public class MultimediaMessagePdu extends GenericPdu{
- /**
- * The body.
- */
- private PduBody mMessageBody;
-
- /**
- * Constructor.
- */
- public MultimediaMessagePdu() {
- super();
- }
-
- /**
- * Constructor.
- *
- * @param header the header of this PDU
- * @param body the body of this PDU
- */
- public MultimediaMessagePdu(PduHeaders header, PduBody body) {
- super(header);
- mMessageBody = body;
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- MultimediaMessagePdu(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Get body of the PDU.
- *
- * @return the body
- */
- public PduBody getBody() {
- return mMessageBody;
- }
-
- /**
- * Set body of the PDU.
- *
- * @param body the body
- */
- public void setBody(PduBody body) {
- mMessageBody = body;
- }
-
- /**
- * Get subject.
- *
- * @return the value
- */
- public EncodedStringValue getSubject() {
- return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT);
- }
-
- /**
- * Set subject.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setSubject(EncodedStringValue value) {
- mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT);
- }
-
- /**
- * Get To value.
- *
- * @return the value
- */
- public EncodedStringValue[] getTo() {
- return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
- }
-
- /**
- * Add a "To" value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void addTo(EncodedStringValue value) {
- mPduHeaders.appendEncodedStringValue(value, PduHeaders.TO);
- }
-
- /**
- * Get X-Mms-Priority value.
- *
- * @return the value
- */
- public int getPriority() {
- return mPduHeaders.getOctet(PduHeaders.PRIORITY);
- }
-
- /**
- * Set X-Mms-Priority value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setPriority(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.PRIORITY);
- }
-
- /**
- * Get Date value.
- *
- * @return the value
- */
- public long getDate() {
- return mPduHeaders.getLongInteger(PduHeaders.DATE);
- }
-
- /**
- * Set Date value in seconds.
- *
- * @param value the value
- */
- public void setDate(long value) {
- mPduHeaders.setLongInteger(value, PduHeaders.DATE);
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/NotificationInd.java b/core/java/com/google/android/mms/pdu/NotificationInd.java
deleted file mode 100644
index c56cba6..0000000
--- a/core/java/com/google/android/mms/pdu/NotificationInd.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-Notification.ind PDU.
- */
-public class NotificationInd extends GenericPdu {
- /**
- * Empty constructor.
- * Since the Pdu corresponding to this class is constructed
- * by the Proxy-Relay server, this class is only instantiated
- * by the Pdu Parser.
- *
- * @throws InvalidHeaderValueException if error occurs.
- * RuntimeException if an undeclared error occurs.
- */
- public NotificationInd() throws InvalidHeaderValueException {
- super();
- setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- NotificationInd(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Get X-Mms-Content-Class Value.
- *
- * @return the value
- */
- public int getContentClass() {
- return mPduHeaders.getOctet(PduHeaders.CONTENT_CLASS);
- }
-
- /**
- * Set X-Mms-Content-Class Value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- * RuntimeException if an undeclared error occurs.
- */
- public void setContentClass(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.CONTENT_CLASS);
- }
-
- /**
- * Get X-Mms-Content-Location value.
- * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
- * Content-location-value = Uri-value
- *
- * @return the value
- */
- public byte[] getContentLocation() {
- return mPduHeaders.getTextString(PduHeaders.CONTENT_LOCATION);
- }
-
- /**
- * Set X-Mms-Content-Location value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- * RuntimeException if an undeclared error occurs.
- */
- public void setContentLocation(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.CONTENT_LOCATION);
- }
-
- /**
- * Get X-Mms-Expiry value.
- *
- * Expiry-value = Value-length
- * (Absolute-token Date-value | Relative-token Delta-seconds-value)
- *
- * @return the value
- */
- public long getExpiry() {
- return mPduHeaders.getLongInteger(PduHeaders.EXPIRY);
- }
-
- /**
- * Set X-Mms-Expiry value.
- *
- * @param value the value
- * @throws RuntimeException if an undeclared error occurs.
- */
- public void setExpiry(long value) {
- mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY);
- }
-
- /**
- * Get From value.
- * From-value = Value-length
- * (Address-present-token Encoded-string-value | Insert-address-token)
- *
- * @return the value
- */
- public EncodedStringValue getFrom() {
- return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
- }
-
- /**
- * Set From value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- * RuntimeException if an undeclared error occurs.
- */
- public void setFrom(EncodedStringValue value) {
- mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
- }
-
- /**
- * Get X-Mms-Message-Class value.
- * Message-class-value = Class-identifier | Token-text
- * Class-identifier = Personal | Advertisement | Informational | Auto
- *
- * @return the value
- */
- public byte[] getMessageClass() {
- return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
- }
-
- /**
- * Set X-Mms-Message-Class value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- * RuntimeException if an undeclared error occurs.
- */
- public void setMessageClass(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
- }
-
- /**
- * Get X-Mms-Message-Size value.
- * Message-size-value = Long-integer
- *
- * @return the value
- */
- public long getMessageSize() {
- return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE);
- }
-
- /**
- * Set X-Mms-Message-Size value.
- *
- * @param value the value
- * @throws RuntimeException if an undeclared error occurs.
- */
- public void setMessageSize(long value) {
- mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE);
- }
-
- /**
- * Get subject.
- *
- * @return the value
- */
- public EncodedStringValue getSubject() {
- return mPduHeaders.getEncodedStringValue(PduHeaders.SUBJECT);
- }
-
- /**
- * Set subject.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- * RuntimeException if an undeclared error occurs.
- */
- public void setSubject(EncodedStringValue value) {
- mPduHeaders.setEncodedStringValue(value, PduHeaders.SUBJECT);
- }
-
- /**
- * Get X-Mms-Transaction-Id.
- *
- * @return the value
- */
- public byte[] getTransactionId() {
- return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
- }
-
- /**
- * Set X-Mms-Transaction-Id.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- * RuntimeException if an undeclared error occurs.
- */
- public void setTransactionId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
- }
-
- /**
- * Get X-Mms-Delivery-Report Value.
- *
- * @return the value
- */
- public int getDeliveryReport() {
- return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
- }
-
- /**
- * Set X-Mms-Delivery-Report Value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- * RuntimeException if an undeclared error occurs.
- */
- public void setDeliveryReport(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
- }
-
- /*
- * Optional, not supported header fields:
- *
- * public byte[] getApplicId() {return null;}
- * public void setApplicId(byte[] value) {}
- *
- * public byte[] getAuxApplicId() {return null;}
- * public void getAuxApplicId(byte[] value) {}
- *
- * public byte getDrmContent() {return 0x00;}
- * public void setDrmContent(byte value) {}
- *
- * public byte getDistributionIndicator() {return 0x00;}
- * public void setDistributionIndicator(byte value) {}
- *
- * public ElementDescriptorValue getElementDescriptor() {return null;}
- * public void getElementDescriptor(ElementDescriptorValue value) {}
- *
- * public byte getPriority() {return 0x00;}
- * public void setPriority(byte value) {}
- *
- * public byte getRecommendedRetrievalMode() {return 0x00;}
- * public void setRecommendedRetrievalMode(byte value) {}
- *
- * public byte getRecommendedRetrievalModeText() {return 0x00;}
- * public void setRecommendedRetrievalModeText(byte value) {}
- *
- * public byte[] getReplaceId() {return 0x00;}
- * public void setReplaceId(byte[] value) {}
- *
- * public byte[] getReplyApplicId() {return 0x00;}
- * public void setReplyApplicId(byte[] value) {}
- *
- * public byte getReplyCharging() {return 0x00;}
- * public void setReplyCharging(byte value) {}
- *
- * public byte getReplyChargingDeadline() {return 0x00;}
- * public void setReplyChargingDeadline(byte value) {}
- *
- * public byte[] getReplyChargingId() {return 0x00;}
- * public void setReplyChargingId(byte[] value) {}
- *
- * public long getReplyChargingSize() {return 0;}
- * public void setReplyChargingSize(long value) {}
- *
- * public byte getStored() {return 0x00;}
- * public void setStored(byte value) {}
- */
-}
diff --git a/core/java/com/google/android/mms/pdu/NotifyRespInd.java b/core/java/com/google/android/mms/pdu/NotifyRespInd.java
deleted file mode 100644
index 2cc2fce..0000000
--- a/core/java/com/google/android/mms/pdu/NotifyRespInd.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-NofifyResp.ind PDU.
- */
-public class NotifyRespInd extends GenericPdu {
- /**
- * Constructor, used when composing a M-NotifyResp.ind pdu.
- *
- * @param mmsVersion current version of mms
- * @param transactionId the transaction-id value
- * @param status the status value
- * @throws InvalidHeaderValueException if parameters are invalid.
- * NullPointerException if transactionId is null.
- * RuntimeException if an undeclared error occurs.
- */
- public NotifyRespInd(int mmsVersion,
- byte[] transactionId,
- int status) throws InvalidHeaderValueException {
- super();
- setMessageType(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND);
- setMmsVersion(mmsVersion);
- setTransactionId(transactionId);
- setStatus(status);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- NotifyRespInd(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Get X-Mms-Report-Allowed field value.
- *
- * @return the X-Mms-Report-Allowed value
- */
- public int getReportAllowed() {
- return mPduHeaders.getOctet(PduHeaders.REPORT_ALLOWED);
- }
-
- /**
- * Set X-Mms-Report-Allowed field value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- * RuntimeException if an undeclared error occurs.
- */
- public void setReportAllowed(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.REPORT_ALLOWED);
- }
-
- /**
- * Set X-Mms-Status field value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- * RuntimeException if an undeclared error occurs.
- */
- public void setStatus(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.STATUS);
- }
-
- /**
- * GetX-Mms-Status field value.
- *
- * @return the X-Mms-Status value
- */
- public int getStatus() {
- return mPduHeaders.getOctet(PduHeaders.STATUS);
- }
-
- /**
- * Get X-Mms-Transaction-Id field value.
- *
- * @return the X-Mms-Report-Allowed value
- */
- public byte[] getTransactionId() {
- return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
- }
-
- /**
- * Set X-Mms-Transaction-Id field value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- * RuntimeException if an undeclared error occurs.
- */
- public void setTransactionId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduBody.java b/core/java/com/google/android/mms/pdu/PduBody.java
deleted file mode 100644
index fa0416c..0000000
--- a/core/java/com/google/android/mms/pdu/PduBody.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-public class PduBody {
- private Vector<PduPart> mParts = null;
-
- private Map<String, PduPart> mPartMapByContentId = null;
- private Map<String, PduPart> mPartMapByContentLocation = null;
- private Map<String, PduPart> mPartMapByName = null;
- private Map<String, PduPart> mPartMapByFileName = null;
-
- /**
- * Constructor.
- */
- public PduBody() {
- mParts = new Vector<PduPart>();
-
- mPartMapByContentId = new HashMap<String, PduPart>();
- mPartMapByContentLocation = new HashMap<String, PduPart>();
- mPartMapByName = new HashMap<String, PduPart>();
- mPartMapByFileName = new HashMap<String, PduPart>();
- }
-
- private void putPartToMaps(PduPart part) {
- // Put part to mPartMapByContentId.
- byte[] contentId = part.getContentId();
- if(null != contentId) {
- mPartMapByContentId.put(new String(contentId), part);
- }
-
- // Put part to mPartMapByContentLocation.
- byte[] contentLocation = part.getContentLocation();
- if(null != contentLocation) {
- String clc = new String(contentLocation);
- mPartMapByContentLocation.put(clc, part);
- }
-
- // Put part to mPartMapByName.
- byte[] name = part.getName();
- if(null != name) {
- String clc = new String(name);
- mPartMapByName.put(clc, part);
- }
-
- // Put part to mPartMapByFileName.
- byte[] fileName = part.getFilename();
- if(null != fileName) {
- String clc = new String(fileName);
- mPartMapByFileName.put(clc, part);
- }
- }
-
- /**
- * Appends the specified part to the end of this body.
- *
- * @param part part to be appended
- * @return true when success, false when fail
- * @throws NullPointerException when part is null
- */
- public boolean addPart(PduPart part) {
- if(null == part) {
- throw new NullPointerException();
- }
-
- putPartToMaps(part);
- return mParts.add(part);
- }
-
- /**
- * Inserts the specified part at the specified position.
- *
- * @param index index at which the specified part is to be inserted
- * @param part part to be inserted
- * @throws NullPointerException when part is null
- */
- public void addPart(int index, PduPart part) {
- if(null == part) {
- throw new NullPointerException();
- }
-
- putPartToMaps(part);
- mParts.add(index, part);
- }
-
- /**
- * Removes the part at the specified position.
- *
- * @param index index of the part to return
- * @return part at the specified index
- */
- public PduPart removePart(int index) {
- return mParts.remove(index);
- }
-
- /**
- * Remove all of the parts.
- */
- public void removeAll() {
- mParts.clear();
- }
-
- /**
- * Get the part at the specified position.
- *
- * @param index index of the part to return
- * @return part at the specified index
- */
- public PduPart getPart(int index) {
- return mParts.get(index);
- }
-
- /**
- * Get the index of the specified part.
- *
- * @param part the part object
- * @return index the index of the first occurrence of the part in this body
- */
- public int getPartIndex(PduPart part) {
- return mParts.indexOf(part);
- }
-
- /**
- * Get the number of parts.
- *
- * @return the number of parts
- */
- public int getPartsNum() {
- return mParts.size();
- }
-
- /**
- * Get pdu part by content id.
- *
- * @param cid the value of content id.
- * @return the pdu part.
- */
- public PduPart getPartByContentId(String cid) {
- return mPartMapByContentId.get(cid);
- }
-
- /**
- * Get pdu part by Content-Location. Content-Location of part is
- * the same as filename and name(param of content-type).
- *
- * @param fileName the value of filename.
- * @return the pdu part.
- */
- public PduPart getPartByContentLocation(String contentLocation) {
- return mPartMapByContentLocation.get(contentLocation);
- }
-
- /**
- * Get pdu part by name.
- *
- * @param fileName the value of filename.
- * @return the pdu part.
- */
- public PduPart getPartByName(String name) {
- return mPartMapByName.get(name);
- }
-
- /**
- * Get pdu part by filename.
- *
- * @param fileName the value of filename.
- * @return the pdu part.
- */
- public PduPart getPartByFileName(String filename) {
- return mPartMapByFileName.get(filename);
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduComposer.java b/core/java/com/google/android/mms/pdu/PduComposer.java
deleted file mode 100644
index d426f89..0000000
--- a/core/java/com/google/android/mms/pdu/PduComposer.java
+++ /dev/null
@@ -1,1179 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.util.Log;
-import android.text.TextUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class PduComposer {
- /**
- * Address type.
- */
- static private final int PDU_PHONE_NUMBER_ADDRESS_TYPE = 1;
- static private final int PDU_EMAIL_ADDRESS_TYPE = 2;
- static private final int PDU_IPV4_ADDRESS_TYPE = 3;
- static private final int PDU_IPV6_ADDRESS_TYPE = 4;
- static private final int PDU_UNKNOWN_ADDRESS_TYPE = 5;
-
- /**
- * Address regular expression string.
- */
- static final String REGEXP_PHONE_NUMBER_ADDRESS_TYPE = "\\+?[0-9|\\.|\\-]+";
- static final String REGEXP_EMAIL_ADDRESS_TYPE = "[a-zA-Z| ]*\\<{0,1}[a-zA-Z| ]+@{1}" +
- "[a-zA-Z| ]+\\.{1}[a-zA-Z| ]+\\>{0,1}";
- static final String REGEXP_IPV6_ADDRESS_TYPE =
- "[a-fA-F]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" +
- "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}\\:{1}" +
- "[a-fA-F0-9]{4}\\:{1}[a-fA-F0-9]{4}";
- static final String REGEXP_IPV4_ADDRESS_TYPE = "[0-9]{1,3}\\.{1}[0-9]{1,3}\\.{1}" +
- "[0-9]{1,3}\\.{1}[0-9]{1,3}";
-
- /**
- * The postfix strings of address.
- */
- static final String STRING_PHONE_NUMBER_ADDRESS_TYPE = "/TYPE=PLMN";
- static final String STRING_IPV4_ADDRESS_TYPE = "/TYPE=IPV4";
- static final String STRING_IPV6_ADDRESS_TYPE = "/TYPE=IPV6";
-
- /**
- * Error values.
- */
- static private final int PDU_COMPOSE_SUCCESS = 0;
- static private final int PDU_COMPOSE_CONTENT_ERROR = 1;
- static private final int PDU_COMPOSE_FIELD_NOT_SET = 2;
- static private final int PDU_COMPOSE_FIELD_NOT_SUPPORTED = 3;
-
- /**
- * WAP values defined in WSP spec.
- */
- static private final int QUOTED_STRING_FLAG = 34;
- static private final int END_STRING_FLAG = 0;
- static private final int LENGTH_QUOTE = 31;
- static private final int TEXT_MAX = 127;
- static private final int SHORT_INTEGER_MAX = 127;
- static private final int LONG_INTEGER_LENGTH_MAX = 8;
-
- /**
- * Block size when read data from InputStream.
- */
- static private final int PDU_COMPOSER_BLOCK_SIZE = 1024;
-
- /**
- * The output message.
- */
- protected ByteArrayOutputStream mMessage = null;
-
- /**
- * The PDU.
- */
- private GenericPdu mPdu = null;
-
- /**
- * Current visiting position of the mMessage.
- */
- protected int mPosition = 0;
-
- /**
- * Message compose buffer stack.
- */
- private BufferStack mStack = null;
-
- /**
- * Content resolver.
- */
- private final ContentResolver mResolver;
-
- /**
- * Header of this pdu.
- */
- private PduHeaders mPduHeader = null;
-
- /**
- * Map of all content type
- */
- private static HashMap<String, Integer> mContentTypeMap = null;
-
- static {
- mContentTypeMap = new HashMap<String, Integer>();
-
- int i;
- for (i = 0; i < PduContentTypes.contentTypes.length; i++) {
- mContentTypeMap.put(PduContentTypes.contentTypes[i], i);
- }
- }
-
- /**
- * Constructor.
- *
- * @param context the context
- * @param pdu the pdu to be composed
- */
- public PduComposer(Context context, GenericPdu pdu) {
- mPdu = pdu;
- mResolver = context.getContentResolver();
- mPduHeader = pdu.getPduHeaders();
- mStack = new BufferStack();
- mMessage = new ByteArrayOutputStream();
- mPosition = 0;
- }
-
- /**
- * Make the message. No need to check whether mandatory fields are set,
- * because the constructors of outgoing pdus are taking care of this.
- *
- * @return OutputStream of maked message. Return null if
- * the PDU is invalid.
- */
- public byte[] make() {
- // Get Message-type.
- int type = mPdu.getMessageType();
-
- /* make the message */
- switch (type) {
- case PduHeaders.MESSAGE_TYPE_SEND_REQ:
- if (makeSendReqPdu() != PDU_COMPOSE_SUCCESS) {
- return null;
- }
- break;
- case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
- if (makeNotifyResp() != PDU_COMPOSE_SUCCESS) {
- return null;
- }
- break;
- case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
- if (makeAckInd() != PDU_COMPOSE_SUCCESS) {
- return null;
- }
- break;
- case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
- if (makeReadRecInd() != PDU_COMPOSE_SUCCESS) {
- return null;
- }
- break;
- default:
- return null;
- }
-
- return mMessage.toByteArray();
- }
-
- /**
- * Copy buf to mMessage.
- */
- protected void arraycopy(byte[] buf, int pos, int length) {
- mMessage.write(buf, pos, length);
- mPosition = mPosition + length;
- }
-
- /**
- * Append a byte to mMessage.
- */
- protected void append(int value) {
- mMessage.write(value);
- mPosition ++;
- }
-
- /**
- * Append short integer value to mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendShortInteger(int value) {
- /*
- * From WAP-230-WSP-20010705-a:
- * Short-integer = OCTET
- * ; Integers in range 0-127 shall be encoded as a one octet value
- * ; with the most significant bit set to one (1xxx xxxx) and with
- * ; the value in the remaining least significant bits.
- * In our implementation, only low 7 bits are stored and otherwise
- * bits are ignored.
- */
- append((value | 0x80) & 0xff);
- }
-
- /**
- * Append an octet number between 128 and 255 into mMessage.
- * NOTE:
- * A value between 0 and 127 should be appended by using appendShortInteger.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendOctet(int number) {
- append(number);
- }
-
- /**
- * Append a short length into mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendShortLength(int value) {
- /*
- * From WAP-230-WSP-20010705-a:
- * Short-length = <Any octet 0-30>
- */
- append(value);
- }
-
- /**
- * Append long integer into mMessage. it's used for really long integers.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendLongInteger(long longInt) {
- /*
- * From WAP-230-WSP-20010705-a:
- * Long-integer = Short-length Multi-octet-integer
- * ; The Short-length indicates the length of the Multi-octet-integer
- * Multi-octet-integer = 1*30 OCTET
- * ; The content octets shall be an unsigned integer value with the
- * ; most significant octet encoded first (big-endian representation).
- * ; The minimum number of octets must be used to encode the value.
- */
- int size;
- long temp = longInt;
-
- // Count the length of the long integer.
- for(size = 0; (temp != 0) && (size < LONG_INTEGER_LENGTH_MAX); size++) {
- temp = (temp >>> 8);
- }
-
- // Set Length.
- appendShortLength(size);
-
- // Count and set the long integer.
- int i;
- int shift = (size -1) * 8;
-
- for (i = 0; i < size; i++) {
- append((int)((longInt >>> shift) & 0xff));
- shift = shift - 8;
- }
- }
-
- /**
- * Append text string into mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendTextString(byte[] text) {
- /*
- * From WAP-230-WSP-20010705-a:
- * Text-string = [Quote] *TEXT End-of-string
- * ; If the first character in the TEXT is in the range of 128-255,
- * ; a Quote character must precede it. Otherwise the Quote character
- * ;must be omitted. The Quote is not part of the contents.
- */
- if (((text[0])&0xff) > TEXT_MAX) { // No need to check for <= 255
- append(TEXT_MAX);
- }
-
- arraycopy(text, 0, text.length);
- append(0);
- }
-
- /**
- * Append text string into mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendTextString(String str) {
- /*
- * From WAP-230-WSP-20010705-a:
- * Text-string = [Quote] *TEXT End-of-string
- * ; If the first character in the TEXT is in the range of 128-255,
- * ; a Quote character must precede it. Otherwise the Quote character
- * ;must be omitted. The Quote is not part of the contents.
- */
- appendTextString(str.getBytes());
- }
-
- /**
- * Append encoded string value to mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendEncodedString(EncodedStringValue enStr) {
- /*
- * From OMA-TS-MMS-ENC-V1_3-20050927-C:
- * Encoded-string-value = Text-string | Value-length Char-set Text-string
- */
- assert(enStr != null);
-
- int charset = enStr.getCharacterSet();
- byte[] textString = enStr.getTextString();
- if (null == textString) {
- return;
- }
-
- /*
- * In the implementation of EncodedStringValue, the charset field will
- * never be 0. It will always be composed as
- * Encoded-string-value = Value-length Char-set Text-string
- */
- mStack.newbuf();
- PositionMarker start = mStack.mark();
-
- appendShortInteger(charset);
- appendTextString(textString);
-
- int len = start.getLength();
- mStack.pop();
- appendValueLength(len);
- mStack.copy();
- }
-
- /**
- * Append uintvar integer into mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendUintvarInteger(long value) {
- /*
- * From WAP-230-WSP-20010705-a:
- * To encode a large unsigned integer, split it into 7-bit fragments
- * and place them in the payloads of multiple octets. The most significant
- * bits are placed in the first octets with the least significant bits
- * ending up in the last octet. All octets MUST set the Continue bit to 1
- * except the last octet, which MUST set the Continue bit to 0.
- */
- int i;
- long max = SHORT_INTEGER_MAX;
-
- for (i = 0; i < 5; i++) {
- if (value < max) {
- break;
- }
-
- max = (max << 7) | 0x7fl;
- }
-
- while(i > 0) {
- long temp = value >>> (i * 7);
- temp = temp & 0x7f;
-
- append((int)((temp | 0x80) & 0xff));
-
- i--;
- }
-
- append((int)(value & 0x7f));
- }
-
- /**
- * Append date value into mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendDateValue(long date) {
- /*
- * From OMA-TS-MMS-ENC-V1_3-20050927-C:
- * Date-value = Long-integer
- */
- appendLongInteger(date);
- }
-
- /**
- * Append value length to mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendValueLength(long value) {
- /*
- * From WAP-230-WSP-20010705-a:
- * Value-length = Short-length | (Length-quote Length)
- * ; Value length is used to indicate the length of the value to follow
- * Short-length = <Any octet 0-30>
- * Length-quote = <Octet 31>
- * Length = Uintvar-integer
- */
- if (value < LENGTH_QUOTE) {
- appendShortLength((int) value);
- return;
- }
-
- append(LENGTH_QUOTE);
- appendUintvarInteger(value);
- }
-
- /**
- * Append quoted string to mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendQuotedString(byte[] text) {
- /*
- * From WAP-230-WSP-20010705-a:
- * Quoted-string = <Octet 34> *TEXT End-of-string
- * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing
- * ;quotation-marks <"> removed.
- */
- append(QUOTED_STRING_FLAG);
- arraycopy(text, 0, text.length);
- append(END_STRING_FLAG);
- }
-
- /**
- * Append quoted string to mMessage.
- * This implementation doesn't check the validity of parameter, since it
- * assumes that the values are validated in the GenericPdu setter methods.
- */
- protected void appendQuotedString(String str) {
- /*
- * From WAP-230-WSP-20010705-a:
- * Quoted-string = <Octet 34> *TEXT End-of-string
- * ;The TEXT encodes an RFC2616 Quoted-string with the enclosing
- * ;quotation-marks <"> removed.
- */
- appendQuotedString(str.getBytes());
- }
-
- private EncodedStringValue appendAddressType(EncodedStringValue address) {
- EncodedStringValue temp = null;
-
- try {
- int addressType = checkAddressType(address.getString());
- temp = EncodedStringValue.copy(address);
- if (PDU_PHONE_NUMBER_ADDRESS_TYPE == addressType) {
- // Phone number.
- temp.appendTextString(STRING_PHONE_NUMBER_ADDRESS_TYPE.getBytes());
- } else if (PDU_IPV4_ADDRESS_TYPE == addressType) {
- // Ipv4 address.
- temp.appendTextString(STRING_IPV4_ADDRESS_TYPE.getBytes());
- } else if (PDU_IPV6_ADDRESS_TYPE == addressType) {
- // Ipv6 address.
- temp.appendTextString(STRING_IPV6_ADDRESS_TYPE.getBytes());
- }
- } catch (NullPointerException e) {
- return null;
- }
-
- return temp;
- }
-
- /**
- * Append header to mMessage.
- */
- private int appendHeader(int field) {
- switch (field) {
- case PduHeaders.MMS_VERSION:
- appendOctet(field);
-
- int version = mPduHeader.getOctet(field);
- if (0 == version) {
- appendShortInteger(PduHeaders.CURRENT_MMS_VERSION);
- } else {
- appendShortInteger(version);
- }
-
- break;
-
- case PduHeaders.MESSAGE_ID:
- case PduHeaders.TRANSACTION_ID:
- byte[] textString = mPduHeader.getTextString(field);
- if (null == textString) {
- return PDU_COMPOSE_FIELD_NOT_SET;
- }
-
- appendOctet(field);
- appendTextString(textString);
- break;
-
- case PduHeaders.TO:
- case PduHeaders.BCC:
- case PduHeaders.CC:
- EncodedStringValue[] addr = mPduHeader.getEncodedStringValues(field);
-
- if (null == addr) {
- return PDU_COMPOSE_FIELD_NOT_SET;
- }
-
- EncodedStringValue temp;
- for (int i = 0; i < addr.length; i++) {
- temp = appendAddressType(addr[i]);
- if (temp == null) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- appendOctet(field);
- appendEncodedString(temp);
- }
- break;
-
- case PduHeaders.FROM:
- // Value-length (Address-present-token Encoded-string-value | Insert-address-token)
- appendOctet(field);
-
- EncodedStringValue from = mPduHeader.getEncodedStringValue(field);
- if ((from == null)
- || TextUtils.isEmpty(from.getString())
- || new String(from.getTextString()).equals(
- PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
- // Length of from = 1
- append(1);
- // Insert-address-token = <Octet 129>
- append(PduHeaders.FROM_INSERT_ADDRESS_TOKEN);
- } else {
- mStack.newbuf();
- PositionMarker fstart = mStack.mark();
-
- // Address-present-token = <Octet 128>
- append(PduHeaders.FROM_ADDRESS_PRESENT_TOKEN);
-
- temp = appendAddressType(from);
- if (temp == null) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- appendEncodedString(temp);
-
- int flen = fstart.getLength();
- mStack.pop();
- appendValueLength(flen);
- mStack.copy();
- }
- break;
-
- case PduHeaders.READ_STATUS:
- case PduHeaders.STATUS:
- case PduHeaders.REPORT_ALLOWED:
- case PduHeaders.PRIORITY:
- case PduHeaders.DELIVERY_REPORT:
- case PduHeaders.READ_REPORT:
- int octet = mPduHeader.getOctet(field);
- if (0 == octet) {
- return PDU_COMPOSE_FIELD_NOT_SET;
- }
-
- appendOctet(field);
- appendOctet(octet);
- break;
-
- case PduHeaders.DATE:
- long date = mPduHeader.getLongInteger(field);
- if (-1 == date) {
- return PDU_COMPOSE_FIELD_NOT_SET;
- }
-
- appendOctet(field);
- appendDateValue(date);
- break;
-
- case PduHeaders.SUBJECT:
- EncodedStringValue enString =
- mPduHeader.getEncodedStringValue(field);
- if (null == enString) {
- return PDU_COMPOSE_FIELD_NOT_SET;
- }
-
- appendOctet(field);
- appendEncodedString(enString);
- break;
-
- case PduHeaders.MESSAGE_CLASS:
- byte[] messageClass = mPduHeader.getTextString(field);
- if (null == messageClass) {
- return PDU_COMPOSE_FIELD_NOT_SET;
- }
-
- appendOctet(field);
- if (Arrays.equals(messageClass,
- PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes())) {
- appendOctet(PduHeaders.MESSAGE_CLASS_ADVERTISEMENT);
- } else if (Arrays.equals(messageClass,
- PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes())) {
- appendOctet(PduHeaders.MESSAGE_CLASS_AUTO);
- } else if (Arrays.equals(messageClass,
- PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes())) {
- appendOctet(PduHeaders.MESSAGE_CLASS_PERSONAL);
- } else if (Arrays.equals(messageClass,
- PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes())) {
- appendOctet(PduHeaders.MESSAGE_CLASS_INFORMATIONAL);
- } else {
- appendTextString(messageClass);
- }
- break;
-
- case PduHeaders.EXPIRY:
- long expiry = mPduHeader.getLongInteger(field);
- if (-1 == expiry) {
- return PDU_COMPOSE_FIELD_NOT_SET;
- }
-
- appendOctet(field);
-
- mStack.newbuf();
- PositionMarker expiryStart = mStack.mark();
-
- append(PduHeaders.VALUE_RELATIVE_TOKEN);
- appendLongInteger(expiry);
-
- int expiryLength = expiryStart.getLength();
- mStack.pop();
- appendValueLength(expiryLength);
- mStack.copy();
- break;
-
- default:
- return PDU_COMPOSE_FIELD_NOT_SUPPORTED;
- }
-
- return PDU_COMPOSE_SUCCESS;
- }
-
- /**
- * Make ReadRec.Ind.
- */
- private int makeReadRecInd() {
- if (mMessage == null) {
- mMessage = new ByteArrayOutputStream();
- mPosition = 0;
- }
-
- // X-Mms-Message-Type
- appendOctet(PduHeaders.MESSAGE_TYPE);
- appendOctet(PduHeaders.MESSAGE_TYPE_READ_REC_IND);
-
- // X-Mms-MMS-Version
- if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // Message-ID
- if (appendHeader(PduHeaders.MESSAGE_ID) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // To
- if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // From
- if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // Date Optional
- appendHeader(PduHeaders.DATE);
-
- // X-Mms-Read-Status
- if (appendHeader(PduHeaders.READ_STATUS) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // X-Mms-Applic-ID Optional(not support)
- // X-Mms-Reply-Applic-ID Optional(not support)
- // X-Mms-Aux-Applic-Info Optional(not support)
-
- return PDU_COMPOSE_SUCCESS;
- }
-
- /**
- * Make NotifyResp.Ind.
- */
- private int makeNotifyResp() {
- if (mMessage == null) {
- mMessage = new ByteArrayOutputStream();
- mPosition = 0;
- }
-
- // X-Mms-Message-Type
- appendOctet(PduHeaders.MESSAGE_TYPE);
- appendOctet(PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND);
-
- // X-Mms-Transaction-ID
- if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // X-Mms-MMS-Version
- if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // X-Mms-Status
- if (appendHeader(PduHeaders.STATUS) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // X-Mms-Report-Allowed Optional (not support)
- return PDU_COMPOSE_SUCCESS;
- }
-
- /**
- * Make Acknowledge.Ind.
- */
- private int makeAckInd() {
- if (mMessage == null) {
- mMessage = new ByteArrayOutputStream();
- mPosition = 0;
- }
-
- // X-Mms-Message-Type
- appendOctet(PduHeaders.MESSAGE_TYPE);
- appendOctet(PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND);
-
- // X-Mms-Transaction-ID
- if (appendHeader(PduHeaders.TRANSACTION_ID) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // X-Mms-MMS-Version
- if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // X-Mms-Report-Allowed Optional
- appendHeader(PduHeaders.REPORT_ALLOWED);
-
- return PDU_COMPOSE_SUCCESS;
- }
-
- /**
- * Make Send.req.
- */
- private int makeSendReqPdu() {
- if (mMessage == null) {
- mMessage = new ByteArrayOutputStream();
- mPosition = 0;
- }
-
- // X-Mms-Message-Type
- appendOctet(PduHeaders.MESSAGE_TYPE);
- appendOctet(PduHeaders.MESSAGE_TYPE_SEND_REQ);
-
- // X-Mms-Transaction-ID
- appendOctet(PduHeaders.TRANSACTION_ID);
-
- byte[] trid = mPduHeader.getTextString(PduHeaders.TRANSACTION_ID);
- if (trid == null) {
- // Transaction-ID should be set(by Transaction) before make().
- throw new IllegalArgumentException("Transaction-ID is null.");
- }
- appendTextString(trid);
-
- // X-Mms-MMS-Version
- if (appendHeader(PduHeaders.MMS_VERSION) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // Date Date-value Optional.
- appendHeader(PduHeaders.DATE);
-
- // From
- if (appendHeader(PduHeaders.FROM) != PDU_COMPOSE_SUCCESS) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- boolean recipient = false;
-
- // To
- if (appendHeader(PduHeaders.TO) != PDU_COMPOSE_CONTENT_ERROR) {
- recipient = true;
- }
-
- // Cc
- if (appendHeader(PduHeaders.CC) != PDU_COMPOSE_CONTENT_ERROR) {
- recipient = true;
- }
-
- // Bcc
- if (appendHeader(PduHeaders.BCC) != PDU_COMPOSE_CONTENT_ERROR) {
- recipient = true;
- }
-
- // Need at least one of "cc", "bcc" and "to".
- if (false == recipient) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // Subject Optional
- appendHeader(PduHeaders.SUBJECT);
-
- // X-Mms-Message-Class Optional
- // Message-class-value = Class-identifier | Token-text
- appendHeader(PduHeaders.MESSAGE_CLASS);
-
- // X-Mms-Expiry Optional
- appendHeader(PduHeaders.EXPIRY);
-
- // X-Mms-Priority Optional
- appendHeader(PduHeaders.PRIORITY);
-
- // X-Mms-Delivery-Report Optional
- appendHeader(PduHeaders.DELIVERY_REPORT);
-
- // X-Mms-Read-Report Optional
- appendHeader(PduHeaders.READ_REPORT);
-
- // Content-Type
- appendOctet(PduHeaders.CONTENT_TYPE);
-
- // Message body
- return makeMessageBody();
- }
-
- /**
- * Make message body.
- */
- private int makeMessageBody() {
- // 1. add body informations
- mStack.newbuf(); // Switching buffer because we need to
-
- PositionMarker ctStart = mStack.mark();
-
- // This contentTypeIdentifier should be used for type of attachment...
- String contentType = new String(mPduHeader.getTextString(PduHeaders.CONTENT_TYPE));
- Integer contentTypeIdentifier = mContentTypeMap.get(contentType);
- if (contentTypeIdentifier == null) {
- // content type is mandatory
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- appendShortInteger(contentTypeIdentifier.intValue());
-
- // content-type parameter: start
- PduBody body = ((SendReq) mPdu).getBody();
- if (null == body || body.getPartsNum() == 0) {
- // empty message
- appendUintvarInteger(0);
- mStack.pop();
- mStack.copy();
- return PDU_COMPOSE_SUCCESS;
- }
-
- PduPart part;
- try {
- part = body.getPart(0);
-
- byte[] start = part.getContentId();
- if (start != null) {
- appendOctet(PduPart.P_DEP_START);
- if (('<' == start[0]) && ('>' == start[start.length - 1])) {
- appendTextString(start);
- } else {
- appendTextString("<" + new String(start) + ">");
- }
- }
-
- // content-type parameter: type
- appendOctet(PduPart.P_CT_MR_TYPE);
- appendTextString(part.getContentType());
- }
- catch (ArrayIndexOutOfBoundsException e){
- e.printStackTrace();
- }
-
- int ctLength = ctStart.getLength();
- mStack.pop();
- appendValueLength(ctLength);
- mStack.copy();
-
- // 3. add content
- int partNum = body.getPartsNum();
- appendUintvarInteger(partNum);
- for (int i = 0; i < partNum; i++) {
- part = body.getPart(i);
- mStack.newbuf(); // Leaving space for header lengh and data length
- PositionMarker attachment = mStack.mark();
-
- mStack.newbuf(); // Leaving space for Content-Type length
- PositionMarker contentTypeBegin = mStack.mark();
-
- byte[] partContentType = part.getContentType();
-
- if (partContentType == null) {
- // content type is mandatory
- return PDU_COMPOSE_CONTENT_ERROR;
- }
-
- // content-type value
- Integer partContentTypeIdentifier =
- mContentTypeMap.get(new String(partContentType));
- if (partContentTypeIdentifier == null) {
- appendTextString(partContentType);
- } else {
- appendShortInteger(partContentTypeIdentifier.intValue());
- }
-
- /* Content-type parameter : name.
- * The value of name, filename, content-location is the same.
- * Just one of them is enough for this PDU.
- */
- byte[] name = part.getName();
-
- if (null == name) {
- name = part.getFilename();
-
- if (null == name) {
- name = part.getContentLocation();
-
- if (null == name) {
- /* at lease one of name, filename, Content-location
- * should be available.
- */
- return PDU_COMPOSE_CONTENT_ERROR;
- }
- }
- }
- appendOctet(PduPart.P_DEP_NAME);
- appendTextString(name);
-
- // content-type parameter : charset
- int charset = part.getCharset();
- if (charset != 0) {
- appendOctet(PduPart.P_CHARSET);
- appendShortInteger(charset);
- }
-
- int contentTypeLength = contentTypeBegin.getLength();
- mStack.pop();
- appendValueLength(contentTypeLength);
- mStack.copy();
-
- // content id
- byte[] contentId = part.getContentId();
-
- if (null != contentId) {
- appendOctet(PduPart.P_CONTENT_ID);
- if (('<' == contentId[0]) && ('>' == contentId[contentId.length - 1])) {
- appendQuotedString(contentId);
- } else {
- appendQuotedString("<" + new String(contentId) + ">");
- }
- }
-
- // content-location
- byte[] contentLocation = part.getContentLocation();
- if (null != contentLocation) {
- appendOctet(PduPart.P_CONTENT_LOCATION);
- appendTextString(contentLocation);
- }
-
- // content
- int headerLength = attachment.getLength();
-
- int dataLength = 0; // Just for safety...
- byte[] partData = part.getData();
-
- if (partData != null) {
- arraycopy(partData, 0, partData.length);
- dataLength = partData.length;
- } else {
- InputStream cr;
- try {
- byte[] buffer = new byte[PDU_COMPOSER_BLOCK_SIZE];
- cr = mResolver.openInputStream(part.getDataUri());
- int len = 0;
- while ((len = cr.read(buffer)) != -1) {
- mMessage.write(buffer, 0, len);
- mPosition += len;
- dataLength += len;
- }
- } catch (FileNotFoundException e) {
- return PDU_COMPOSE_CONTENT_ERROR;
- } catch (IOException e) {
- return PDU_COMPOSE_CONTENT_ERROR;
- } catch (RuntimeException e) {
- return PDU_COMPOSE_CONTENT_ERROR;
- }
- }
-
- if (dataLength != (attachment.getLength() - headerLength)) {
- throw new RuntimeException("BUG: Length sanity check failed");
- }
-
- mStack.pop();
- appendUintvarInteger(headerLength);
- appendUintvarInteger(dataLength);
- mStack.copy();
- }
-
- return PDU_COMPOSE_SUCCESS;
- }
-
- /**
- * Record current message informations.
- */
- static private class LengthRecordNode {
- ByteArrayOutputStream currentMessage = null;
- public int currentPosition = 0;
-
- public LengthRecordNode next = null;
- }
-
- /**
- * Mark current message position and stact size.
- */
- private class PositionMarker {
- private int c_pos; // Current position
- private int currentStackSize; // Current stack size
-
- int getLength() {
- // If these assert fails, likely that you are finding the
- // size of buffer that is deep in BufferStack you can only
- // find the length of the buffer that is on top
- if (currentStackSize != mStack.stackSize) {
- throw new RuntimeException("BUG: Invalid call to getLength()");
- }
-
- return mPosition - c_pos;
- }
- }
-
- /**
- * This implementation can be OPTIMIZED to use only
- * 2 buffers. This optimization involves changing BufferStack
- * only... Its usage (interface) will not change.
- */
- private class BufferStack {
- private LengthRecordNode stack = null;
- private LengthRecordNode toCopy = null;
-
- int stackSize = 0;
-
- /**
- * Create a new message buffer and push it into the stack.
- */
- void newbuf() {
- // You can't create a new buff when toCopy != null
- // That is after calling pop() and before calling copy()
- // If you do, it is a bug
- if (toCopy != null) {
- throw new RuntimeException("BUG: Invalid newbuf() before copy()");
- }
-
- LengthRecordNode temp = new LengthRecordNode();
-
- temp.currentMessage = mMessage;
- temp.currentPosition = mPosition;
-
- temp.next = stack;
- stack = temp;
-
- stackSize = stackSize + 1;
-
- mMessage = new ByteArrayOutputStream();
- mPosition = 0;
- }
-
- /**
- * Pop the message before and record current message in the stack.
- */
- void pop() {
- ByteArrayOutputStream currentMessage = mMessage;
- int currentPosition = mPosition;
-
- mMessage = stack.currentMessage;
- mPosition = stack.currentPosition;
-
- toCopy = stack;
- // Re using the top element of the stack to avoid memory allocation
-
- stack = stack.next;
- stackSize = stackSize - 1;
-
- toCopy.currentMessage = currentMessage;
- toCopy.currentPosition = currentPosition;
- }
-
- /**
- * Append current message to the message before.
- */
- void copy() {
- arraycopy(toCopy.currentMessage.toByteArray(), 0,
- toCopy.currentPosition);
-
- toCopy = null;
- }
-
- /**
- * Mark current message position
- */
- PositionMarker mark() {
- PositionMarker m = new PositionMarker();
-
- m.c_pos = mPosition;
- m.currentStackSize = stackSize;
-
- return m;
- }
- }
-
- /**
- * Check address type.
- *
- * @param address address string without the postfix stinng type,
- * such as "/TYPE=PLMN", "/TYPE=IPv6" and "/TYPE=IPv4"
- * @return PDU_PHONE_NUMBER_ADDRESS_TYPE if it is phone number,
- * PDU_EMAIL_ADDRESS_TYPE if it is email address,
- * PDU_IPV4_ADDRESS_TYPE if it is ipv4 address,
- * PDU_IPV6_ADDRESS_TYPE if it is ipv6 address,
- * PDU_UNKNOWN_ADDRESS_TYPE if it is unknown.
- */
- protected static int checkAddressType(String address) {
- /**
- * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf, section 8.
- * address = ( e-mail / device-address / alphanum-shortcode / num-shortcode)
- * e-mail = mailbox; to the definition of mailbox as described in
- * section 3.4 of [RFC2822], but excluding the
- * obsolete definitions as indicated by the "obs-" prefix.
- * device-address = ( global-phone-number "/TYPE=PLMN" )
- * / ( ipv4 "/TYPE=IPv4" ) / ( ipv6 "/TYPE=IPv6" )
- * / ( escaped-value "/TYPE=" address-type )
- *
- * global-phone-number = ["+"] 1*( DIGIT / written-sep )
- * written-sep =("-"/".")
- *
- * ipv4 = 1*3DIGIT 3( "." 1*3DIGIT ) ; IPv4 address value
- *
- * ipv6 = 4HEXDIG 7( ":" 4HEXDIG ) ; IPv6 address per RFC 2373
- */
-
- if (null == address) {
- return PDU_UNKNOWN_ADDRESS_TYPE;
- }
-
- if (address.matches(REGEXP_IPV4_ADDRESS_TYPE)) {
- // Ipv4 address.
- return PDU_IPV4_ADDRESS_TYPE;
- }else if (address.matches(REGEXP_PHONE_NUMBER_ADDRESS_TYPE)) {
- // Phone number.
- return PDU_PHONE_NUMBER_ADDRESS_TYPE;
- } else if (address.matches(REGEXP_EMAIL_ADDRESS_TYPE)) {
- // Email address.
- return PDU_EMAIL_ADDRESS_TYPE;
- } else if (address.matches(REGEXP_IPV6_ADDRESS_TYPE)) {
- // Ipv6 address.
- return PDU_IPV6_ADDRESS_TYPE;
- } else {
- // Unknown address.
- return PDU_UNKNOWN_ADDRESS_TYPE;
- }
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduContentTypes.java b/core/java/com/google/android/mms/pdu/PduContentTypes.java
deleted file mode 100644
index 7799e0e..0000000
--- a/core/java/com/google/android/mms/pdu/PduContentTypes.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-public class PduContentTypes {
- /**
- * All content types. From:
- * http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.htm
- */
- static final String[] contentTypes = {
- "*/*", /* 0x00 */
- "text/*", /* 0x01 */
- "text/html", /* 0x02 */
- "text/plain", /* 0x03 */
- "text/x-hdml", /* 0x04 */
- "text/x-ttml", /* 0x05 */
- "text/x-vCalendar", /* 0x06 */
- "text/x-vCard", /* 0x07 */
- "text/vnd.wap.wml", /* 0x08 */
- "text/vnd.wap.wmlscript", /* 0x09 */
- "text/vnd.wap.wta-event", /* 0x0A */
- "multipart/*", /* 0x0B */
- "multipart/mixed", /* 0x0C */
- "multipart/form-data", /* 0x0D */
- "multipart/byterantes", /* 0x0E */
- "multipart/alternative", /* 0x0F */
- "application/*", /* 0x10 */
- "application/java-vm", /* 0x11 */
- "application/x-www-form-urlencoded", /* 0x12 */
- "application/x-hdmlc", /* 0x13 */
- "application/vnd.wap.wmlc", /* 0x14 */
- "application/vnd.wap.wmlscriptc", /* 0x15 */
- "application/vnd.wap.wta-eventc", /* 0x16 */
- "application/vnd.wap.uaprof", /* 0x17 */
- "application/vnd.wap.wtls-ca-certificate", /* 0x18 */
- "application/vnd.wap.wtls-user-certificate", /* 0x19 */
- "application/x-x509-ca-cert", /* 0x1A */
- "application/x-x509-user-cert", /* 0x1B */
- "image/*", /* 0x1C */
- "image/gif", /* 0x1D */
- "image/jpeg", /* 0x1E */
- "image/tiff", /* 0x1F */
- "image/png", /* 0x20 */
- "image/vnd.wap.wbmp", /* 0x21 */
- "application/vnd.wap.multipart.*", /* 0x22 */
- "application/vnd.wap.multipart.mixed", /* 0x23 */
- "application/vnd.wap.multipart.form-data", /* 0x24 */
- "application/vnd.wap.multipart.byteranges", /* 0x25 */
- "application/vnd.wap.multipart.alternative", /* 0x26 */
- "application/xml", /* 0x27 */
- "text/xml", /* 0x28 */
- "application/vnd.wap.wbxml", /* 0x29 */
- "application/x-x968-cross-cert", /* 0x2A */
- "application/x-x968-ca-cert", /* 0x2B */
- "application/x-x968-user-cert", /* 0x2C */
- "text/vnd.wap.si", /* 0x2D */
- "application/vnd.wap.sic", /* 0x2E */
- "text/vnd.wap.sl", /* 0x2F */
- "application/vnd.wap.slc", /* 0x30 */
- "text/vnd.wap.co", /* 0x31 */
- "application/vnd.wap.coc", /* 0x32 */
- "application/vnd.wap.multipart.related", /* 0x33 */
- "application/vnd.wap.sia", /* 0x34 */
- "text/vnd.wap.connectivity-xml", /* 0x35 */
- "application/vnd.wap.connectivity-wbxml", /* 0x36 */
- "application/pkcs7-mime", /* 0x37 */
- "application/vnd.wap.hashed-certificate", /* 0x38 */
- "application/vnd.wap.signed-certificate", /* 0x39 */
- "application/vnd.wap.cert-response", /* 0x3A */
- "application/xhtml+xml", /* 0x3B */
- "application/wml+xml", /* 0x3C */
- "text/css", /* 0x3D */
- "application/vnd.wap.mms-message", /* 0x3E */
- "application/vnd.wap.rollover-certificate", /* 0x3F */
- "application/vnd.wap.locc+wbxml", /* 0x40 */
- "application/vnd.wap.loc+xml", /* 0x41 */
- "application/vnd.syncml.dm+wbxml", /* 0x42 */
- "application/vnd.syncml.dm+xml", /* 0x43 */
- "application/vnd.syncml.notification", /* 0x44 */
- "application/vnd.wap.xhtml+xml", /* 0x45 */
- "application/vnd.wv.csp.cir", /* 0x46 */
- "application/vnd.oma.dd+xml", /* 0x47 */
- "application/vnd.oma.drm.message", /* 0x48 */
- "application/vnd.oma.drm.content", /* 0x49 */
- "application/vnd.oma.drm.rights+xml", /* 0x4A */
- "application/vnd.oma.drm.rights+wbxml", /* 0x4B */
- "application/vnd.wv.csp+xml", /* 0x4C */
- "application/vnd.wv.csp+wbxml", /* 0x4D */
- "application/vnd.syncml.ds.notification", /* 0x4E */
- "audio/*", /* 0x4F */
- "video/*", /* 0x50 */
- "application/vnd.oma.dd2+xml", /* 0x51 */
- "application/mikey" /* 0x52 */
- };
-}
diff --git a/core/java/com/google/android/mms/pdu/PduHeaders.java b/core/java/com/google/android/mms/pdu/PduHeaders.java
deleted file mode 100644
index 4313815..0000000
--- a/core/java/com/google/android/mms/pdu/PduHeaders.java
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class PduHeaders {
- /**
- * All pdu header fields.
- */
- public static final int BCC = 0x81;
- public static final int CC = 0x82;
- public static final int CONTENT_LOCATION = 0x83;
- public static final int CONTENT_TYPE = 0x84;
- public static final int DATE = 0x85;
- public static final int DELIVERY_REPORT = 0x86;
- public static final int DELIVERY_TIME = 0x87;
- public static final int EXPIRY = 0x88;
- public static final int FROM = 0x89;
- public static final int MESSAGE_CLASS = 0x8A;
- public static final int MESSAGE_ID = 0x8B;
- public static final int MESSAGE_TYPE = 0x8C;
- public static final int MMS_VERSION = 0x8D;
- public static final int MESSAGE_SIZE = 0x8E;
- public static final int PRIORITY = 0x8F;
-
- public static final int READ_REPLY = 0x90;
- public static final int READ_REPORT = 0x90;
- public static final int REPORT_ALLOWED = 0x91;
- public static final int RESPONSE_STATUS = 0x92;
- public static final int RESPONSE_TEXT = 0x93;
- public static final int SENDER_VISIBILITY = 0x94;
- public static final int STATUS = 0x95;
- public static final int SUBJECT = 0x96;
- public static final int TO = 0x97;
- public static final int TRANSACTION_ID = 0x98;
- public static final int RETRIEVE_STATUS = 0x99;
- public static final int RETRIEVE_TEXT = 0x9A;
- public static final int READ_STATUS = 0x9B;
- public static final int REPLY_CHARGING = 0x9C;
- public static final int REPLY_CHARGING_DEADLINE = 0x9D;
- public static final int REPLY_CHARGING_ID = 0x9E;
- public static final int REPLY_CHARGING_SIZE = 0x9F;
-
- public static final int PREVIOUSLY_SENT_BY = 0xA0;
- public static final int PREVIOUSLY_SENT_DATE = 0xA1;
- public static final int STORE = 0xA2;
- public static final int MM_STATE = 0xA3;
- public static final int MM_FLAGS = 0xA4;
- public static final int STORE_STATUS = 0xA5;
- public static final int STORE_STATUS_TEXT = 0xA6;
- public static final int STORED = 0xA7;
- public static final int ATTRIBUTES = 0xA8;
- public static final int TOTALS = 0xA9;
- public static final int MBOX_TOTALS = 0xAA;
- public static final int QUOTAS = 0xAB;
- public static final int MBOX_QUOTAS = 0xAC;
- public static final int MESSAGE_COUNT = 0xAD;
- public static final int CONTENT = 0xAE;
- public static final int START = 0xAF;
-
- public static final int ADDITIONAL_HEADERS = 0xB0;
- public static final int DISTRIBUTION_INDICATOR = 0xB1;
- public static final int ELEMENT_DESCRIPTOR = 0xB2;
- public static final int LIMIT = 0xB3;
- public static final int RECOMMENDED_RETRIEVAL_MODE = 0xB4;
- public static final int RECOMMENDED_RETRIEVAL_MODE_TEXT = 0xB5;
- public static final int STATUS_TEXT = 0xB6;
- public static final int APPLIC_ID = 0xB7;
- public static final int REPLY_APPLIC_ID = 0xB8;
- public static final int AUX_APPLIC_ID = 0xB9;
- public static final int CONTENT_CLASS = 0xBA;
- public static final int DRM_CONTENT = 0xBB;
- public static final int ADAPTATION_ALLOWED = 0xBC;
- public static final int REPLACE_ID = 0xBD;
- public static final int CANCEL_ID = 0xBE;
- public static final int CANCEL_STATUS = 0xBF;
-
- /**
- * X-Mms-Message-Type field types.
- */
- public static final int MESSAGE_TYPE_SEND_REQ = 0x80;
- public static final int MESSAGE_TYPE_SEND_CONF = 0x81;
- public static final int MESSAGE_TYPE_NOTIFICATION_IND = 0x82;
- public static final int MESSAGE_TYPE_NOTIFYRESP_IND = 0x83;
- public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84;
- public static final int MESSAGE_TYPE_ACKNOWLEDGE_IND = 0x85;
- public static final int MESSAGE_TYPE_DELIVERY_IND = 0x86;
- public static final int MESSAGE_TYPE_READ_REC_IND = 0x87;
- public static final int MESSAGE_TYPE_READ_ORIG_IND = 0x88;
- public static final int MESSAGE_TYPE_FORWARD_REQ = 0x89;
- public static final int MESSAGE_TYPE_FORWARD_CONF = 0x8A;
- public static final int MESSAGE_TYPE_MBOX_STORE_REQ = 0x8B;
- public static final int MESSAGE_TYPE_MBOX_STORE_CONF = 0x8C;
- public static final int MESSAGE_TYPE_MBOX_VIEW_REQ = 0x8D;
- public static final int MESSAGE_TYPE_MBOX_VIEW_CONF = 0x8E;
- public static final int MESSAGE_TYPE_MBOX_UPLOAD_REQ = 0x8F;
- public static final int MESSAGE_TYPE_MBOX_UPLOAD_CONF = 0x90;
- public static final int MESSAGE_TYPE_MBOX_DELETE_REQ = 0x91;
- public static final int MESSAGE_TYPE_MBOX_DELETE_CONF = 0x92;
- public static final int MESSAGE_TYPE_MBOX_DESCR = 0x93;
- public static final int MESSAGE_TYPE_DELETE_REQ = 0x94;
- public static final int MESSAGE_TYPE_DELETE_CONF = 0x95;
- public static final int MESSAGE_TYPE_CANCEL_REQ = 0x96;
- public static final int MESSAGE_TYPE_CANCEL_CONF = 0x97;
-
- /**
- * X-Mms-Delivery-Report |
- * X-Mms-Read-Report |
- * X-Mms-Report-Allowed |
- * X-Mms-Sender-Visibility |
- * X-Mms-Store |
- * X-Mms-Stored |
- * X-Mms-Totals |
- * X-Mms-Quotas |
- * X-Mms-Distribution-Indicator |
- * X-Mms-DRM-Content |
- * X-Mms-Adaptation-Allowed |
- * field types.
- */
- public static final int VALUE_YES = 0x80;
- public static final int VALUE_NO = 0x81;
-
- /**
- * Delivery-Time |
- * Expiry and Reply-Charging-Deadline |
- * field type components.
- */
- public static final int VALUE_ABSOLUTE_TOKEN = 0x80;
- public static final int VALUE_RELATIVE_TOKEN = 0x81;
-
- /**
- * X-Mms-MMS-Version field types.
- */
- public static final int MMS_VERSION_1_3 = ((1 << 4) | 3);
- public static final int MMS_VERSION_1_2 = ((1 << 4) | 2);
- public static final int MMS_VERSION_1_1 = ((1 << 4) | 1);
- public static final int MMS_VERSION_1_0 = ((1 << 4) | 0);
-
- // Current version is 1.2.
- public static final int CURRENT_MMS_VERSION = MMS_VERSION_1_2;
-
- /**
- * From field type components.
- */
- public static final int FROM_ADDRESS_PRESENT_TOKEN = 0x80;
- public static final int FROM_INSERT_ADDRESS_TOKEN = 0x81;
-
- public static final String FROM_ADDRESS_PRESENT_TOKEN_STR = "address-present-token";
- public static final String FROM_INSERT_ADDRESS_TOKEN_STR = "insert-address-token";
-
- /**
- * X-Mms-Status Field.
- */
- public static final int STATUS_EXPIRED = 0x80;
- public static final int STATUS_RETRIEVED = 0x81;
- public static final int STATUS_REJECTED = 0x82;
- public static final int STATUS_DEFERRED = 0x83;
- public static final int STATUS_UNRECOGNIZED = 0x84;
- public static final int STATUS_INDETERMINATE = 0x85;
- public static final int STATUS_FORWARDED = 0x86;
- public static final int STATUS_UNREACHABLE = 0x87;
-
- /**
- * MM-Flags field type components.
- */
- public static final int MM_FLAGS_ADD_TOKEN = 0x80;
- public static final int MM_FLAGS_REMOVE_TOKEN = 0x81;
- public static final int MM_FLAGS_FILTER_TOKEN = 0x82;
-
- /**
- * X-Mms-Message-Class field types.
- */
- public static final int MESSAGE_CLASS_PERSONAL = 0x80;
- public static final int MESSAGE_CLASS_ADVERTISEMENT = 0x81;
- public static final int MESSAGE_CLASS_INFORMATIONAL = 0x82;
- public static final int MESSAGE_CLASS_AUTO = 0x83;
-
- public static final String MESSAGE_CLASS_PERSONAL_STR = "personal";
- public static final String MESSAGE_CLASS_ADVERTISEMENT_STR = "advertisement";
- public static final String MESSAGE_CLASS_INFORMATIONAL_STR = "informational";
- public static final String MESSAGE_CLASS_AUTO_STR = "auto";
-
- /**
- * X-Mms-Priority field types.
- */
- public static final int PRIORITY_LOW = 0x80;
- public static final int PRIORITY_NORMAL = 0x81;
- public static final int PRIORITY_HIGH = 0x82;
-
- /**
- * X-Mms-Response-Status field types.
- */
- public static final int RESPONSE_STATUS_OK = 0x80;
- public static final int RESPONSE_STATUS_ERROR_UNSPECIFIED = 0x81;
- public static final int RESPONSE_STATUS_ERROR_SERVICE_DENIED = 0x82;
-
- public static final int RESPONSE_STATUS_ERROR_MESSAGE_FORMAT_CORRUPT = 0x83;
- public static final int RESPONSE_STATUS_ERROR_SENDING_ADDRESS_UNRESOLVED = 0x84;
-
- public static final int RESPONSE_STATUS_ERROR_MESSAGE_NOT_FOUND = 0x85;
- public static final int RESPONSE_STATUS_ERROR_NETWORK_PROBLEM = 0x86;
- public static final int RESPONSE_STATUS_ERROR_CONTENT_NOT_ACCEPTED = 0x87;
- public static final int RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE = 0x88;
- public static final int RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0;
-
- public static final int RESPONSE_STATUS_ERROR_TRANSIENT_SENDNG_ADDRESS_UNRESOLVED = 0xC1;
- public static final int RESPONSE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC2;
- public static final int RESPONSE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC3;
- public static final int RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS = 0xC4;
-
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED = 0xE3;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE4;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED = 0xE5;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET = 0xE6;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED = 0xE6;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED = 0xE8;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED = 0xE9;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED = 0xEA;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID = 0xEB;
- public static final int RESPONSE_STATUS_ERROR_PERMANENT_END = 0xFF;
-
- /**
- * X-Mms-Retrieve-Status field types.
- */
- public static final int RETRIEVE_STATUS_OK = 0x80;
- public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0;
- public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND = 0xC1;
- public static final int RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC2;
- public static final int RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0;
- public static final int RETRIEVE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1;
- public static final int RETRIEVE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE2;
- public static final int RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 0xE3;
- public static final int RETRIEVE_STATUS_ERROR_END = 0xFF;
-
- /**
- * X-Mms-Sender-Visibility field types.
- */
- public static final int SENDER_VISIBILITY_HIDE = 0x80;
- public static final int SENDER_VISIBILITY_SHOW = 0x81;
-
- /**
- * X-Mms-Read-Status field types.
- */
- public static final int READ_STATUS_READ = 0x80;
- public static final int READ_STATUS__DELETED_WITHOUT_BEING_READ = 0x81;
-
- /**
- * X-Mms-Cancel-Status field types.
- */
- public static final int CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED = 0x80;
- public static final int CANCEL_STATUS_REQUEST_CORRUPTED = 0x81;
-
- /**
- * X-Mms-Reply-Charging field types.
- */
- public static final int REPLY_CHARGING_REQUESTED = 0x80;
- public static final int REPLY_CHARGING_REQUESTED_TEXT_ONLY = 0x81;
- public static final int REPLY_CHARGING_ACCEPTED = 0x82;
- public static final int REPLY_CHARGING_ACCEPTED_TEXT_ONLY = 0x83;
-
- /**
- * X-Mms-MM-State field types.
- */
- public static final int MM_STATE_DRAFT = 0x80;
- public static final int MM_STATE_SENT = 0x81;
- public static final int MM_STATE_NEW = 0x82;
- public static final int MM_STATE_RETRIEVED = 0x83;
- public static final int MM_STATE_FORWARDED = 0x84;
-
- /**
- * X-Mms-Recommended-Retrieval-Mode field types.
- */
- public static final int RECOMMENDED_RETRIEVAL_MODE_MANUAL = 0x80;
-
- /**
- * X-Mms-Content-Class field types.
- */
- public static final int CONTENT_CLASS_TEXT = 0x80;
- public static final int CONTENT_CLASS_IMAGE_BASIC = 0x81;
- public static final int CONTENT_CLASS_IMAGE_RICH = 0x82;
- public static final int CONTENT_CLASS_VIDEO_BASIC = 0x83;
- public static final int CONTENT_CLASS_VIDEO_RICH = 0x84;
- public static final int CONTENT_CLASS_MEGAPIXEL = 0x85;
- public static final int CONTENT_CLASS_CONTENT_BASIC = 0x86;
- public static final int CONTENT_CLASS_CONTENT_RICH = 0x87;
-
- /**
- * X-Mms-Store-Status field types.
- */
- public static final int STORE_STATUS_SUCCESS = 0x80;
- public static final int STORE_STATUS_ERROR_TRANSIENT_FAILURE = 0xC0;
- public static final int STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM = 0xC1;
- public static final int STORE_STATUS_ERROR_PERMANENT_FAILURE = 0xE0;
- public static final int STORE_STATUS_ERROR_PERMANENT_SERVICE_DENIED = 0xE1;
- public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 0xE2;
- public static final int STORE_STATUS_ERROR_PERMANENT_MESSAGE_NOT_FOUND = 0xE3;
- public static final int STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL = 0xE4;
- public static final int STORE_STATUS_ERROR_END = 0xFF;
-
- /**
- * The map contains the value of all headers.
- */
- private HashMap<Integer, Object> mHeaderMap = null;
-
- /**
- * Constructor of PduHeaders.
- */
- public PduHeaders() {
- mHeaderMap = new HashMap<Integer, Object>();
- }
-
- /**
- * Get octet value by header field.
- *
- * @param field the field
- * @return the octet value of the pdu header
- * with specified header field. Return 0 if
- * the value is not set.
- */
- protected int getOctet(int field) {
- Integer octet = (Integer) mHeaderMap.get(field);
- if (null == octet) {
- return 0;
- }
-
- return octet;
- }
-
- /**
- * Set octet value to pdu header by header field.
- *
- * @param value the value
- * @param field the field
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- protected void setOctet(int value, int field)
- throws InvalidHeaderValueException{
- /**
- * Check whether this field can be set for specific
- * header and check validity of the field.
- */
- switch (field) {
- case REPORT_ALLOWED:
- case ADAPTATION_ALLOWED:
- case DELIVERY_REPORT:
- case DRM_CONTENT:
- case DISTRIBUTION_INDICATOR:
- case QUOTAS:
- case READ_REPORT:
- case STORE:
- case STORED:
- case TOTALS:
- case SENDER_VISIBILITY:
- if ((VALUE_YES != value) && (VALUE_NO != value)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case READ_STATUS:
- if ((READ_STATUS_READ != value) &&
- (READ_STATUS__DELETED_WITHOUT_BEING_READ != value)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case CANCEL_STATUS:
- if ((CANCEL_STATUS_REQUEST_SUCCESSFULLY_RECEIVED != value) &&
- (CANCEL_STATUS_REQUEST_CORRUPTED != value)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case PRIORITY:
- if ((value < PRIORITY_LOW) || (value > PRIORITY_HIGH)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case STATUS:
- if ((value < STATUS_EXPIRED) || (value > STATUS_UNREACHABLE)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case REPLY_CHARGING:
- if ((value < REPLY_CHARGING_REQUESTED)
- || (value > REPLY_CHARGING_ACCEPTED_TEXT_ONLY)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case MM_STATE:
- if ((value < MM_STATE_DRAFT) || (value > MM_STATE_FORWARDED)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case RECOMMENDED_RETRIEVAL_MODE:
- if (RECOMMENDED_RETRIEVAL_MODE_MANUAL != value) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case CONTENT_CLASS:
- if ((value < CONTENT_CLASS_TEXT)
- || (value > CONTENT_CLASS_CONTENT_RICH)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- case RETRIEVE_STATUS:
- // According to oma-ts-mms-enc-v1_3, section 7.3.50, we modify the invalid value.
- if ((value > RETRIEVE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) &&
- (value < RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE)) {
- value = RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE;
- } else if ((value > RETRIEVE_STATUS_ERROR_PERMANENT_CONTENT_UNSUPPORTED) &&
- (value <= RETRIEVE_STATUS_ERROR_END)) {
- value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE;
- } else if ((value < RETRIEVE_STATUS_OK) ||
- ((value > RETRIEVE_STATUS_OK) &&
- (value < RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
- (value > RETRIEVE_STATUS_ERROR_END)) {
- value = RETRIEVE_STATUS_ERROR_PERMANENT_FAILURE;
- }
- break;
- case STORE_STATUS:
- // According to oma-ts-mms-enc-v1_3, section 7.3.58, we modify the invalid value.
- if ((value > STORE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM) &&
- (value < STORE_STATUS_ERROR_PERMANENT_FAILURE)) {
- value = STORE_STATUS_ERROR_TRANSIENT_FAILURE;
- } else if ((value > STORE_STATUS_ERROR_PERMANENT_MMBOX_FULL) &&
- (value <= STORE_STATUS_ERROR_END)) {
- value = STORE_STATUS_ERROR_PERMANENT_FAILURE;
- } else if ((value < STORE_STATUS_SUCCESS) ||
- ((value > STORE_STATUS_SUCCESS) &&
- (value < STORE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
- (value > STORE_STATUS_ERROR_END)) {
- value = STORE_STATUS_ERROR_PERMANENT_FAILURE;
- }
- break;
- case RESPONSE_STATUS:
- // According to oma-ts-mms-enc-v1_3, section 7.3.48, we modify the invalid value.
- if ((value > RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS) &&
- (value < RESPONSE_STATUS_ERROR_PERMANENT_FAILURE)) {
- value = RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE;
- } else if (((value > RESPONSE_STATUS_ERROR_PERMANENT_LACK_OF_PREPAID) &&
- (value <= RESPONSE_STATUS_ERROR_PERMANENT_END)) ||
- (value < RESPONSE_STATUS_OK) ||
- ((value > RESPONSE_STATUS_ERROR_UNSUPPORTED_MESSAGE) &&
- (value < RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE)) ||
- (value > RESPONSE_STATUS_ERROR_PERMANENT_END)) {
- value = RESPONSE_STATUS_ERROR_PERMANENT_FAILURE;
- }
- break;
- case MMS_VERSION:
- if ((value < MMS_VERSION_1_0)|| (value > MMS_VERSION_1_3)) {
- value = CURRENT_MMS_VERSION; // Current version is the default value.
- }
- break;
- case MESSAGE_TYPE:
- if ((value < MESSAGE_TYPE_SEND_REQ) || (value > MESSAGE_TYPE_CANCEL_CONF)) {
- // Invalid value.
- throw new InvalidHeaderValueException("Invalid Octet value!");
- }
- break;
- default:
- // This header value should not be Octect.
- throw new RuntimeException("Invalid header field!");
- }
- mHeaderMap.put(field, value);
- }
-
- /**
- * Get TextString value by header field.
- *
- * @param field the field
- * @return the TextString value of the pdu header
- * with specified header field
- */
- protected byte[] getTextString(int field) {
- return (byte[]) mHeaderMap.get(field);
- }
-
- /**
- * Set TextString value to pdu header by header field.
- *
- * @param value the value
- * @param field the field
- * @return the TextString value of the pdu header
- * with specified header field
- * @throws NullPointerException if the value is null.
- */
- protected void setTextString(byte[] value, int field) {
- /**
- * Check whether this field can be set for specific
- * header and check validity of the field.
- */
- if (null == value) {
- throw new NullPointerException();
- }
-
- switch (field) {
- case TRANSACTION_ID:
- case REPLY_CHARGING_ID:
- case AUX_APPLIC_ID:
- case APPLIC_ID:
- case REPLY_APPLIC_ID:
- case MESSAGE_ID:
- case REPLACE_ID:
- case CANCEL_ID:
- case CONTENT_LOCATION:
- case MESSAGE_CLASS:
- case CONTENT_TYPE:
- break;
- default:
- // This header value should not be Text-String.
- throw new RuntimeException("Invalid header field!");
- }
- mHeaderMap.put(field, value);
- }
-
- /**
- * Get EncodedStringValue value by header field.
- *
- * @param field the field
- * @return the EncodedStringValue value of the pdu header
- * with specified header field
- */
- protected EncodedStringValue getEncodedStringValue(int field) {
- return (EncodedStringValue) mHeaderMap.get(field);
- }
-
- /**
- * Get TO, CC or BCC header value.
- *
- * @param field the field
- * @return the EncodeStringValue array of the pdu header
- * with specified header field
- */
- protected EncodedStringValue[] getEncodedStringValues(int field) {
- ArrayList<EncodedStringValue> list =
- (ArrayList<EncodedStringValue>) mHeaderMap.get(field);
- if (null == list) {
- return null;
- }
- EncodedStringValue[] values = new EncodedStringValue[list.size()];
- return list.toArray(values);
- }
-
- /**
- * Set EncodedStringValue value to pdu header by header field.
- *
- * @param value the value
- * @param field the field
- * @return the EncodedStringValue value of the pdu header
- * with specified header field
- * @throws NullPointerException if the value is null.
- */
- protected void setEncodedStringValue(EncodedStringValue value, int field) {
- /**
- * Check whether this field can be set for specific
- * header and check validity of the field.
- */
- if (null == value) {
- throw new NullPointerException();
- }
-
- switch (field) {
- case SUBJECT:
- case RECOMMENDED_RETRIEVAL_MODE_TEXT:
- case RETRIEVE_TEXT:
- case STATUS_TEXT:
- case STORE_STATUS_TEXT:
- case RESPONSE_TEXT:
- case FROM:
- case PREVIOUSLY_SENT_BY:
- case MM_FLAGS:
- break;
- default:
- // This header value should not be Encoded-String-Value.
- throw new RuntimeException("Invalid header field!");
- }
-
- mHeaderMap.put(field, value);
- }
-
- /**
- * Set TO, CC or BCC header value.
- *
- * @param value the value
- * @param field the field
- * @return the EncodedStringValue value array of the pdu header
- * with specified header field
- * @throws NullPointerException if the value is null.
- */
- protected void setEncodedStringValues(EncodedStringValue[] value, int field) {
- /**
- * Check whether this field can be set for specific
- * header and check validity of the field.
- */
- if (null == value) {
- throw new NullPointerException();
- }
-
- switch (field) {
- case BCC:
- case CC:
- case TO:
- break;
- default:
- // This header value should not be Encoded-String-Value.
- throw new RuntimeException("Invalid header field!");
- }
-
- ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>();
- for (int i = 0; i < value.length; i++) {
- list.add(value[i]);
- }
- mHeaderMap.put(field, list);
- }
-
- /**
- * Append one EncodedStringValue to another.
- *
- * @param value the EncodedStringValue to append
- * @param field the field
- * @throws NullPointerException if the value is null.
- */
- protected void appendEncodedStringValue(EncodedStringValue value,
- int field) {
- if (null == value) {
- throw new NullPointerException();
- }
-
- switch (field) {
- case BCC:
- case CC:
- case TO:
- break;
- default:
- throw new RuntimeException("Invalid header field!");
- }
-
- ArrayList<EncodedStringValue> list =
- (ArrayList<EncodedStringValue>) mHeaderMap.get(field);
- if (null == list) {
- list = new ArrayList<EncodedStringValue>();
- }
- list.add(value);
- mHeaderMap.put(field, list);
- }
-
- /**
- * Get LongInteger value by header field.
- *
- * @param field the field
- * @return the LongInteger value of the pdu header
- * with specified header field. if return -1, the
- * field is not existed in pdu header.
- */
- protected long getLongInteger(int field) {
- Long longInteger = (Long) mHeaderMap.get(field);
- if (null == longInteger) {
- return -1;
- }
-
- return longInteger.longValue();
- }
-
- /**
- * Set LongInteger value to pdu header by header field.
- *
- * @param value the value
- * @param field the field
- */
- protected void setLongInteger(long value, int field) {
- /**
- * Check whether this field can be set for specific
- * header and check validity of the field.
- */
- switch (field) {
- case DATE:
- case REPLY_CHARGING_SIZE:
- case MESSAGE_SIZE:
- case MESSAGE_COUNT:
- case START:
- case LIMIT:
- case DELIVERY_TIME:
- case EXPIRY:
- case REPLY_CHARGING_DEADLINE:
- case PREVIOUSLY_SENT_DATE:
- break;
- default:
- // This header value should not be LongInteger.
- throw new RuntimeException("Invalid header field!");
- }
- mHeaderMap.put(field, value);
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java
deleted file mode 100755
index 015d864..0000000
--- a/core/java/com/google/android/mms/pdu/PduParser.java
+++ /dev/null
@@ -1,1912 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.ContentType;
-import com.google.android.mms.InvalidHeaderValueException;
-
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.HashMap;
-
-import android.content.res.Resources;
-
-public class PduParser {
- /**
- * The next are WAP values defined in WSP specification.
- */
- private static final int QUOTE = 127;
- private static final int LENGTH_QUOTE = 31;
- private static final int TEXT_MIN = 32;
- private static final int TEXT_MAX = 127;
- private static final int SHORT_INTEGER_MAX = 127;
- private static final int SHORT_LENGTH_MAX = 30;
- private static final int LONG_INTEGER_LENGTH_MAX = 8;
- private static final int QUOTED_STRING_FLAG = 34;
- private static final int END_STRING_FLAG = 0x00;
- //The next two are used by the interface "parseWapString" to
- //distinguish Text-String and Quoted-String.
- private static final int TYPE_TEXT_STRING = 0;
- private static final int TYPE_QUOTED_STRING = 1;
- private static final int TYPE_TOKEN_STRING = 2;
-
- /**
- * Specify the part position.
- */
- private static final int THE_FIRST_PART = 0;
- private static final int THE_LAST_PART = 1;
-
- /**
- * The pdu data.
- */
- private ByteArrayInputStream mPduDataStream = null;
-
- /**
- * Store pdu headers
- */
- private PduHeaders mHeaders = null;
-
- /**
- * Store pdu parts.
- */
- private PduBody mBody = null;
-
- /**
- * Store the "type" parameter in "Content-Type" header field.
- */
- private static byte[] mTypeParam = null;
-
- /**
- * Store the "start" parameter in "Content-Type" header field.
- */
- private static byte[] mStartParam = null;
-
- /**
- * The log tag.
- */
- private static final String LOG_TAG = "PduParser";
- private static final boolean DEBUG = false;
- private static final boolean LOCAL_LOGV = false;
-
- /**
- * Constructor.
- *
- * @param pduDataStream pdu data to be parsed
- */
- public PduParser(byte[] pduDataStream) {
- mPduDataStream = new ByteArrayInputStream(pduDataStream);
- }
-
- /**
- * Parse the pdu.
- *
- * @return the pdu structure if parsing successfully.
- * null if parsing error happened or mandatory fields are not set.
- */
- public GenericPdu parse(){
- if (mPduDataStream == null) {
- return null;
- }
-
- /* parse headers */
- mHeaders = parseHeaders(mPduDataStream);
- if (null == mHeaders) {
- // Parse headers failed.
- return null;
- }
-
- /* get the message type */
- int messageType = mHeaders.getOctet(PduHeaders.MESSAGE_TYPE);
-
- /* check mandatory header fields */
- if (false == checkMandatoryHeader(mHeaders)) {
- log("check mandatory headers failed!");
- return null;
- }
-
- if ((PduHeaders.MESSAGE_TYPE_SEND_REQ == messageType) ||
- (PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF == messageType)) {
- /* need to parse the parts */
- mBody = parseParts(mPduDataStream);
- if (null == mBody) {
- // Parse parts failed.
- return null;
- }
- }
-
- switch (messageType) {
- case PduHeaders.MESSAGE_TYPE_SEND_REQ:
- SendReq sendReq = new SendReq(mHeaders, mBody);
- return sendReq;
- case PduHeaders.MESSAGE_TYPE_SEND_CONF:
- SendConf sendConf = new SendConf(mHeaders);
- return sendConf;
- case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
- NotificationInd notificationInd =
- new NotificationInd(mHeaders);
- return notificationInd;
- case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
- NotifyRespInd notifyRespInd =
- new NotifyRespInd(mHeaders);
- return notifyRespInd;
- case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
- RetrieveConf retrieveConf =
- new RetrieveConf(mHeaders, mBody);
-
- byte[] contentType = retrieveConf.getContentType();
- if (null == contentType) {
- return null;
- }
- String ctTypeStr = new String(contentType);
- if (ctTypeStr.equals(ContentType.MULTIPART_MIXED)
- || ctTypeStr.equals(ContentType.MULTIPART_RELATED)
- || ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
- // The MMS content type must be "application/vnd.wap.multipart.mixed"
- // or "application/vnd.wap.multipart.related"
- // or "application/vnd.wap.multipart.alternative"
- return retrieveConf;
- } else if (ctTypeStr.equals(ContentType.MULTIPART_ALTERNATIVE)) {
- // "application/vnd.wap.multipart.alternative"
- // should take only the first part.
- PduPart firstPart = mBody.getPart(0);
- mBody.removeAll();
- mBody.addPart(0, firstPart);
- return retrieveConf;
- }
- return null;
- case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
- DeliveryInd deliveryInd =
- new DeliveryInd(mHeaders);
- return deliveryInd;
- case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
- AcknowledgeInd acknowledgeInd =
- new AcknowledgeInd(mHeaders);
- return acknowledgeInd;
- case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
- ReadOrigInd readOrigInd =
- new ReadOrigInd(mHeaders);
- return readOrigInd;
- case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
- ReadRecInd readRecInd =
- new ReadRecInd(mHeaders);
- return readRecInd;
- default:
- log("Parser doesn't support this message type in this version!");
- return null;
- }
- }
-
- /**
- * Parse pdu headers.
- *
- * @param pduDataStream pdu data input stream
- * @return headers in PduHeaders structure, null when parse fail
- */
- protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream){
- if (pduDataStream == null) {
- return null;
- }
-
- boolean keepParsing = true;
- PduHeaders headers = new PduHeaders();
-
- while (keepParsing && (pduDataStream.available() > 0)) {
- pduDataStream.mark(1);
- int headerField = extractByteValue(pduDataStream);
- /* parse custom text header */
- if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) {
- pduDataStream.reset();
- byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- if (LOCAL_LOGV) {
- Log.v(LOG_TAG, "TextHeader: " + new String(bVal));
- }
- /* we should ignore it at the moment */
- continue;
- }
- switch (headerField) {
- case PduHeaders.MESSAGE_TYPE:
- {
- int messageType = extractByteValue(pduDataStream);
- switch (messageType) {
- // We don't support these kind of messages now.
- case PduHeaders.MESSAGE_TYPE_FORWARD_REQ:
- case PduHeaders.MESSAGE_TYPE_FORWARD_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ:
- case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ:
- case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ:
- case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ:
- case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_DESCR:
- case PduHeaders.MESSAGE_TYPE_DELETE_REQ:
- case PduHeaders.MESSAGE_TYPE_DELETE_CONF:
- case PduHeaders.MESSAGE_TYPE_CANCEL_REQ:
- case PduHeaders.MESSAGE_TYPE_CANCEL_CONF:
- return null;
- }
- try {
- headers.setOctet(messageType, headerField);
- } catch(InvalidHeaderValueException e) {
- log("Set invalid Octet value: " + messageType +
- " into the header filed: " + headerField);
- return null;
- } catch(RuntimeException e) {
- log(headerField + "is not Octet header field!");
- return null;
- }
- break;
- }
- /* Octect value */
- case PduHeaders.REPORT_ALLOWED:
- case PduHeaders.ADAPTATION_ALLOWED:
- case PduHeaders.DELIVERY_REPORT:
- case PduHeaders.DRM_CONTENT:
- case PduHeaders.DISTRIBUTION_INDICATOR:
- case PduHeaders.QUOTAS:
- case PduHeaders.READ_REPORT:
- case PduHeaders.STORE:
- case PduHeaders.STORED:
- case PduHeaders.TOTALS:
- case PduHeaders.SENDER_VISIBILITY:
- case PduHeaders.READ_STATUS:
- case PduHeaders.CANCEL_STATUS:
- case PduHeaders.PRIORITY:
- case PduHeaders.STATUS:
- case PduHeaders.REPLY_CHARGING:
- case PduHeaders.MM_STATE:
- case PduHeaders.RECOMMENDED_RETRIEVAL_MODE:
- case PduHeaders.CONTENT_CLASS:
- case PduHeaders.RETRIEVE_STATUS:
- case PduHeaders.STORE_STATUS:
- /**
- * The following field has a different value when
- * used in the M-Mbox-Delete.conf and M-Delete.conf PDU.
- * For now we ignore this fact, since we do not support these PDUs
- */
- case PduHeaders.RESPONSE_STATUS:
- {
- int value = extractByteValue(pduDataStream);
-
- try {
- headers.setOctet(value, headerField);
- } catch(InvalidHeaderValueException e) {
- log("Set invalid Octet value: " + value +
- " into the header filed: " + headerField);
- return null;
- } catch(RuntimeException e) {
- log(headerField + "is not Octet header field!");
- return null;
- }
- break;
- }
-
- /* Long-Integer */
- case PduHeaders.DATE:
- case PduHeaders.REPLY_CHARGING_SIZE:
- case PduHeaders.MESSAGE_SIZE:
- {
- try {
- long value = parseLongInteger(pduDataStream);
- headers.setLongInteger(value, headerField);
- } catch(RuntimeException e) {
- log(headerField + "is not Long-Integer header field!");
- return null;
- }
- break;
- }
-
- /* Integer-Value */
- case PduHeaders.MESSAGE_COUNT:
- case PduHeaders.START:
- case PduHeaders.LIMIT:
- {
- try {
- long value = parseIntegerValue(pduDataStream);
- headers.setLongInteger(value, headerField);
- } catch(RuntimeException e) {
- log(headerField + "is not Long-Integer header field!");
- return null;
- }
- break;
- }
-
- /* Text-String */
- case PduHeaders.TRANSACTION_ID:
- case PduHeaders.REPLY_CHARGING_ID:
- case PduHeaders.AUX_APPLIC_ID:
- case PduHeaders.APPLIC_ID:
- case PduHeaders.REPLY_APPLIC_ID:
- /**
- * The next three header fields are email addresses
- * as defined in RFC2822,
- * not including the characters "<" and ">"
- */
- case PduHeaders.MESSAGE_ID:
- case PduHeaders.REPLACE_ID:
- case PduHeaders.CANCEL_ID:
- /**
- * The following field has a different value when
- * used in the M-Mbox-Delete.conf and M-Delete.conf PDU.
- * For now we ignore this fact, since we do not support these PDUs
- */
- case PduHeaders.CONTENT_LOCATION:
- {
- byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- if (null != value) {
- try {
- headers.setTextString(value, headerField);
- } catch(NullPointerException e) {
- log("null pointer error!");
- } catch(RuntimeException e) {
- log(headerField + "is not Text-String header field!");
- return null;
- }
- }
- break;
- }
-
- /* Encoded-string-value */
- case PduHeaders.SUBJECT:
- case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT:
- case PduHeaders.RETRIEVE_TEXT:
- case PduHeaders.STATUS_TEXT:
- case PduHeaders.STORE_STATUS_TEXT:
- /* the next one is not support
- * M-Mbox-Delete.conf and M-Delete.conf now */
- case PduHeaders.RESPONSE_TEXT:
- {
- EncodedStringValue value =
- parseEncodedStringValue(pduDataStream);
- if (null != value) {
- try {
- headers.setEncodedStringValue(value, headerField);
- } catch(NullPointerException e) {
- log("null pointer error!");
- } catch (RuntimeException e) {
- log(headerField + "is not Encoded-String-Value header field!");
- return null;
- }
- }
- break;
- }
-
- /* Addressing model */
- case PduHeaders.BCC:
- case PduHeaders.CC:
- case PduHeaders.TO:
- {
- EncodedStringValue value =
- parseEncodedStringValue(pduDataStream);
- if (null != value) {
- byte[] address = value.getTextString();
- if (null != address) {
- String str = new String(address);
- int endIndex = str.indexOf("/");
- if (endIndex > 0) {
- str = str.substring(0, endIndex);
- }
- try {
- value.setTextString(str.getBytes());
- } catch(NullPointerException e) {
- log("null pointer error!");
- return null;
- }
- }
-
- try {
- headers.appendEncodedStringValue(value, headerField);
- } catch(NullPointerException e) {
- log("null pointer error!");
- } catch(RuntimeException e) {
- log(headerField + "is not Encoded-String-Value header field!");
- return null;
- }
- }
- break;
- }
-
- /* Value-length
- * (Absolute-token Date-value | Relative-token Delta-seconds-value) */
- case PduHeaders.DELIVERY_TIME:
- case PduHeaders.EXPIRY:
- case PduHeaders.REPLY_CHARGING_DEADLINE:
- {
- /* parse Value-length */
- parseValueLength(pduDataStream);
-
- /* Absolute-token or Relative-token */
- int token = extractByteValue(pduDataStream);
-
- /* Date-value or Delta-seconds-value */
- long timeValue;
- try {
- timeValue = parseLongInteger(pduDataStream);
- } catch(RuntimeException e) {
- log(headerField + "is not Long-Integer header field!");
- return null;
- }
- if (PduHeaders.VALUE_RELATIVE_TOKEN == token) {
- /* need to convert the Delta-seconds-value
- * into Date-value */
- timeValue = System.currentTimeMillis()/1000 + timeValue;
- }
-
- try {
- headers.setLongInteger(timeValue, headerField);
- } catch(RuntimeException e) {
- log(headerField + "is not Long-Integer header field!");
- return null;
- }
- break;
- }
-
- case PduHeaders.FROM: {
- /* From-value =
- * Value-length
- * (Address-present-token Encoded-string-value | Insert-address-token)
- */
- EncodedStringValue from = null;
- parseValueLength(pduDataStream); /* parse value-length */
-
- /* Address-present-token or Insert-address-token */
- int fromToken = extractByteValue(pduDataStream);
-
- /* Address-present-token or Insert-address-token */
- if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) {
- /* Encoded-string-value */
- from = parseEncodedStringValue(pduDataStream);
- if (null != from) {
- byte[] address = from.getTextString();
- if (null != address) {
- String str = new String(address);
- int endIndex = str.indexOf("/");
- if (endIndex > 0) {
- str = str.substring(0, endIndex);
- }
- try {
- from.setTextString(str.getBytes());
- } catch(NullPointerException e) {
- log("null pointer error!");
- return null;
- }
- }
- }
- } else {
- try {
- from = new EncodedStringValue(
- PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes());
- } catch(NullPointerException e) {
- log(headerField + "is not Encoded-String-Value header field!");
- return null;
- }
- }
-
- try {
- headers.setEncodedStringValue(from, PduHeaders.FROM);
- } catch(NullPointerException e) {
- log("null pointer error!");
- } catch(RuntimeException e) {
- log(headerField + "is not Encoded-String-Value header field!");
- return null;
- }
- break;
- }
-
- case PduHeaders.MESSAGE_CLASS: {
- /* Message-class-value = Class-identifier | Token-text */
- pduDataStream.mark(1);
- int messageClass = extractByteValue(pduDataStream);
-
- if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) {
- /* Class-identifier */
- try {
- if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) {
- headers.setTextString(
- PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(),
- PduHeaders.MESSAGE_CLASS);
- } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) {
- headers.setTextString(
- PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(),
- PduHeaders.MESSAGE_CLASS);
- } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) {
- headers.setTextString(
- PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(),
- PduHeaders.MESSAGE_CLASS);
- } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) {
- headers.setTextString(
- PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(),
- PduHeaders.MESSAGE_CLASS);
- }
- } catch(NullPointerException e) {
- log("null pointer error!");
- } catch(RuntimeException e) {
- log(headerField + "is not Text-String header field!");
- return null;
- }
- } else {
- /* Token-text */
- pduDataStream.reset();
- byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- if (null != messageClassString) {
- try {
- headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS);
- } catch(NullPointerException e) {
- log("null pointer error!");
- } catch(RuntimeException e) {
- log(headerField + "is not Text-String header field!");
- return null;
- }
- }
- }
- break;
- }
-
- case PduHeaders.MMS_VERSION: {
- int version = parseShortInteger(pduDataStream);
-
- try {
- headers.setOctet(version, PduHeaders.MMS_VERSION);
- } catch(InvalidHeaderValueException e) {
- log("Set invalid Octet value: " + version +
- " into the header filed: " + headerField);
- return null;
- } catch(RuntimeException e) {
- log(headerField + "is not Octet header field!");
- return null;
- }
- break;
- }
-
- case PduHeaders.PREVIOUSLY_SENT_BY: {
- /* Previously-sent-by-value =
- * Value-length Forwarded-count-value Encoded-string-value */
- /* parse value-length */
- parseValueLength(pduDataStream);
-
- /* parse Forwarded-count-value */
- try {
- parseIntegerValue(pduDataStream);
- } catch(RuntimeException e) {
- log(headerField + " is not Integer-Value");
- return null;
- }
-
- /* parse Encoded-string-value */
- EncodedStringValue previouslySentBy =
- parseEncodedStringValue(pduDataStream);
- if (null != previouslySentBy) {
- try {
- headers.setEncodedStringValue(previouslySentBy,
- PduHeaders.PREVIOUSLY_SENT_BY);
- } catch(NullPointerException e) {
- log("null pointer error!");
- } catch(RuntimeException e) {
- log(headerField + "is not Encoded-String-Value header field!");
- return null;
- }
- }
- break;
- }
-
- case PduHeaders.PREVIOUSLY_SENT_DATE: {
- /* Previously-sent-date-value =
- * Value-length Forwarded-count-value Date-value */
- /* parse value-length */
- parseValueLength(pduDataStream);
-
- /* parse Forwarded-count-value */
- try {
- parseIntegerValue(pduDataStream);
- } catch(RuntimeException e) {
- log(headerField + " is not Integer-Value");
- return null;
- }
-
- /* Date-value */
- try {
- long perviouslySentDate = parseLongInteger(pduDataStream);
- headers.setLongInteger(perviouslySentDate,
- PduHeaders.PREVIOUSLY_SENT_DATE);
- } catch(RuntimeException e) {
- log(headerField + "is not Long-Integer header field!");
- return null;
- }
- break;
- }
-
- case PduHeaders.MM_FLAGS: {
- /* MM-flags-value =
- * Value-length
- * ( Add-token | Remove-token | Filter-token )
- * Encoded-string-value
- */
-
- /* parse Value-length */
- parseValueLength(pduDataStream);
-
- /* Add-token | Remove-token | Filter-token */
- extractByteValue(pduDataStream);
-
- /* Encoded-string-value */
- parseEncodedStringValue(pduDataStream);
-
- /* not store this header filed in "headers",
- * because now PduHeaders doesn't support it */
- break;
- }
-
- /* Value-length
- * (Message-total-token | Size-total-token) Integer-Value */
- case PduHeaders.MBOX_TOTALS:
- case PduHeaders.MBOX_QUOTAS:
- {
- /* Value-length */
- parseValueLength(pduDataStream);
-
- /* Message-total-token | Size-total-token */
- extractByteValue(pduDataStream);
-
- /*Integer-Value*/
- try {
- parseIntegerValue(pduDataStream);
- } catch(RuntimeException e) {
- log(headerField + " is not Integer-Value");
- return null;
- }
-
- /* not store these headers filed in "headers",
- because now PduHeaders doesn't support them */
- break;
- }
-
- case PduHeaders.ELEMENT_DESCRIPTOR: {
- parseContentType(pduDataStream, null);
-
- /* not store this header filed in "headers",
- because now PduHeaders doesn't support it */
- break;
- }
-
- case PduHeaders.CONTENT_TYPE: {
- HashMap<Integer, Object> map =
- new HashMap<Integer, Object>();
- byte[] contentType =
- parseContentType(pduDataStream, map);
-
- if (null != contentType) {
- try {
- headers.setTextString(contentType, PduHeaders.CONTENT_TYPE);
- } catch(NullPointerException e) {
- log("null pointer error!");
- } catch(RuntimeException e) {
- log(headerField + "is not Text-String header field!");
- return null;
- }
- }
-
- /* get start parameter */
- mStartParam = (byte[]) map.get(PduPart.P_START);
-
- /* get charset parameter */
- mTypeParam= (byte[]) map.get(PduPart.P_TYPE);
-
- keepParsing = false;
- break;
- }
-
- case PduHeaders.CONTENT:
- case PduHeaders.ADDITIONAL_HEADERS:
- case PduHeaders.ATTRIBUTES:
- default: {
- log("Unknown header");
- }
- }
- }
-
- return headers;
- }
-
- /**
- * Parse pdu parts.
- *
- * @param pduDataStream pdu data input stream
- * @return parts in PduBody structure
- */
- protected static PduBody parseParts(ByteArrayInputStream pduDataStream) {
- if (pduDataStream == null) {
- return null;
- }
-
- int count = parseUnsignedInt(pduDataStream); // get the number of parts
- PduBody body = new PduBody();
-
- for (int i = 0 ; i < count ; i++) {
- int headerLength = parseUnsignedInt(pduDataStream);
- int dataLength = parseUnsignedInt(pduDataStream);
- PduPart part = new PduPart();
- int startPos = pduDataStream.available();
- if (startPos <= 0) {
- // Invalid part.
- return null;
- }
-
- /* parse part's content-type */
- HashMap<Integer, Object> map = new HashMap<Integer, Object>();
- byte[] contentType = parseContentType(pduDataStream, map);
- if (null != contentType) {
- part.setContentType(contentType);
- } else {
- part.setContentType((PduContentTypes.contentTypes[0]).getBytes()); //"*/*"
- }
-
- /* get name parameter */
- byte[] name = (byte[]) map.get(PduPart.P_NAME);
- if (null != name) {
- part.setName(name);
- }
-
- /* get charset parameter */
- Integer charset = (Integer) map.get(PduPart.P_CHARSET);
- if (null != charset) {
- part.setCharset(charset);
- }
-
- /* parse part's headers */
- int endPos = pduDataStream.available();
- int partHeaderLen = headerLength - (startPos - endPos);
- if (partHeaderLen > 0) {
- if (false == parsePartHeaders(pduDataStream, part, partHeaderLen)) {
- // Parse part header faild.
- return null;
- }
- } else if (partHeaderLen < 0) {
- // Invalid length of content-type.
- return null;
- }
-
- /* FIXME: check content-id, name, filename and content location,
- * if not set anyone of them, generate a default content-location
- */
- if ((null == part.getContentLocation())
- && (null == part.getName())
- && (null == part.getFilename())
- && (null == part.getContentId())) {
- part.setContentLocation(Long.toOctalString(
- System.currentTimeMillis()).getBytes());
- }
-
- /* get part's data */
- if (dataLength > 0) {
- byte[] partData = new byte[dataLength];
- String partContentType = new String(part.getContentType());
- pduDataStream.read(partData, 0, dataLength);
- if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) {
- // parse "multipart/vnd.wap.multipart.alternative".
- PduBody childBody = parseParts(new ByteArrayInputStream(partData));
- // take the first part of children.
- part = childBody.getPart(0);
- } else {
- // Check Content-Transfer-Encoding.
- byte[] partDataEncoding = part.getContentTransferEncoding();
- if (null != partDataEncoding) {
- String encoding = new String(partDataEncoding);
- if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) {
- // Decode "base64" into "binary".
- partData = Base64.decodeBase64(partData);
- } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) {
- // Decode "quoted-printable" into "binary".
- partData = QuotedPrintable.decodeQuotedPrintable(partData);
- } else {
- // "binary" is the default encoding.
- }
- }
- if (null == partData) {
- log("Decode part data error!");
- return null;
- }
- part.setData(partData);
- }
- }
-
- /* add this part to body */
- if (THE_FIRST_PART == checkPartPosition(part)) {
- /* this is the first part */
- body.addPart(0, part);
- } else {
- /* add the part to the end */
- body.addPart(part);
- }
- }
-
- return body;
- }
-
- /**
- * Log status.
- *
- * @param text log information
- */
- private static void log(String text) {
- if (LOCAL_LOGV) {
- Log.v(LOG_TAG, text);
- }
- }
-
- /**
- * Parse unsigned integer.
- *
- * @param pduDataStream pdu data input stream
- * @return the integer, -1 when failed
- */
- protected static int parseUnsignedInt(ByteArrayInputStream pduDataStream) {
- /**
- * From wap-230-wsp-20010705-a.pdf
- * The maximum size of a uintvar is 32 bits.
- * So it will be encoded in no more than 5 octets.
- */
- assert(null != pduDataStream);
- int result = 0;
- int temp = pduDataStream.read();
- if (temp == -1) {
- return temp;
- }
-
- while((temp & 0x80) != 0) {
- result = result << 7;
- result |= temp & 0x7F;
- temp = pduDataStream.read();
- if (temp == -1) {
- return temp;
- }
- }
-
- result = result << 7;
- result |= temp & 0x7F;
-
- return result;
- }
-
- /**
- * Parse value length.
- *
- * @param pduDataStream pdu data input stream
- * @return the integer
- */
- protected static int parseValueLength(ByteArrayInputStream pduDataStream) {
- /**
- * From wap-230-wsp-20010705-a.pdf
- * Value-length = Short-length | (Length-quote Length)
- * Short-length = <Any octet 0-30>
- * Length-quote = <Octet 31>
- * Length = Uintvar-integer
- * Uintvar-integer = 1*5 OCTET
- */
- assert(null != pduDataStream);
- int temp = pduDataStream.read();
- assert(-1 != temp);
- int first = temp & 0xFF;
-
- if (first <= SHORT_LENGTH_MAX) {
- return first;
- } else if (first == LENGTH_QUOTE) {
- return parseUnsignedInt(pduDataStream);
- }
-
- throw new RuntimeException ("Value length > LENGTH_QUOTE!");
- }
-
- /**
- * Parse encoded string value.
- *
- * @param pduDataStream pdu data input stream
- * @return the EncodedStringValue
- */
- protected static EncodedStringValue parseEncodedStringValue(ByteArrayInputStream pduDataStream){
- /**
- * From OMA-TS-MMS-ENC-V1_3-20050927-C.pdf
- * Encoded-string-value = Text-string | Value-length Char-set Text-string
- */
- assert(null != pduDataStream);
- pduDataStream.mark(1);
- EncodedStringValue returnValue = null;
- int charset = 0;
- int temp = pduDataStream.read();
- assert(-1 != temp);
- int first = temp & 0xFF;
- if (first == 0) {
- return null; // Blank subject, bail.
- }
-
- pduDataStream.reset();
- if (first < TEXT_MIN) {
- parseValueLength(pduDataStream);
-
- charset = parseShortInteger(pduDataStream); //get the "Charset"
- }
-
- byte[] textString = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-
- try {
- if (0 != charset) {
- returnValue = new EncodedStringValue(charset, textString);
- } else {
- returnValue = new EncodedStringValue(textString);
- }
- } catch(Exception e) {
- return null;
- }
-
- return returnValue;
- }
-
- /**
- * Parse Text-String or Quoted-String.
- *
- * @param pduDataStream pdu data input stream
- * @param stringType TYPE_TEXT_STRING or TYPE_QUOTED_STRING
- * @return the string without End-of-string in byte array
- */
- protected static byte[] parseWapString(ByteArrayInputStream pduDataStream,
- int stringType) {
- assert(null != pduDataStream);
- /**
- * From wap-230-wsp-20010705-a.pdf
- * Text-string = [Quote] *TEXT End-of-string
- * If the first character in the TEXT is in the range of 128-255,
- * a Quote character must precede it.
- * Otherwise the Quote character must be omitted.
- * The Quote is not part of the contents.
- * Quote = <Octet 127>
- * End-of-string = <Octet 0>
- *
- * Quoted-string = <Octet 34> *TEXT End-of-string
- *
- * Token-text = Token End-of-string
- */
-
- // Mark supposed beginning of Text-string
- // We will have to mark again if first char is QUOTE or QUOTED_STRING_FLAG
- pduDataStream.mark(1);
-
- // Check first char
- int temp = pduDataStream.read();
- assert(-1 != temp);
- if ((TYPE_QUOTED_STRING == stringType) &&
- (QUOTED_STRING_FLAG == temp)) {
- // Mark again if QUOTED_STRING_FLAG and ignore it
- pduDataStream.mark(1);
- } else if ((TYPE_TEXT_STRING == stringType) &&
- (QUOTE == temp)) {
- // Mark again if QUOTE and ignore it
- pduDataStream.mark(1);
- } else {
- // Otherwise go back to origin
- pduDataStream.reset();
- }
-
- // We are now definitely at the beginning of string
- /**
- * Return *TOKEN or *TEXT (Text-String without QUOTE,
- * Quoted-String without QUOTED_STRING_FLAG and without End-of-string)
- */
- return getWapString(pduDataStream, stringType);
- }
-
- /**
- * Check TOKEN data defined in RFC2616.
- * @param ch checking data
- * @return true when ch is TOKEN, false when ch is not TOKEN
- */
- protected static boolean isTokenCharacter(int ch) {
- /**
- * Token = 1*<any CHAR except CTLs or separators>
- * separators = "("(40) | ")"(41) | "<"(60) | ">"(62) | "@"(64)
- * | ","(44) | ";"(59) | ":"(58) | "\"(92) | <">(34)
- * | "/"(47) | "["(91) | "]"(93) | "?"(63) | "="(61)
- * | "{"(123) | "}"(125) | SP(32) | HT(9)
- * CHAR = <any US-ASCII character (octets 0 - 127)>
- * CTL = <any US-ASCII control character
- * (octets 0 - 31) and DEL (127)>
- * SP = <US-ASCII SP, space (32)>
- * HT = <US-ASCII HT, horizontal-tab (9)>
- */
- if((ch < 33) || (ch > 126)) {
- return false;
- }
-
- switch(ch) {
- case '"': /* '"' */
- case '(': /* '(' */
- case ')': /* ')' */
- case ',': /* ',' */
- case '/': /* '/' */
- case ':': /* ':' */
- case ';': /* ';' */
- case '<': /* '<' */
- case '=': /* '=' */
- case '>': /* '>' */
- case '?': /* '?' */
- case '@': /* '@' */
- case '[': /* '[' */
- case '\\': /* '\' */
- case ']': /* ']' */
- case '{': /* '{' */
- case '}': /* '}' */
- return false;
- }
-
- return true;
- }
-
- /**
- * Check TEXT data defined in RFC2616.
- * @param ch checking data
- * @return true when ch is TEXT, false when ch is not TEXT
- */
- protected static boolean isText(int ch) {
- /**
- * TEXT = <any OCTET except CTLs,
- * but including LWS>
- * CTL = <any US-ASCII control character
- * (octets 0 - 31) and DEL (127)>
- * LWS = [CRLF] 1*( SP | HT )
- * CRLF = CR LF
- * CR = <US-ASCII CR, carriage return (13)>
- * LF = <US-ASCII LF, linefeed (10)>
- */
- if(((ch >= 32) && (ch <= 126)) || ((ch >= 128) && (ch <= 255))) {
- return true;
- }
-
- switch(ch) {
- case '\t': /* '\t' */
- case '\n': /* '\n' */
- case '\r': /* '\r' */
- return true;
- }
-
- return false;
- }
-
- protected static byte[] getWapString(ByteArrayInputStream pduDataStream,
- int stringType) {
- assert(null != pduDataStream);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int temp = pduDataStream.read();
- assert(-1 != temp);
- while((-1 != temp) && ('\0' != temp)) {
- // check each of the character
- if (stringType == TYPE_TOKEN_STRING) {
- if (isTokenCharacter(temp)) {
- out.write(temp);
- }
- } else {
- if (isText(temp)) {
- out.write(temp);
- }
- }
-
- temp = pduDataStream.read();
- assert(-1 != temp);
- }
-
- if (out.size() > 0) {
- return out.toByteArray();
- }
-
- return null;
- }
-
- /**
- * Extract a byte value from the input stream.
- *
- * @param pduDataStream pdu data input stream
- * @return the byte
- */
- protected static int extractByteValue(ByteArrayInputStream pduDataStream) {
- assert(null != pduDataStream);
- int temp = pduDataStream.read();
- assert(-1 != temp);
- return temp & 0xFF;
- }
-
- /**
- * Parse Short-Integer.
- *
- * @param pduDataStream pdu data input stream
- * @return the byte
- */
- protected static int parseShortInteger(ByteArrayInputStream pduDataStream) {
- /**
- * From wap-230-wsp-20010705-a.pdf
- * Short-integer = OCTET
- * Integers in range 0-127 shall be encoded as a one
- * octet value with the most significant bit set to one (1xxx xxxx)
- * and with the value in the remaining least significant bits.
- */
- assert(null != pduDataStream);
- int temp = pduDataStream.read();
- assert(-1 != temp);
- return temp & 0x7F;
- }
-
- /**
- * Parse Long-Integer.
- *
- * @param pduDataStream pdu data input stream
- * @return long integer
- */
- protected static long parseLongInteger(ByteArrayInputStream pduDataStream) {
- /**
- * From wap-230-wsp-20010705-a.pdf
- * Long-integer = Short-length Multi-octet-integer
- * The Short-length indicates the length of the Multi-octet-integer
- * Multi-octet-integer = 1*30 OCTET
- * The content octets shall be an unsigned integer value
- * with the most significant octet encoded first (big-endian representation).
- * The minimum number of octets must be used to encode the value.
- * Short-length = <Any octet 0-30>
- */
- assert(null != pduDataStream);
- int temp = pduDataStream.read();
- assert(-1 != temp);
- int count = temp & 0xFF;
-
- if (count > LONG_INTEGER_LENGTH_MAX) {
- throw new RuntimeException("Octet count greater than 8 and I can't represent that!");
- }
-
- long result = 0;
-
- for (int i = 0 ; i < count ; i++) {
- temp = pduDataStream.read();
- assert(-1 != temp);
- result <<= 8;
- result += (temp & 0xFF);
- }
-
- return result;
- }
-
- /**
- * Parse Integer-Value.
- *
- * @param pduDataStream pdu data input stream
- * @return long integer
- */
- protected static long parseIntegerValue(ByteArrayInputStream pduDataStream) {
- /**
- * From wap-230-wsp-20010705-a.pdf
- * Integer-Value = Short-integer | Long-integer
- */
- assert(null != pduDataStream);
- pduDataStream.mark(1);
- int temp = pduDataStream.read();
- assert(-1 != temp);
- pduDataStream.reset();
- if (temp > SHORT_INTEGER_MAX) {
- return parseShortInteger(pduDataStream);
- } else {
- return parseLongInteger(pduDataStream);
- }
- }
-
- /**
- * To skip length of the wap value.
- *
- * @param pduDataStream pdu data input stream
- * @param length area size
- * @return the values in this area
- */
- protected static int skipWapValue(ByteArrayInputStream pduDataStream, int length) {
- assert(null != pduDataStream);
- byte[] area = new byte[length];
- int readLen = pduDataStream.read(area, 0, length);
- if (readLen < length) { //The actually read length is lower than the length
- return -1;
- } else {
- return readLen;
- }
- }
-
- /**
- * Parse content type parameters. For now we just support
- * four parameters used in mms: "type", "start", "name", "charset".
- *
- * @param pduDataStream pdu data input stream
- * @param map to store parameters of Content-Type field
- * @param length length of all the parameters
- */
- protected static void parseContentTypeParams(ByteArrayInputStream pduDataStream,
- HashMap<Integer, Object> map, Integer length) {
- /**
- * From wap-230-wsp-20010705-a.pdf
- * Parameter = Typed-parameter | Untyped-parameter
- * Typed-parameter = Well-known-parameter-token Typed-value
- * the actual expected type of the value is implied by the well-known parameter
- * Well-known-parameter-token = Integer-value
- * the code values used for parameters are specified in the Assigned Numbers appendix
- * Typed-value = Compact-value | Text-value
- * In addition to the expected type, there may be no value.
- * If the value cannot be encoded using the expected type, it shall be encoded as text.
- * Compact-value = Integer-value |
- * Date-value | Delta-seconds-value | Q-value | Version-value |
- * Uri-value
- * Untyped-parameter = Token-text Untyped-value
- * the type of the value is unknown, but it shall be encoded as an integer,
- * if that is possible.
- * Untyped-value = Integer-value | Text-value
- */
- assert(null != pduDataStream);
- assert(length > 0);
-
- int startPos = pduDataStream.available();
- int tempPos = 0;
- int lastLen = length;
- while(0 < lastLen) {
- int param = pduDataStream.read();
- assert(-1 != param);
- lastLen--;
-
- switch (param) {
- /**
- * From rfc2387, chapter 3.1
- * The type parameter must be specified and its value is the MIME media
- * type of the "root" body part. It permits a MIME user agent to
- * determine the content-type without reference to the enclosed body
- * part. If the value of the type parameter and the root body part's
- * content-type differ then the User Agent's behavior is undefined.
- *
- * From wap-230-wsp-20010705-a.pdf
- * type = Constrained-encoding
- * Constrained-encoding = Extension-Media | Short-integer
- * Extension-media = *TEXT End-of-string
- */
- case PduPart.P_TYPE:
- case PduPart.P_CT_MR_TYPE:
- pduDataStream.mark(1);
- int first = extractByteValue(pduDataStream);
- pduDataStream.reset();
- if (first > TEXT_MAX) {
- // Short-integer (well-known type)
- int index = parseShortInteger(pduDataStream);
-
- if (index < PduContentTypes.contentTypes.length) {
- byte[] type = (PduContentTypes.contentTypes[index]).getBytes();
- map.put(PduPart.P_TYPE, type);
- } else {
- //not support this type, ignore it.
- }
- } else {
- // Text-String (extension-media)
- byte[] type = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- if ((null != type) && (null != map)) {
- map.put(PduPart.P_TYPE, type);
- }
- }
-
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
- break;
-
- /**
- * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.3.
- * Start Parameter Referring to Presentation
- *
- * From rfc2387, chapter 3.2
- * The start parameter, if given, is the content-ID of the compound
- * object's "root". If not present the "root" is the first body part in
- * the Multipart/Related entity. The "root" is the element the
- * applications processes first.
- *
- * From wap-230-wsp-20010705-a.pdf
- * start = Text-String
- */
- case PduPart.P_START:
- case PduPart.P_DEP_START:
- byte[] start = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- if ((null != start) && (null != map)) {
- map.put(PduPart.P_START, start);
- }
-
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
- break;
-
- /**
- * From oma-ts-mms-conf-v1_3.pdf
- * In creation, the character set SHALL be either us-ascii
- * (IANA MIBenum 3) or utf-8 (IANA MIBenum 106)[Unicode].
- * In retrieval, both us-ascii and utf-8 SHALL be supported.
- *
- * From wap-230-wsp-20010705-a.pdf
- * charset = Well-known-charset|Text-String
- * Well-known-charset = Any-charset | Integer-value
- * Both are encoded using values from Character Set
- * Assignments table in Assigned Numbers
- * Any-charset = <Octet 128>
- * Equivalent to the special RFC2616 charset value "*"
- */
- case PduPart.P_CHARSET:
- pduDataStream.mark(1);
- int firstValue = extractByteValue(pduDataStream);
- pduDataStream.reset();
- //Check first char
- if (((firstValue > TEXT_MIN) && (firstValue < TEXT_MAX)) ||
- (END_STRING_FLAG == firstValue)) {
- //Text-String (extension-charset)
- byte[] charsetStr = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- try {
- int charsetInt = CharacterSets.getMibEnumValue(
- new String(charsetStr));
- map.put(PduPart.P_CHARSET, charsetInt);
- } catch (UnsupportedEncodingException e) {
- // Not a well-known charset, use "*".
- Log.e(LOG_TAG, Arrays.toString(charsetStr), e);
- map.put(PduPart.P_CHARSET, CharacterSets.ANY_CHARSET);
- }
- } else {
- //Well-known-charset
- int charset = (int) parseIntegerValue(pduDataStream);
- if (map != null) {
- map.put(PduPart.P_CHARSET, charset);
- }
- }
-
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
- break;
-
- /**
- * From oma-ts-mms-conf-v1_3.pdf
- * A name for multipart object SHALL be encoded using name-parameter
- * for Content-Type header in WSP multipart headers.
- *
- * From wap-230-wsp-20010705-a.pdf
- * name = Text-String
- */
- case PduPart.P_DEP_NAME:
- case PduPart.P_NAME:
- byte[] name = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- if ((null != name) && (null != map)) {
- map.put(PduPart.P_NAME, name);
- }
-
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
- break;
- default:
- if (LOCAL_LOGV) {
- Log.v(LOG_TAG, "Not supported Content-Type parameter");
- }
- if (-1 == skipWapValue(pduDataStream, lastLen)) {
- Log.e(LOG_TAG, "Corrupt Content-Type");
- } else {
- lastLen = 0;
- }
- break;
- }
- }
-
- if (0 != lastLen) {
- Log.e(LOG_TAG, "Corrupt Content-Type");
- }
- }
-
- /**
- * Parse content type.
- *
- * @param pduDataStream pdu data input stream
- * @param map to store parameters in Content-Type header field
- * @return Content-Type value
- */
- protected static byte[] parseContentType(ByteArrayInputStream pduDataStream,
- HashMap<Integer, Object> map) {
- /**
- * From wap-230-wsp-20010705-a.pdf
- * Content-type-value = Constrained-media | Content-general-form
- * Content-general-form = Value-length Media-type
- * Media-type = (Well-known-media | Extension-Media) *(Parameter)
- */
- assert(null != pduDataStream);
-
- byte[] contentType = null;
- pduDataStream.mark(1);
- int temp = pduDataStream.read();
- assert(-1 != temp);
- pduDataStream.reset();
-
- int cur = (temp & 0xFF);
-
- if (cur < TEXT_MIN) {
- int length = parseValueLength(pduDataStream);
- int startPos = pduDataStream.available();
- pduDataStream.mark(1);
- temp = pduDataStream.read();
- assert(-1 != temp);
- pduDataStream.reset();
- int first = (temp & 0xFF);
-
- if ((first >= TEXT_MIN) && (first <= TEXT_MAX)) {
- contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- } else if (first > TEXT_MAX) {
- int index = parseShortInteger(pduDataStream);
-
- if (index < PduContentTypes.contentTypes.length) { //well-known type
- contentType = (PduContentTypes.contentTypes[index]).getBytes();
- } else {
- pduDataStream.reset();
- contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- }
- } else {
- Log.e(LOG_TAG, "Corrupt content-type");
- return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*"
- }
-
- int endPos = pduDataStream.available();
- int parameterLen = length - (startPos - endPos);
- if (parameterLen > 0) {//have parameters
- parseContentTypeParams(pduDataStream, map, parameterLen);
- }
-
- if (parameterLen < 0) {
- Log.e(LOG_TAG, "Corrupt MMS message");
- return (PduContentTypes.contentTypes[0]).getBytes(); //"*/*"
- }
- } else if (cur <= TEXT_MAX) {
- contentType = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- } else {
- contentType =
- (PduContentTypes.contentTypes[parseShortInteger(pduDataStream)]).getBytes();
- }
-
- return contentType;
- }
-
- /**
- * Parse part's headers.
- *
- * @param pduDataStream pdu data input stream
- * @param part to store the header informations of the part
- * @param length length of the headers
- * @return true if parse successfully, false otherwise
- */
- protected static boolean parsePartHeaders(ByteArrayInputStream pduDataStream,
- PduPart part, int length) {
- assert(null != pduDataStream);
- assert(null != part);
- assert(length > 0);
-
- /**
- * From oma-ts-mms-conf-v1_3.pdf, chapter 10.2.
- * A name for multipart object SHALL be encoded using name-parameter
- * for Content-Type header in WSP multipart headers.
- * In decoding, name-parameter of Content-Type SHALL be used if available.
- * If name-parameter of Content-Type is not available,
- * filename parameter of Content-Disposition header SHALL be used if available.
- * If neither name-parameter of Content-Type header nor filename parameter
- * of Content-Disposition header is available,
- * Content-Location header SHALL be used if available.
- *
- * Within SMIL part the reference to the media object parts SHALL use
- * either Content-ID or Content-Location mechanism [RFC2557]
- * and the corresponding WSP part headers in media object parts
- * contain the corresponding definitions.
- */
- int startPos = pduDataStream.available();
- int tempPos = 0;
- int lastLen = length;
- while(0 < lastLen) {
- int header = pduDataStream.read();
- assert(-1 != header);
- lastLen--;
-
- if (header > TEXT_MAX) {
- // Number assigned headers.
- switch (header) {
- case PduPart.P_CONTENT_LOCATION:
- /**
- * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
- * Content-location-value = Uri-value
- */
- byte[] contentLocation = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- if (null != contentLocation) {
- part.setContentLocation(contentLocation);
- }
-
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
- break;
- case PduPart.P_CONTENT_ID:
- /**
- * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
- * Content-ID-value = Quoted-string
- */
- byte[] contentId = parseWapString(pduDataStream, TYPE_QUOTED_STRING);
- if (null != contentId) {
- part.setContentId(contentId);
- }
-
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
- break;
- case PduPart.P_DEP_CONTENT_DISPOSITION:
- case PduPart.P_CONTENT_DISPOSITION:
- /**
- * From wap-230-wsp-20010705-a.pdf, chapter 8.4.2.21
- * Content-disposition-value = Value-length Disposition *(Parameter)
- * Disposition = Form-data | Attachment | Inline | Token-text
- * Form-data = <Octet 128>
- * Attachment = <Octet 129>
- * Inline = <Octet 130>
- */
-
- /*
- * some carrier mmsc servers do not support content_disposition
- * field correctly
- */
- boolean contentDisposition = Resources.getSystem().getBoolean(com
- .android.internal.R.bool.config_mms_content_disposition_support);
-
- if (contentDisposition) {
- int len = parseValueLength(pduDataStream);
- pduDataStream.mark(1);
- int thisStartPos = pduDataStream.available();
- int thisEndPos = 0;
- int value = pduDataStream.read();
-
- if (value == PduPart.P_DISPOSITION_FROM_DATA ) {
- part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA);
- } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) {
- part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT);
- } else if (value == PduPart.P_DISPOSITION_INLINE) {
- part.setContentDisposition(PduPart.DISPOSITION_INLINE);
- } else {
- pduDataStream.reset();
- /* Token-text */
- part.setContentDisposition(parseWapString(pduDataStream
- , TYPE_TEXT_STRING));
- }
-
- /* get filename parameter and skip other parameters */
- thisEndPos = pduDataStream.available();
- if (thisStartPos - thisEndPos < len) {
- value = pduDataStream.read();
- if (value == PduPart.P_FILENAME) { //filename is text-string
- part.setFilename(parseWapString(pduDataStream
- , TYPE_TEXT_STRING));
- }
-
- /* skip other parameters */
- thisEndPos = pduDataStream.available();
- if (thisStartPos - thisEndPos < len) {
- int last = len - (thisStartPos - thisEndPos);
- byte[] temp = new byte[last];
- pduDataStream.read(temp, 0, last);
- }
- }
-
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
- }
- break;
- default:
- if (LOCAL_LOGV) {
- Log.v(LOG_TAG, "Not supported Part headers: " + header);
- }
- if (-1 == skipWapValue(pduDataStream, lastLen)) {
- Log.e(LOG_TAG, "Corrupt Part headers");
- return false;
- }
- lastLen = 0;
- break;
- }
- } else if ((header >= TEXT_MIN) && (header <= TEXT_MAX)) {
- // Not assigned header.
- byte[] tempHeader = parseWapString(pduDataStream, TYPE_TEXT_STRING);
- byte[] tempValue = parseWapString(pduDataStream, TYPE_TEXT_STRING);
-
- // Check the header whether it is "Content-Transfer-Encoding".
- if (true ==
- PduPart.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(new String(tempHeader))) {
- part.setContentTransferEncoding(tempValue);
- }
-
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
- } else {
- if (LOCAL_LOGV) {
- Log.v(LOG_TAG, "Not supported Part headers: " + header);
- }
- // Skip all headers of this part.
- if (-1 == skipWapValue(pduDataStream, lastLen)) {
- Log.e(LOG_TAG, "Corrupt Part headers");
- return false;
- }
- lastLen = 0;
- }
- }
-
- if (0 != lastLen) {
- Log.e(LOG_TAG, "Corrupt Part headers");
- return false;
- }
-
- return true;
- }
-
- /**
- * Check the position of a specified part.
- *
- * @param part the part to be checked
- * @return part position, THE_FIRST_PART when it's the
- * first one, THE_LAST_PART when it's the last one.
- */
- private static int checkPartPosition(PduPart part) {
- assert(null != part);
- if ((null == mTypeParam) &&
- (null == mStartParam)) {
- return THE_LAST_PART;
- }
-
- /* check part's content-id */
- if (null != mStartParam) {
- byte[] contentId = part.getContentId();
- if (null != contentId) {
- if (true == Arrays.equals(mStartParam, contentId)) {
- return THE_FIRST_PART;
- }
- }
- }
-
- /* check part's content-type */
- if (null != mTypeParam) {
- byte[] contentType = part.getContentType();
- if (null != contentType) {
- if (true == Arrays.equals(mTypeParam, contentType)) {
- return THE_FIRST_PART;
- }
- }
- }
-
- return THE_LAST_PART;
- }
-
- /**
- * Check mandatory headers of a pdu.
- *
- * @param headers pdu headers
- * @return true if the pdu has all of the mandatory headers, false otherwise.
- */
- protected static boolean checkMandatoryHeader(PduHeaders headers) {
- if (null == headers) {
- return false;
- }
-
- /* get message type */
- int messageType = headers.getOctet(PduHeaders.MESSAGE_TYPE);
-
- /* check Mms-Version field */
- int mmsVersion = headers.getOctet(PduHeaders.MMS_VERSION);
- if (0 == mmsVersion) {
- // Every message should have Mms-Version field.
- return false;
- }
-
- /* check mandatory header fields */
- switch (messageType) {
- case PduHeaders.MESSAGE_TYPE_SEND_REQ:
- // Content-Type field.
- byte[] srContentType = headers.getTextString(PduHeaders.CONTENT_TYPE);
- if (null == srContentType) {
- return false;
- }
-
- // From field.
- EncodedStringValue srFrom = headers.getEncodedStringValue(PduHeaders.FROM);
- if (null == srFrom) {
- return false;
- }
-
- // Transaction-Id field.
- byte[] srTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
- if (null == srTransactionId) {
- return false;
- }
-
- break;
- case PduHeaders.MESSAGE_TYPE_SEND_CONF:
- // Response-Status field.
- int scResponseStatus = headers.getOctet(PduHeaders.RESPONSE_STATUS);
- if (0 == scResponseStatus) {
- return false;
- }
-
- // Transaction-Id field.
- byte[] scTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
- if (null == scTransactionId) {
- return false;
- }
-
- break;
- case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
- // Content-Location field.
- byte[] niContentLocation = headers.getTextString(PduHeaders.CONTENT_LOCATION);
- if (null == niContentLocation) {
- return false;
- }
-
- // Expiry field.
- long niExpiry = headers.getLongInteger(PduHeaders.EXPIRY);
- if (-1 == niExpiry) {
- return false;
- }
-
- // Message-Class field.
- byte[] niMessageClass = headers.getTextString(PduHeaders.MESSAGE_CLASS);
- if (null == niMessageClass) {
- return false;
- }
-
- // Message-Size field.
- long niMessageSize = headers.getLongInteger(PduHeaders.MESSAGE_SIZE);
- if (-1 == niMessageSize) {
- return false;
- }
-
- // Transaction-Id field.
- byte[] niTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
- if (null == niTransactionId) {
- return false;
- }
-
- break;
- case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
- // Status field.
- int nriStatus = headers.getOctet(PduHeaders.STATUS);
- if (0 == nriStatus) {
- return false;
- }
-
- // Transaction-Id field.
- byte[] nriTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
- if (null == nriTransactionId) {
- return false;
- }
-
- break;
- case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
- // Content-Type field.
- byte[] rcContentType = headers.getTextString(PduHeaders.CONTENT_TYPE);
- if (null == rcContentType) {
- return false;
- }
-
- // Date field.
- long rcDate = headers.getLongInteger(PduHeaders.DATE);
- if (-1 == rcDate) {
- return false;
- }
-
- break;
- case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
- // Date field.
- long diDate = headers.getLongInteger(PduHeaders.DATE);
- if (-1 == diDate) {
- return false;
- }
-
- // Message-Id field.
- byte[] diMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
- if (null == diMessageId) {
- return false;
- }
-
- // Status field.
- int diStatus = headers.getOctet(PduHeaders.STATUS);
- if (0 == diStatus) {
- return false;
- }
-
- // To field.
- EncodedStringValue[] diTo = headers.getEncodedStringValues(PduHeaders.TO);
- if (null == diTo) {
- return false;
- }
-
- break;
- case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
- // Transaction-Id field.
- byte[] aiTransactionId = headers.getTextString(PduHeaders.TRANSACTION_ID);
- if (null == aiTransactionId) {
- return false;
- }
-
- break;
- case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
- // Date field.
- long roDate = headers.getLongInteger(PduHeaders.DATE);
- if (-1 == roDate) {
- return false;
- }
-
- // From field.
- EncodedStringValue roFrom = headers.getEncodedStringValue(PduHeaders.FROM);
- if (null == roFrom) {
- return false;
- }
-
- // Message-Id field.
- byte[] roMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
- if (null == roMessageId) {
- return false;
- }
-
- // Read-Status field.
- int roReadStatus = headers.getOctet(PduHeaders.READ_STATUS);
- if (0 == roReadStatus) {
- return false;
- }
-
- // To field.
- EncodedStringValue[] roTo = headers.getEncodedStringValues(PduHeaders.TO);
- if (null == roTo) {
- return false;
- }
-
- break;
- case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
- // From field.
- EncodedStringValue rrFrom = headers.getEncodedStringValue(PduHeaders.FROM);
- if (null == rrFrom) {
- return false;
- }
-
- // Message-Id field.
- byte[] rrMessageId = headers.getTextString(PduHeaders.MESSAGE_ID);
- if (null == rrMessageId) {
- return false;
- }
-
- // Read-Status field.
- int rrReadStatus = headers.getOctet(PduHeaders.READ_STATUS);
- if (0 == rrReadStatus) {
- return false;
- }
-
- // To field.
- EncodedStringValue[] rrTo = headers.getEncodedStringValues(PduHeaders.TO);
- if (null == rrTo) {
- return false;
- }
-
- break;
- default:
- // Parser doesn't support this message type in this version.
- return false;
- }
-
- return true;
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/PduPart.java b/core/java/com/google/android/mms/pdu/PduPart.java
deleted file mode 100644
index b43e388..0000000
--- a/core/java/com/google/android/mms/pdu/PduPart.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import android.net.Uri;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The pdu part.
- */
-public class PduPart {
- /**
- * Well-Known Parameters.
- */
- public static final int P_Q = 0x80;
- public static final int P_CHARSET = 0x81;
- public static final int P_LEVEL = 0x82;
- public static final int P_TYPE = 0x83;
- public static final int P_DEP_NAME = 0x85;
- public static final int P_DEP_FILENAME = 0x86;
- public static final int P_DIFFERENCES = 0x87;
- public static final int P_PADDING = 0x88;
- // This value of "TYPE" s used with Content-Type: multipart/related
- public static final int P_CT_MR_TYPE = 0x89;
- public static final int P_DEP_START = 0x8A;
- public static final int P_DEP_START_INFO = 0x8B;
- public static final int P_DEP_COMMENT = 0x8C;
- public static final int P_DEP_DOMAIN = 0x8D;
- public static final int P_MAX_AGE = 0x8E;
- public static final int P_DEP_PATH = 0x8F;
- public static final int P_SECURE = 0x90;
- public static final int P_SEC = 0x91;
- public static final int P_MAC = 0x92;
- public static final int P_CREATION_DATE = 0x93;
- public static final int P_MODIFICATION_DATE = 0x94;
- public static final int P_READ_DATE = 0x95;
- public static final int P_SIZE = 0x96;
- public static final int P_NAME = 0x97;
- public static final int P_FILENAME = 0x98;
- public static final int P_START = 0x99;
- public static final int P_START_INFO = 0x9A;
- public static final int P_COMMENT = 0x9B;
- public static final int P_DOMAIN = 0x9C;
- public static final int P_PATH = 0x9D;
-
- /**
- * Header field names.
- */
- public static final int P_CONTENT_TYPE = 0x91;
- public static final int P_CONTENT_LOCATION = 0x8E;
- public static final int P_CONTENT_ID = 0xC0;
- public static final int P_DEP_CONTENT_DISPOSITION = 0xAE;
- public static final int P_CONTENT_DISPOSITION = 0xC5;
- // The next header is unassigned header, use reserved header(0x48) value.
- public static final int P_CONTENT_TRANSFER_ENCODING = 0xC8;
-
- /**
- * Content=Transfer-Encoding string.
- */
- public static final String CONTENT_TRANSFER_ENCODING =
- "Content-Transfer-Encoding";
-
- /**
- * Value of Content-Transfer-Encoding.
- */
- public static final String P_BINARY = "binary";
- public static final String P_7BIT = "7bit";
- public static final String P_8BIT = "8bit";
- public static final String P_BASE64 = "base64";
- public static final String P_QUOTED_PRINTABLE = "quoted-printable";
-
- /**
- * Value of disposition can be set to PduPart when the value is octet in
- * the PDU.
- * "from-data" instead of Form-data<Octet 128>.
- * "attachment" instead of Attachment<Octet 129>.
- * "inline" instead of Inline<Octet 130>.
- */
- static final byte[] DISPOSITION_FROM_DATA = "from-data".getBytes();
- static final byte[] DISPOSITION_ATTACHMENT = "attachment".getBytes();
- static final byte[] DISPOSITION_INLINE = "inline".getBytes();
-
- /**
- * Content-Disposition value.
- */
- public static final int P_DISPOSITION_FROM_DATA = 0x80;
- public static final int P_DISPOSITION_ATTACHMENT = 0x81;
- public static final int P_DISPOSITION_INLINE = 0x82;
-
- /**
- * Header of part.
- */
- private Map<Integer, Object> mPartHeader = null;
-
- /**
- * Data uri.
- */
- private Uri mUri = null;
-
- /**
- * Part data.
- */
- private byte[] mPartData = null;
-
- private static final String TAG = "PduPart";
-
- /**
- * Empty Constructor.
- */
- public PduPart() {
- mPartHeader = new HashMap<Integer, Object>();
- }
-
- /**
- * Set part data. The data are stored as byte array.
- *
- * @param data the data
- */
- public void setData(byte[] data) {
- if(data == null) {
- return;
- }
-
- mPartData = new byte[data.length];
- System.arraycopy(data, 0, mPartData, 0, data.length);
- }
-
- /**
- * @return A copy of the part data or null if the data wasn't set or
- * the data is stored as Uri.
- * @see #getDataUri
- */
- public byte[] getData() {
- if(mPartData == null) {
- return null;
- }
-
- byte[] byteArray = new byte[mPartData.length];
- System.arraycopy(mPartData, 0, byteArray, 0, mPartData.length);
- return byteArray;
- }
-
- /**
- * Set data uri. The data are stored as Uri.
- *
- * @param uri the uri
- */
- public void setDataUri(Uri uri) {
- mUri = uri;
- }
-
- /**
- * @return The Uri of the part data or null if the data wasn't set or
- * the data is stored as byte array.
- * @see #getData
- */
- public Uri getDataUri() {
- return mUri;
- }
-
- /**
- * Set Content-id value
- *
- * @param contentId the content-id value
- * @throws NullPointerException if the value is null.
- */
- public void setContentId(byte[] contentId) {
- if((contentId == null) || (contentId.length == 0)) {
- throw new IllegalArgumentException(
- "Content-Id may not be null or empty.");
- }
-
- if ((contentId.length > 1)
- && ((char) contentId[0] == '<')
- && ((char) contentId[contentId.length - 1] == '>')) {
- mPartHeader.put(P_CONTENT_ID, contentId);
- return;
- }
-
- // Insert beginning '<' and trailing '>' for Content-Id.
- byte[] buffer = new byte[contentId.length + 2];
- buffer[0] = (byte) (0xff & '<');
- buffer[buffer.length - 1] = (byte) (0xff & '>');
- System.arraycopy(contentId, 0, buffer, 1, contentId.length);
- mPartHeader.put(P_CONTENT_ID, buffer);
- }
-
- /**
- * Get Content-id value.
- *
- * @return the value
- */
- public byte[] getContentId() {
- return (byte[]) mPartHeader.get(P_CONTENT_ID);
- }
-
- /**
- * Set Char-set value.
- *
- * @param charset the value
- */
- public void setCharset(int charset) {
- mPartHeader.put(P_CHARSET, charset);
- }
-
- /**
- * Get Char-set value
- *
- * @return the charset value. Return 0 if charset was not set.
- */
- public int getCharset() {
- Integer charset = (Integer) mPartHeader.get(P_CHARSET);
- if(charset == null) {
- return 0;
- } else {
- return charset.intValue();
- }
- }
-
- /**
- * Set Content-Location value.
- *
- * @param contentLocation the value
- * @throws NullPointerException if the value is null.
- */
- public void setContentLocation(byte[] contentLocation) {
- if(contentLocation == null) {
- throw new NullPointerException("null content-location");
- }
-
- mPartHeader.put(P_CONTENT_LOCATION, contentLocation);
- }
-
- /**
- * Get Content-Location value.
- *
- * @return the value
- * return PduPart.disposition[0] instead of <Octet 128> (Form-data).
- * return PduPart.disposition[1] instead of <Octet 129> (Attachment).
- * return PduPart.disposition[2] instead of <Octet 130> (Inline).
- */
- public byte[] getContentLocation() {
- return (byte[]) mPartHeader.get(P_CONTENT_LOCATION);
- }
-
- /**
- * Set Content-Disposition value.
- * Use PduPart.disposition[0] instead of <Octet 128> (Form-data).
- * Use PduPart.disposition[1] instead of <Octet 129> (Attachment).
- * Use PduPart.disposition[2] instead of <Octet 130> (Inline).
- *
- * @param contentDisposition the value
- * @throws NullPointerException if the value is null.
- */
- public void setContentDisposition(byte[] contentDisposition) {
- if(contentDisposition == null) {
- throw new NullPointerException("null content-disposition");
- }
-
- mPartHeader.put(P_CONTENT_DISPOSITION, contentDisposition);
- }
-
- /**
- * Get Content-Disposition value.
- *
- * @return the value
- */
- public byte[] getContentDisposition() {
- return (byte[]) mPartHeader.get(P_CONTENT_DISPOSITION);
- }
-
- /**
- * Set Content-Type value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setContentType(byte[] contentType) {
- if(contentType == null) {
- throw new NullPointerException("null content-type");
- }
-
- mPartHeader.put(P_CONTENT_TYPE, contentType);
- }
-
- /**
- * Get Content-Type value of part.
- *
- * @return the value
- */
- public byte[] getContentType() {
- return (byte[]) mPartHeader.get(P_CONTENT_TYPE);
- }
-
- /**
- * Set Content-Transfer-Encoding value
- *
- * @param contentId the content-id value
- * @throws NullPointerException if the value is null.
- */
- public void setContentTransferEncoding(byte[] contentTransferEncoding) {
- if(contentTransferEncoding == null) {
- throw new NullPointerException("null content-transfer-encoding");
- }
-
- mPartHeader.put(P_CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
- }
-
- /**
- * Get Content-Transfer-Encoding value.
- *
- * @return the value
- */
- public byte[] getContentTransferEncoding() {
- return (byte[]) mPartHeader.get(P_CONTENT_TRANSFER_ENCODING);
- }
-
- /**
- * Set Content-type parameter: name.
- *
- * @param name the name value
- * @throws NullPointerException if the value is null.
- */
- public void setName(byte[] name) {
- if(null == name) {
- throw new NullPointerException("null content-id");
- }
-
- mPartHeader.put(P_NAME, name);
- }
-
- /**
- * Get content-type parameter: name.
- *
- * @return the name
- */
- public byte[] getName() {
- return (byte[]) mPartHeader.get(P_NAME);
- }
-
- /**
- * Get Content-disposition parameter: filename
- *
- * @param fileName the filename value
- * @throws NullPointerException if the value is null.
- */
- public void setFilename(byte[] fileName) {
- if(null == fileName) {
- throw new NullPointerException("null content-id");
- }
-
- mPartHeader.put(P_FILENAME, fileName);
- }
-
- /**
- * Set Content-disposition parameter: filename
- *
- * @return the filename
- */
- public byte[] getFilename() {
- return (byte[]) mPartHeader.get(P_FILENAME);
- }
-
- public String generateLocation() {
- // Assumption: At least one of the content-location / name / filename
- // or content-id should be set. This is guaranteed by the PduParser
- // for incoming messages and by MM composer for outgoing messages.
- byte[] location = (byte[]) mPartHeader.get(P_NAME);
- if(null == location) {
- location = (byte[]) mPartHeader.get(P_FILENAME);
-
- if (null == location) {
- location = (byte[]) mPartHeader.get(P_CONTENT_LOCATION);
- }
- }
-
- if (null == location) {
- byte[] contentId = (byte[]) mPartHeader.get(P_CONTENT_ID);
- return "cid:" + new String(contentId);
- } else {
- return new String(location);
- }
- }
-}
-
diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
deleted file mode 100644
index ee285aa..0000000
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ /dev/null
@@ -1,1477 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.ContentType;
-import com.google.android.mms.InvalidHeaderValueException;
-import com.google.android.mms.MmsException;
-import com.google.android.mms.util.DownloadDrmHelper;
-import com.google.android.mms.util.DrmConvertSession;
-import com.google.android.mms.util.PduCache;
-import com.google.android.mms.util.PduCacheEntry;
-import com.google.android.mms.util.SqliteWrapper;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteException;
-import android.drm.DrmManagerClient;
-import android.net.Uri;
-import android.os.FileUtils;
-import android.provider.MediaStore;
-import android.provider.Telephony;
-import android.provider.Telephony.Mms;
-import android.provider.Telephony.MmsSms;
-import android.provider.Telephony.Threads;
-import android.provider.Telephony.Mms.Addr;
-import android.provider.Telephony.Mms.Part;
-import android.provider.Telephony.MmsSms.PendingMessages;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import com.google.android.mms.pdu.EncodedStringValue;
-
-/**
- * This class is the high-level manager of PDU storage.
- */
-public class PduPersister {
- private static final String TAG = "PduPersister";
- private static final boolean DEBUG = false;
- private static final boolean LOCAL_LOGV = false;
-
- private static final long DUMMY_THREAD_ID = Long.MAX_VALUE;
-
- /**
- * The uri of temporary drm objects.
- */
- public static final String TEMPORARY_DRM_OBJECT_URI =
- "content://mms/" + Long.MAX_VALUE + "/part";
- /**
- * Indicate that we transiently failed to process a MM.
- */
- public static final int PROC_STATUS_TRANSIENT_FAILURE = 1;
- /**
- * Indicate that we permanently failed to process a MM.
- */
- public static final int PROC_STATUS_PERMANENTLY_FAILURE = 2;
- /**
- * Indicate that we have successfully processed a MM.
- */
- public static final int PROC_STATUS_COMPLETED = 3;
-
- private static PduPersister sPersister;
- private static final PduCache PDU_CACHE_INSTANCE;
-
- private static final int[] ADDRESS_FIELDS = new int[] {
- PduHeaders.BCC,
- PduHeaders.CC,
- PduHeaders.FROM,
- PduHeaders.TO
- };
-
- private static final String[] PDU_PROJECTION = new String[] {
- Mms._ID,
- Mms.MESSAGE_BOX,
- Mms.THREAD_ID,
- Mms.RETRIEVE_TEXT,
- Mms.SUBJECT,
- Mms.CONTENT_LOCATION,
- Mms.CONTENT_TYPE,
- Mms.MESSAGE_CLASS,
- Mms.MESSAGE_ID,
- Mms.RESPONSE_TEXT,
- Mms.TRANSACTION_ID,
- Mms.CONTENT_CLASS,
- Mms.DELIVERY_REPORT,
- Mms.MESSAGE_TYPE,
- Mms.MMS_VERSION,
- Mms.PRIORITY,
- Mms.READ_REPORT,
- Mms.READ_STATUS,
- Mms.REPORT_ALLOWED,
- Mms.RETRIEVE_STATUS,
- Mms.STATUS,
- Mms.DATE,
- Mms.DELIVERY_TIME,
- Mms.EXPIRY,
- Mms.MESSAGE_SIZE,
- Mms.SUBJECT_CHARSET,
- Mms.RETRIEVE_TEXT_CHARSET,
- };
-
- private static final int PDU_COLUMN_ID = 0;
- private static final int PDU_COLUMN_MESSAGE_BOX = 1;
- private static final int PDU_COLUMN_THREAD_ID = 2;
- private static final int PDU_COLUMN_RETRIEVE_TEXT = 3;
- private static final int PDU_COLUMN_SUBJECT = 4;
- private static final int PDU_COLUMN_CONTENT_LOCATION = 5;
- private static final int PDU_COLUMN_CONTENT_TYPE = 6;
- private static final int PDU_COLUMN_MESSAGE_CLASS = 7;
- private static final int PDU_COLUMN_MESSAGE_ID = 8;
- private static final int PDU_COLUMN_RESPONSE_TEXT = 9;
- private static final int PDU_COLUMN_TRANSACTION_ID = 10;
- private static final int PDU_COLUMN_CONTENT_CLASS = 11;
- private static final int PDU_COLUMN_DELIVERY_REPORT = 12;
- private static final int PDU_COLUMN_MESSAGE_TYPE = 13;
- private static final int PDU_COLUMN_MMS_VERSION = 14;
- private static final int PDU_COLUMN_PRIORITY = 15;
- private static final int PDU_COLUMN_READ_REPORT = 16;
- private static final int PDU_COLUMN_READ_STATUS = 17;
- private static final int PDU_COLUMN_REPORT_ALLOWED = 18;
- private static final int PDU_COLUMN_RETRIEVE_STATUS = 19;
- private static final int PDU_COLUMN_STATUS = 20;
- private static final int PDU_COLUMN_DATE = 21;
- private static final int PDU_COLUMN_DELIVERY_TIME = 22;
- private static final int PDU_COLUMN_EXPIRY = 23;
- private static final int PDU_COLUMN_MESSAGE_SIZE = 24;
- private static final int PDU_COLUMN_SUBJECT_CHARSET = 25;
- private static final int PDU_COLUMN_RETRIEVE_TEXT_CHARSET = 26;
-
- private static final String[] PART_PROJECTION = new String[] {
- Part._ID,
- Part.CHARSET,
- Part.CONTENT_DISPOSITION,
- Part.CONTENT_ID,
- Part.CONTENT_LOCATION,
- Part.CONTENT_TYPE,
- Part.FILENAME,
- Part.NAME,
- Part.TEXT
- };
-
- private static final int PART_COLUMN_ID = 0;
- private static final int PART_COLUMN_CHARSET = 1;
- private static final int PART_COLUMN_CONTENT_DISPOSITION = 2;
- private static final int PART_COLUMN_CONTENT_ID = 3;
- private static final int PART_COLUMN_CONTENT_LOCATION = 4;
- private static final int PART_COLUMN_CONTENT_TYPE = 5;
- private static final int PART_COLUMN_FILENAME = 6;
- private static final int PART_COLUMN_NAME = 7;
- private static final int PART_COLUMN_TEXT = 8;
-
- private static final HashMap<Uri, Integer> MESSAGE_BOX_MAP;
- // These map are used for convenience in persist() and load().
- private static final HashMap<Integer, Integer> CHARSET_COLUMN_INDEX_MAP;
- private static final HashMap<Integer, Integer> ENCODED_STRING_COLUMN_INDEX_MAP;
- private static final HashMap<Integer, Integer> TEXT_STRING_COLUMN_INDEX_MAP;
- private static final HashMap<Integer, Integer> OCTET_COLUMN_INDEX_MAP;
- private static final HashMap<Integer, Integer> LONG_COLUMN_INDEX_MAP;
- private static final HashMap<Integer, String> CHARSET_COLUMN_NAME_MAP;
- private static final HashMap<Integer, String> ENCODED_STRING_COLUMN_NAME_MAP;
- private static final HashMap<Integer, String> TEXT_STRING_COLUMN_NAME_MAP;
- private static final HashMap<Integer, String> OCTET_COLUMN_NAME_MAP;
- private static final HashMap<Integer, String> LONG_COLUMN_NAME_MAP;
-
- static {
- MESSAGE_BOX_MAP = new HashMap<Uri, Integer>();
- MESSAGE_BOX_MAP.put(Mms.Inbox.CONTENT_URI, Mms.MESSAGE_BOX_INBOX);
- MESSAGE_BOX_MAP.put(Mms.Sent.CONTENT_URI, Mms.MESSAGE_BOX_SENT);
- MESSAGE_BOX_MAP.put(Mms.Draft.CONTENT_URI, Mms.MESSAGE_BOX_DRAFTS);
- MESSAGE_BOX_MAP.put(Mms.Outbox.CONTENT_URI, Mms.MESSAGE_BOX_OUTBOX);
-
- CHARSET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
- CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT_CHARSET);
- CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT_CHARSET);
-
- CHARSET_COLUMN_NAME_MAP = new HashMap<Integer, String>();
- CHARSET_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT_CHARSET);
- CHARSET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT_CHARSET);
-
- // Encoded string field code -> column index/name map.
- ENCODED_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
- ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT);
- ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT);
-
- ENCODED_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>();
- ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT);
- ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT);
-
- // Text string field code -> column index/name map.
- TEXT_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
- TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_LOCATION, PDU_COLUMN_CONTENT_LOCATION);
- TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_TYPE, PDU_COLUMN_CONTENT_TYPE);
- TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_CLASS, PDU_COLUMN_MESSAGE_CLASS);
- TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_ID, PDU_COLUMN_MESSAGE_ID);
- TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RESPONSE_TEXT, PDU_COLUMN_RESPONSE_TEXT);
- TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.TRANSACTION_ID, PDU_COLUMN_TRANSACTION_ID);
-
- TEXT_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>();
- TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_LOCATION, Mms.CONTENT_LOCATION);
- TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_TYPE, Mms.CONTENT_TYPE);
- TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_CLASS, Mms.MESSAGE_CLASS);
- TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_ID, Mms.MESSAGE_ID);
- TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.RESPONSE_TEXT, Mms.RESPONSE_TEXT);
- TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.TRANSACTION_ID, Mms.TRANSACTION_ID);
-
- // Octet field code -> column index/name map.
- OCTET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_CLASS, PDU_COLUMN_CONTENT_CLASS);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_REPORT, PDU_COLUMN_DELIVERY_REPORT);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_TYPE, PDU_COLUMN_MESSAGE_TYPE);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MMS_VERSION, PDU_COLUMN_MMS_VERSION);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.PRIORITY, PDU_COLUMN_PRIORITY);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_REPORT, PDU_COLUMN_READ_REPORT);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_STATUS, PDU_COLUMN_READ_STATUS);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.REPORT_ALLOWED, PDU_COLUMN_REPORT_ALLOWED);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_STATUS, PDU_COLUMN_RETRIEVE_STATUS);
- OCTET_COLUMN_INDEX_MAP.put(PduHeaders.STATUS, PDU_COLUMN_STATUS);
-
- OCTET_COLUMN_NAME_MAP = new HashMap<Integer, String>();
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_CLASS, Mms.CONTENT_CLASS);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_REPORT, Mms.DELIVERY_REPORT);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_TYPE, Mms.MESSAGE_TYPE);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.MMS_VERSION, Mms.MMS_VERSION);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.PRIORITY, Mms.PRIORITY);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_REPORT, Mms.READ_REPORT);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_STATUS, Mms.READ_STATUS);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.REPORT_ALLOWED, Mms.REPORT_ALLOWED);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_STATUS, Mms.RETRIEVE_STATUS);
- OCTET_COLUMN_NAME_MAP.put(PduHeaders.STATUS, Mms.STATUS);
-
- // Long field code -> column index/name map.
- LONG_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>();
- LONG_COLUMN_INDEX_MAP.put(PduHeaders.DATE, PDU_COLUMN_DATE);
- LONG_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_TIME, PDU_COLUMN_DELIVERY_TIME);
- LONG_COLUMN_INDEX_MAP.put(PduHeaders.EXPIRY, PDU_COLUMN_EXPIRY);
- LONG_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_SIZE, PDU_COLUMN_MESSAGE_SIZE);
-
- LONG_COLUMN_NAME_MAP = new HashMap<Integer, String>();
- LONG_COLUMN_NAME_MAP.put(PduHeaders.DATE, Mms.DATE);
- LONG_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_TIME, Mms.DELIVERY_TIME);
- LONG_COLUMN_NAME_MAP.put(PduHeaders.EXPIRY, Mms.EXPIRY);
- LONG_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_SIZE, Mms.MESSAGE_SIZE);
-
- PDU_CACHE_INSTANCE = PduCache.getInstance();
- }
-
- private final Context mContext;
- private final ContentResolver mContentResolver;
- private final DrmManagerClient mDrmManagerClient;
-
- private PduPersister(Context context) {
- mContext = context;
- mContentResolver = context.getContentResolver();
- mDrmManagerClient = new DrmManagerClient(context);
- }
-
- /** Get(or create if not exist) an instance of PduPersister */
- public static PduPersister getPduPersister(Context context) {
- if ((sPersister == null) || !context.equals(sPersister.mContext)) {
- sPersister = new PduPersister(context);
- }
-
- return sPersister;
- }
-
- private void setEncodedStringValueToHeaders(
- Cursor c, int columnIndex,
- PduHeaders headers, int mapColumn) {
- String s = c.getString(columnIndex);
- if ((s != null) && (s.length() > 0)) {
- int charsetColumnIndex = CHARSET_COLUMN_INDEX_MAP.get(mapColumn);
- int charset = c.getInt(charsetColumnIndex);
- EncodedStringValue value = new EncodedStringValue(
- charset, getBytes(s));
- headers.setEncodedStringValue(value, mapColumn);
- }
- }
-
- private void setTextStringToHeaders(
- Cursor c, int columnIndex,
- PduHeaders headers, int mapColumn) {
- String s = c.getString(columnIndex);
- if (s != null) {
- headers.setTextString(getBytes(s), mapColumn);
- }
- }
-
- private void setOctetToHeaders(
- Cursor c, int columnIndex,
- PduHeaders headers, int mapColumn) throws InvalidHeaderValueException {
- if (!c.isNull(columnIndex)) {
- int b = c.getInt(columnIndex);
- headers.setOctet(b, mapColumn);
- }
- }
-
- private void setLongToHeaders(
- Cursor c, int columnIndex,
- PduHeaders headers, int mapColumn) {
- if (!c.isNull(columnIndex)) {
- long l = c.getLong(columnIndex);
- headers.setLongInteger(l, mapColumn);
- }
- }
-
- private Integer getIntegerFromPartColumn(Cursor c, int columnIndex) {
- if (!c.isNull(columnIndex)) {
- return c.getInt(columnIndex);
- }
- return null;
- }
-
- private byte[] getByteArrayFromPartColumn(Cursor c, int columnIndex) {
- if (!c.isNull(columnIndex)) {
- return getBytes(c.getString(columnIndex));
- }
- return null;
- }
-
- private PduPart[] loadParts(long msgId) throws MmsException {
- Cursor c = SqliteWrapper.query(mContext, mContentResolver,
- Uri.parse("content://mms/" + msgId + "/part"),
- PART_PROJECTION, null, null, null);
-
- PduPart[] parts = null;
-
- try {
- if ((c == null) || (c.getCount() == 0)) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "loadParts(" + msgId + "): no part to load.");
- }
- return null;
- }
-
- int partCount = c.getCount();
- int partIdx = 0;
- parts = new PduPart[partCount];
- while (c.moveToNext()) {
- PduPart part = new PduPart();
- Integer charset = getIntegerFromPartColumn(
- c, PART_COLUMN_CHARSET);
- if (charset != null) {
- part.setCharset(charset);
- }
-
- byte[] contentDisposition = getByteArrayFromPartColumn(
- c, PART_COLUMN_CONTENT_DISPOSITION);
- if (contentDisposition != null) {
- part.setContentDisposition(contentDisposition);
- }
-
- byte[] contentId = getByteArrayFromPartColumn(
- c, PART_COLUMN_CONTENT_ID);
- if (contentId != null) {
- part.setContentId(contentId);
- }
-
- byte[] contentLocation = getByteArrayFromPartColumn(
- c, PART_COLUMN_CONTENT_LOCATION);
- if (contentLocation != null) {
- part.setContentLocation(contentLocation);
- }
-
- byte[] contentType = getByteArrayFromPartColumn(
- c, PART_COLUMN_CONTENT_TYPE);
- if (contentType != null) {
- part.setContentType(contentType);
- } else {
- throw new MmsException("Content-Type must be set.");
- }
-
- byte[] fileName = getByteArrayFromPartColumn(
- c, PART_COLUMN_FILENAME);
- if (fileName != null) {
- part.setFilename(fileName);
- }
-
- byte[] name = getByteArrayFromPartColumn(
- c, PART_COLUMN_NAME);
- if (name != null) {
- part.setName(name);
- }
-
- // Construct a Uri for this part.
- long partId = c.getLong(PART_COLUMN_ID);
- Uri partURI = Uri.parse("content://mms/part/" + partId);
- part.setDataUri(partURI);
-
- // For images/audio/video, we won't keep their data in Part
- // because their renderer accept Uri as source.
- String type = toIsoString(contentType);
- if (!ContentType.isImageType(type)
- && !ContentType.isAudioType(type)
- && !ContentType.isVideoType(type)) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- InputStream is = null;
-
- // Store simple string values directly in the database instead of an
- // external file. This makes the text searchable and retrieval slightly
- // faster.
- if (ContentType.TEXT_PLAIN.equals(type) || ContentType.APP_SMIL.equals(type)
- || ContentType.TEXT_HTML.equals(type)) {
- String text = c.getString(PART_COLUMN_TEXT);
- byte [] blob = new EncodedStringValue(text != null ? text : "")
- .getTextString();
- baos.write(blob, 0, blob.length);
- } else {
-
- try {
- is = mContentResolver.openInputStream(partURI);
-
- byte[] buffer = new byte[256];
- int len = is.read(buffer);
- while (len >= 0) {
- baos.write(buffer, 0, len);
- len = is.read(buffer);
- }
- } catch (IOException e) {
- Log.e(TAG, "Failed to load part data", e);
- c.close();
- throw new MmsException(e);
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- Log.e(TAG, "Failed to close stream", e);
- } // Ignore
- }
- }
- }
- part.setData(baos.toByteArray());
- }
- parts[partIdx++] = part;
- }
- } finally {
- if (c != null) {
- c.close();
- }
- }
-
- return parts;
- }
-
- private void loadAddress(long msgId, PduHeaders headers) {
- Cursor c = SqliteWrapper.query(mContext, mContentResolver,
- Uri.parse("content://mms/" + msgId + "/addr"),
- new String[] { Addr.ADDRESS, Addr.CHARSET, Addr.TYPE },
- null, null, null);
-
- if (c != null) {
- try {
- while (c.moveToNext()) {
- String addr = c.getString(0);
- if (!TextUtils.isEmpty(addr)) {
- int addrType = c.getInt(2);
- switch (addrType) {
- case PduHeaders.FROM:
- headers.setEncodedStringValue(
- new EncodedStringValue(c.getInt(1), getBytes(addr)),
- addrType);
- break;
- case PduHeaders.TO:
- case PduHeaders.CC:
- case PduHeaders.BCC:
- headers.appendEncodedStringValue(
- new EncodedStringValue(c.getInt(1), getBytes(addr)),
- addrType);
- break;
- default:
- Log.e(TAG, "Unknown address type: " + addrType);
- break;
- }
- }
- }
- } finally {
- c.close();
- }
- }
- }
-
- /**
- * Load a PDU from storage by given Uri.
- *
- * @param uri The Uri of the PDU to be loaded.
- * @return A generic PDU object, it may be cast to dedicated PDU.
- * @throws MmsException Failed to load some fields of a PDU.
- */
- public GenericPdu load(Uri uri) throws MmsException {
- GenericPdu pdu = null;
- PduCacheEntry cacheEntry = null;
- int msgBox = 0;
- long threadId = -1;
- try {
- synchronized(PDU_CACHE_INSTANCE) {
- if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "load: " + uri + " blocked by isUpdating()");
- }
- try {
- PDU_CACHE_INSTANCE.wait();
- } catch (InterruptedException e) {
- Log.e(TAG, "load: ", e);
- }
- cacheEntry = PDU_CACHE_INSTANCE.get(uri);
- if (cacheEntry != null) {
- return cacheEntry.getPdu();
- }
- }
- // Tell the cache to indicate to other callers that this item
- // is currently being updated.
- PDU_CACHE_INSTANCE.setUpdating(uri, true);
- }
-
- Cursor c = SqliteWrapper.query(mContext, mContentResolver, uri,
- PDU_PROJECTION, null, null, null);
- PduHeaders headers = new PduHeaders();
- Set<Entry<Integer, Integer>> set;
- long msgId = ContentUris.parseId(uri);
-
- try {
- if ((c == null) || (c.getCount() != 1) || !c.moveToFirst()) {
- throw new MmsException("Bad uri: " + uri);
- }
-
- msgBox = c.getInt(PDU_COLUMN_MESSAGE_BOX);
- threadId = c.getLong(PDU_COLUMN_THREAD_ID);
-
- set = ENCODED_STRING_COLUMN_INDEX_MAP.entrySet();
- for (Entry<Integer, Integer> e : set) {
- setEncodedStringValueToHeaders(
- c, e.getValue(), headers, e.getKey());
- }
-
- set = TEXT_STRING_COLUMN_INDEX_MAP.entrySet();
- for (Entry<Integer, Integer> e : set) {
- setTextStringToHeaders(
- c, e.getValue(), headers, e.getKey());
- }
-
- set = OCTET_COLUMN_INDEX_MAP.entrySet();
- for (Entry<Integer, Integer> e : set) {
- setOctetToHeaders(
- c, e.getValue(), headers, e.getKey());
- }
-
- set = LONG_COLUMN_INDEX_MAP.entrySet();
- for (Entry<Integer, Integer> e : set) {
- setLongToHeaders(
- c, e.getValue(), headers, e.getKey());
- }
- } finally {
- if (c != null) {
- c.close();
- }
- }
-
- // Check whether 'msgId' has been assigned a valid value.
- if (msgId == -1L) {
- throw new MmsException("Error! ID of the message: -1.");
- }
-
- // Load address information of the MM.
- loadAddress(msgId, headers);
-
- int msgType = headers.getOctet(PduHeaders.MESSAGE_TYPE);
- PduBody body = new PduBody();
-
- // For PDU which type is M_retrieve.conf or Send.req, we should
- // load multiparts and put them into the body of the PDU.
- if ((msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)
- || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) {
- PduPart[] parts = loadParts(msgId);
- if (parts != null) {
- int partsNum = parts.length;
- for (int i = 0; i < partsNum; i++) {
- body.addPart(parts[i]);
- }
- }
- }
-
- switch (msgType) {
- case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
- pdu = new NotificationInd(headers);
- break;
- case PduHeaders.MESSAGE_TYPE_DELIVERY_IND:
- pdu = new DeliveryInd(headers);
- break;
- case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND:
- pdu = new ReadOrigInd(headers);
- break;
- case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
- pdu = new RetrieveConf(headers, body);
- break;
- case PduHeaders.MESSAGE_TYPE_SEND_REQ:
- pdu = new SendReq(headers, body);
- break;
- case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND:
- pdu = new AcknowledgeInd(headers);
- break;
- case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND:
- pdu = new NotifyRespInd(headers);
- break;
- case PduHeaders.MESSAGE_TYPE_READ_REC_IND:
- pdu = new ReadRecInd(headers);
- break;
- case PduHeaders.MESSAGE_TYPE_SEND_CONF:
- case PduHeaders.MESSAGE_TYPE_FORWARD_REQ:
- case PduHeaders.MESSAGE_TYPE_FORWARD_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ:
- case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ:
- case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ:
- case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ:
- case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF:
- case PduHeaders.MESSAGE_TYPE_MBOX_DESCR:
- case PduHeaders.MESSAGE_TYPE_DELETE_REQ:
- case PduHeaders.MESSAGE_TYPE_DELETE_CONF:
- case PduHeaders.MESSAGE_TYPE_CANCEL_REQ:
- case PduHeaders.MESSAGE_TYPE_CANCEL_CONF:
- throw new MmsException(
- "Unsupported PDU type: " + Integer.toHexString(msgType));
-
- default:
- throw new MmsException(
- "Unrecognized PDU type: " + Integer.toHexString(msgType));
- }
- } finally {
- synchronized(PDU_CACHE_INSTANCE) {
- if (pdu != null) {
- assert(PDU_CACHE_INSTANCE.get(uri) == null);
- // Update the cache entry with the real info
- cacheEntry = new PduCacheEntry(pdu, msgBox, threadId);
- PDU_CACHE_INSTANCE.put(uri, cacheEntry);
- }
- PDU_CACHE_INSTANCE.setUpdating(uri, false);
- PDU_CACHE_INSTANCE.notifyAll(); // tell anybody waiting on this entry to go ahead
- }
- }
- return pdu;
- }
-
- private void persistAddress(
- long msgId, int type, EncodedStringValue[] array) {
- ContentValues values = new ContentValues(3);
-
- for (EncodedStringValue addr : array) {
- values.clear(); // Clear all values first.
- values.put(Addr.ADDRESS, toIsoString(addr.getTextString()));
- values.put(Addr.CHARSET, addr.getCharacterSet());
- values.put(Addr.TYPE, type);
-
- Uri uri = Uri.parse("content://mms/" + msgId + "/addr");
- SqliteWrapper.insert(mContext, mContentResolver, uri, values);
- }
- }
-
- public Uri persistPart(PduPart part, long msgId)
- throws MmsException {
- Uri uri = Uri.parse("content://mms/" + msgId + "/part");
- ContentValues values = new ContentValues(8);
-
- int charset = part.getCharset();
- if (charset != 0 ) {
- values.put(Part.CHARSET, charset);
- }
-
- String contentType = null;
- if (part.getContentType() != null) {
- contentType = toIsoString(part.getContentType());
-
- // There is no "image/jpg" in Android (and it's an invalid mimetype).
- // Change it to "image/jpeg"
- if (ContentType.IMAGE_JPG.equals(contentType)) {
- contentType = ContentType.IMAGE_JPEG;
- }
-
- values.put(Part.CONTENT_TYPE, contentType);
- // To ensure the SMIL part is always the first part.
- if (ContentType.APP_SMIL.equals(contentType)) {
- values.put(Part.SEQ, -1);
- }
- } else {
- throw new MmsException("MIME type of the part must be set.");
- }
-
- if (part.getFilename() != null) {
- String fileName = new String(part.getFilename());
- values.put(Part.FILENAME, fileName);
- }
-
- if (part.getName() != null) {
- String name = new String(part.getName());
- values.put(Part.NAME, name);
- }
-
- Object value = null;
- if (part.getContentDisposition() != null) {
- value = toIsoString(part.getContentDisposition());
- values.put(Part.CONTENT_DISPOSITION, (String) value);
- }
-
- if (part.getContentId() != null) {
- value = toIsoString(part.getContentId());
- values.put(Part.CONTENT_ID, (String) value);
- }
-
- if (part.getContentLocation() != null) {
- value = toIsoString(part.getContentLocation());
- values.put(Part.CONTENT_LOCATION, (String) value);
- }
-
- Uri res = SqliteWrapper.insert(mContext, mContentResolver, uri, values);
- if (res == null) {
- throw new MmsException("Failed to persist part, return null.");
- }
-
- persistData(part, res, contentType);
- // After successfully store the data, we should update
- // the dataUri of the part.
- part.setDataUri(res);
-
- return res;
- }
-
- /**
- * Save data of the part into storage. The source data may be given
- * by a byte[] or a Uri. If it's a byte[], directly save it
- * into storage, otherwise load source data from the dataUri and then
- * save it. If the data is an image, we may scale down it according
- * to user preference.
- *
- * @param part The PDU part which contains data to be saved.
- * @param uri The URI of the part.
- * @param contentType The MIME type of the part.
- * @throws MmsException Cannot find source data or error occurred
- * while saving the data.
- */
- private void persistData(PduPart part, Uri uri,
- String contentType)
- throws MmsException {
- OutputStream os = null;
- InputStream is = null;
- DrmConvertSession drmConvertSession = null;
- Uri dataUri = null;
- String path = null;
-
- try {
- byte[] data = part.getData();
- if (ContentType.TEXT_PLAIN.equals(contentType)
- || ContentType.APP_SMIL.equals(contentType)
- || ContentType.TEXT_HTML.equals(contentType)) {
- ContentValues cv = new ContentValues();
- cv.put(Telephony.Mms.Part.TEXT, new EncodedStringValue(data).getString());
- if (mContentResolver.update(uri, cv, null, null) != 1) {
- throw new MmsException("unable to update " + uri.toString());
- }
- } else {
- boolean isDrm = DownloadDrmHelper.isDrmConvertNeeded(contentType);
- if (isDrm) {
- if (uri != null) {
- try {
- path = convertUriToPath(mContext, uri);
- if (LOCAL_LOGV) {
- Log.v(TAG, "drm uri: " + uri + " path: " + path);
- }
- File f = new File(path);
- long len = f.length();
- if (LOCAL_LOGV) {
- Log.v(TAG, "drm path: " + path + " len: " + len);
- }
- if (len > 0) {
- // we're not going to re-persist and re-encrypt an already
- // converted drm file
- return;
- }
- } catch (Exception e) {
- Log.e(TAG, "Can't get file info for: " + part.getDataUri(), e);
- }
- }
- // We haven't converted the file yet, start the conversion
- drmConvertSession = DrmConvertSession.open(mContext, contentType);
- if (drmConvertSession == null) {
- throw new MmsException("Mimetype " + contentType +
- " can not be converted.");
- }
- }
- os = mContentResolver.openOutputStream(uri);
- if (data == null) {
- dataUri = part.getDataUri();
- if ((dataUri == null) || (dataUri == uri)) {
- Log.w(TAG, "Can't find data for this part.");
- return;
- }
- is = mContentResolver.openInputStream(dataUri);
-
- if (LOCAL_LOGV) {
- Log.v(TAG, "Saving data to: " + uri);
- }
-
- byte[] buffer = new byte[8192];
- for (int len = 0; (len = is.read(buffer)) != -1; ) {
- if (!isDrm) {
- os.write(buffer, 0, len);
- } else {
- byte[] convertedData = drmConvertSession.convert(buffer, len);
- if (convertedData != null) {
- os.write(convertedData, 0, convertedData.length);
- } else {
- throw new MmsException("Error converting drm data.");
- }
- }
- }
- } else {
- if (LOCAL_LOGV) {
- Log.v(TAG, "Saving data to: " + uri);
- }
- if (!isDrm) {
- os.write(data);
- } else {
- dataUri = uri;
- byte[] convertedData = drmConvertSession.convert(data, data.length);
- if (convertedData != null) {
- os.write(convertedData, 0, convertedData.length);
- } else {
- throw new MmsException("Error converting drm data.");
- }
- }
- }
- }
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Failed to open Input/Output stream.", e);
- throw new MmsException(e);
- } catch (IOException e) {
- Log.e(TAG, "Failed to read/write data.", e);
- throw new MmsException(e);
- } finally {
- if (os != null) {
- try {
- os.close();
- } catch (IOException e) {
- Log.e(TAG, "IOException while closing: " + os, e);
- } // Ignore
- }
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- Log.e(TAG, "IOException while closing: " + is, e);
- } // Ignore
- }
- if (drmConvertSession != null) {
- drmConvertSession.close(path);
-
- // Reset the permissions on the encrypted part file so everyone has only read
- // permission.
- File f = new File(path);
- ContentValues values = new ContentValues(0);
- SqliteWrapper.update(mContext, mContentResolver,
- Uri.parse("content://mms/resetFilePerm/" + f.getName()),
- values, null, null);
- }
- }
- }
-
- /**
- * This method expects uri in the following format
- * content://media/<table_name>/<row_index> (or)
- * file://sdcard/test.mp4
- * http://test.com/test.mp4
- *
- * Here <table_name> shall be "video" or "audio" or "images"
- * <row_index> the index of the content in given table
- */
- static public String convertUriToPath(Context context, Uri uri) {
- String path = null;
- if (null != uri) {
- String scheme = uri.getScheme();
- if (null == scheme || scheme.equals("") ||
- scheme.equals(ContentResolver.SCHEME_FILE)) {
- path = uri.getPath();
-
- } else if (scheme.equals("http")) {
- path = uri.toString();
-
- } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
- String[] projection = new String[] {MediaStore.MediaColumns.DATA};
- Cursor cursor = null;
- try {
- cursor = context.getContentResolver().query(uri, projection, null,
- null, null);
- if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) {
- throw new IllegalArgumentException("Given Uri could not be found" +
- " in media store");
- }
- int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
- path = cursor.getString(pathIndex);
- } catch (SQLiteException e) {
- throw new IllegalArgumentException("Given Uri is not formatted in a way " +
- "so that it can be found in media store.");
- } finally {
- if (null != cursor) {
- cursor.close();
- }
- }
- } else {
- throw new IllegalArgumentException("Given Uri scheme is not supported");
- }
- }
- return path;
- }
-
- private void updateAddress(
- long msgId, int type, EncodedStringValue[] array) {
- // Delete old address information and then insert new ones.
- SqliteWrapper.delete(mContext, mContentResolver,
- Uri.parse("content://mms/" + msgId + "/addr"),
- Addr.TYPE + "=" + type, null);
-
- persistAddress(msgId, type, array);
- }
-
- /**
- * Update headers of a SendReq.
- *
- * @param uri The PDU which need to be updated.
- * @param pdu New headers.
- * @throws MmsException Bad URI or updating failed.
- */
- public void updateHeaders(Uri uri, SendReq sendReq) {
- synchronized(PDU_CACHE_INSTANCE) {
- // If the cache item is getting updated, wait until it's done updating before
- // purging it.
- if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "updateHeaders: " + uri + " blocked by isUpdating()");
- }
- try {
- PDU_CACHE_INSTANCE.wait();
- } catch (InterruptedException e) {
- Log.e(TAG, "updateHeaders: ", e);
- }
- }
- }
- PDU_CACHE_INSTANCE.purge(uri);
-
- ContentValues values = new ContentValues(10);
- byte[] contentType = sendReq.getContentType();
- if (contentType != null) {
- values.put(Mms.CONTENT_TYPE, toIsoString(contentType));
- }
-
- long date = sendReq.getDate();
- if (date != -1) {
- values.put(Mms.DATE, date);
- }
-
- int deliveryReport = sendReq.getDeliveryReport();
- if (deliveryReport != 0) {
- values.put(Mms.DELIVERY_REPORT, deliveryReport);
- }
-
- long expiry = sendReq.getExpiry();
- if (expiry != -1) {
- values.put(Mms.EXPIRY, expiry);
- }
-
- byte[] msgClass = sendReq.getMessageClass();
- if (msgClass != null) {
- values.put(Mms.MESSAGE_CLASS, toIsoString(msgClass));
- }
-
- int priority = sendReq.getPriority();
- if (priority != 0) {
- values.put(Mms.PRIORITY, priority);
- }
-
- int readReport = sendReq.getReadReport();
- if (readReport != 0) {
- values.put(Mms.READ_REPORT, readReport);
- }
-
- byte[] transId = sendReq.getTransactionId();
- if (transId != null) {
- values.put(Mms.TRANSACTION_ID, toIsoString(transId));
- }
-
- EncodedStringValue subject = sendReq.getSubject();
- if (subject != null) {
- values.put(Mms.SUBJECT, toIsoString(subject.getTextString()));
- values.put(Mms.SUBJECT_CHARSET, subject.getCharacterSet());
- } else {
- values.put(Mms.SUBJECT, "");
- }
-
- long messageSize = sendReq.getMessageSize();
- if (messageSize > 0) {
- values.put(Mms.MESSAGE_SIZE, messageSize);
- }
-
- PduHeaders headers = sendReq.getPduHeaders();
- HashSet<String> recipients = new HashSet<String>();
- for (int addrType : ADDRESS_FIELDS) {
- EncodedStringValue[] array = null;
- if (addrType == PduHeaders.FROM) {
- EncodedStringValue v = headers.getEncodedStringValue(addrType);
- if (v != null) {
- array = new EncodedStringValue[1];
- array[0] = v;
- }
- } else {
- array = headers.getEncodedStringValues(addrType);
- }
-
- if (array != null) {
- long msgId = ContentUris.parseId(uri);
- updateAddress(msgId, addrType, array);
- if (addrType == PduHeaders.TO) {
- for (EncodedStringValue v : array) {
- if (v != null) {
- recipients.add(v.getString());
- }
- }
- }
- }
- }
- if (!recipients.isEmpty()) {
- long threadId = Threads.getOrCreateThreadId(mContext, recipients);
- values.put(Mms.THREAD_ID, threadId);
- }
-
- SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null);
- }
-
- private void updatePart(Uri uri, PduPart part) throws MmsException {
- ContentValues values = new ContentValues(7);
-
- int charset = part.getCharset();
- if (charset != 0 ) {
- values.put(Part.CHARSET, charset);
- }
-
- String contentType = null;
- if (part.getContentType() != null) {
- contentType = toIsoString(part.getContentType());
- values.put(Part.CONTENT_TYPE, contentType);
- } else {
- throw new MmsException("MIME type of the part must be set.");
- }
-
- if (part.getFilename() != null) {
- String fileName = new String(part.getFilename());
- values.put(Part.FILENAME, fileName);
- }
-
- if (part.getName() != null) {
- String name = new String(part.getName());
- values.put(Part.NAME, name);
- }
-
- Object value = null;
- if (part.getContentDisposition() != null) {
- value = toIsoString(part.getContentDisposition());
- values.put(Part.CONTENT_DISPOSITION, (String) value);
- }
-
- if (part.getContentId() != null) {
- value = toIsoString(part.getContentId());
- values.put(Part.CONTENT_ID, (String) value);
- }
-
- if (part.getContentLocation() != null) {
- value = toIsoString(part.getContentLocation());
- values.put(Part.CONTENT_LOCATION, (String) value);
- }
-
- SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null);
-
- // Only update the data when:
- // 1. New binary data supplied or
- // 2. The Uri of the part is different from the current one.
- if ((part.getData() != null)
- || (uri != part.getDataUri())) {
- persistData(part, uri, contentType);
- }
- }
-
- /**
- * Update all parts of a PDU.
- *
- * @param uri The PDU which need to be updated.
- * @param body New message body of the PDU.
- * @throws MmsException Bad URI or updating failed.
- */
- public void updateParts(Uri uri, PduBody body)
- throws MmsException {
- try {
- PduCacheEntry cacheEntry;
- synchronized(PDU_CACHE_INSTANCE) {
- if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "updateParts: " + uri + " blocked by isUpdating()");
- }
- try {
- PDU_CACHE_INSTANCE.wait();
- } catch (InterruptedException e) {
- Log.e(TAG, "updateParts: ", e);
- }
- cacheEntry = PDU_CACHE_INSTANCE.get(uri);
- if (cacheEntry != null) {
- ((MultimediaMessagePdu) cacheEntry.getPdu()).setBody(body);
- }
- }
- // Tell the cache to indicate to other callers that this item
- // is currently being updated.
- PDU_CACHE_INSTANCE.setUpdating(uri, true);
- }
-
- ArrayList<PduPart> toBeCreated = new ArrayList<PduPart>();
- HashMap<Uri, PduPart> toBeUpdated = new HashMap<Uri, PduPart>();
-
- int partsNum = body.getPartsNum();
- StringBuilder filter = new StringBuilder().append('(');
- for (int i = 0; i < partsNum; i++) {
- PduPart part = body.getPart(i);
- Uri partUri = part.getDataUri();
- if ((partUri == null) || !partUri.getAuthority().startsWith("mms")) {
- toBeCreated.add(part);
- } else {
- toBeUpdated.put(partUri, part);
-
- // Don't use 'i > 0' to determine whether we should append
- // 'AND' since 'i = 0' may be skipped in another branch.
- if (filter.length() > 1) {
- filter.append(" AND ");
- }
-
- filter.append(Part._ID);
- filter.append("!=");
- DatabaseUtils.appendEscapedSQLString(filter, partUri.getLastPathSegment());
- }
- }
- filter.append(')');
-
- long msgId = ContentUris.parseId(uri);
-
- // Remove the parts which doesn't exist anymore.
- SqliteWrapper.delete(mContext, mContentResolver,
- Uri.parse(Mms.CONTENT_URI + "/" + msgId + "/part"),
- filter.length() > 2 ? filter.toString() : null, null);
-
- // Create new parts which didn't exist before.
- for (PduPart part : toBeCreated) {
- persistPart(part, msgId);
- }
-
- // Update the modified parts.
- for (Map.Entry<Uri, PduPart> e : toBeUpdated.entrySet()) {
- updatePart(e.getKey(), e.getValue());
- }
- } finally {
- synchronized(PDU_CACHE_INSTANCE) {
- PDU_CACHE_INSTANCE.setUpdating(uri, false);
- PDU_CACHE_INSTANCE.notifyAll();
- }
- }
- }
-
- /**
- * Persist a PDU object to specific location in the storage.
- *
- * @param pdu The PDU object to be stored.
- * @param uri Where to store the given PDU object.
- * @return A Uri which can be used to access the stored PDU.
- */
- public Uri persist(GenericPdu pdu, Uri uri) throws MmsException {
- if (uri == null) {
- throw new MmsException("Uri may not be null.");
- }
- long msgId = -1;
- try {
- msgId = ContentUris.parseId(uri);
- } catch (NumberFormatException e) {
- // the uri ends with "inbox" or something else like that
- }
- boolean existingUri = msgId != -1;
-
- if (!existingUri && MESSAGE_BOX_MAP.get(uri) == null) {
- throw new MmsException(
- "Bad destination, must be one of "
- + "content://mms/inbox, content://mms/sent, "
- + "content://mms/drafts, content://mms/outbox, "
- + "content://mms/temp.");
- }
- synchronized(PDU_CACHE_INSTANCE) {
- // If the cache item is getting updated, wait until it's done updating before
- // purging it.
- if (PDU_CACHE_INSTANCE.isUpdating(uri)) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "persist: " + uri + " blocked by isUpdating()");
- }
- try {
- PDU_CACHE_INSTANCE.wait();
- } catch (InterruptedException e) {
- Log.e(TAG, "persist1: ", e);
- }
- }
- }
- PDU_CACHE_INSTANCE.purge(uri);
-
- PduHeaders header = pdu.getPduHeaders();
- PduBody body = null;
- ContentValues values = new ContentValues();
- Set<Entry<Integer, String>> set;
-
- set = ENCODED_STRING_COLUMN_NAME_MAP.entrySet();
- for (Entry<Integer, String> e : set) {
- int field = e.getKey();
- EncodedStringValue encodedString = header.getEncodedStringValue(field);
- if (encodedString != null) {
- String charsetColumn = CHARSET_COLUMN_NAME_MAP.get(field);
- values.put(e.getValue(), toIsoString(encodedString.getTextString()));
- values.put(charsetColumn, encodedString.getCharacterSet());
- }
- }
-
- set = TEXT_STRING_COLUMN_NAME_MAP.entrySet();
- for (Entry<Integer, String> e : set){
- byte[] text = header.getTextString(e.getKey());
- if (text != null) {
- values.put(e.getValue(), toIsoString(text));
- }
- }
-
- set = OCTET_COLUMN_NAME_MAP.entrySet();
- for (Entry<Integer, String> e : set){
- int b = header.getOctet(e.getKey());
- if (b != 0) {
- values.put(e.getValue(), b);
- }
- }
-
- set = LONG_COLUMN_NAME_MAP.entrySet();
- for (Entry<Integer, String> e : set){
- long l = header.getLongInteger(e.getKey());
- if (l != -1L) {
- values.put(e.getValue(), l);
- }
- }
-
- HashMap<Integer, EncodedStringValue[]> addressMap =
- new HashMap<Integer, EncodedStringValue[]>(ADDRESS_FIELDS.length);
- // Save address information.
- for (int addrType : ADDRESS_FIELDS) {
- EncodedStringValue[] array = null;
- if (addrType == PduHeaders.FROM) {
- EncodedStringValue v = header.getEncodedStringValue(addrType);
- if (v != null) {
- array = new EncodedStringValue[1];
- array[0] = v;
- }
- } else {
- array = header.getEncodedStringValues(addrType);
- }
- addressMap.put(addrType, array);
- }
-
- HashSet<String> recipients = new HashSet<String>();
- int msgType = pdu.getMessageType();
- // Here we only allocate thread ID for M-Notification.ind,
- // M-Retrieve.conf and M-Send.req.
- // Some of other PDU types may be allocated a thread ID outside
- // this scope.
- if ((msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND)
- || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)
- || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) {
- EncodedStringValue[] array = null;
- switch (msgType) {
- case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
- case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF:
- array = addressMap.get(PduHeaders.FROM);
- break;
- case PduHeaders.MESSAGE_TYPE_SEND_REQ:
- array = addressMap.get(PduHeaders.TO);
- break;
- }
-
- if (array != null) {
- for (EncodedStringValue v : array) {
- if (v != null) {
- recipients.add(v.getString());
- }
- }
- }
- if (!recipients.isEmpty()) {
- long threadId = Threads.getOrCreateThreadId(mContext, recipients);
- values.put(Mms.THREAD_ID, threadId);
- }
- }
-
- // Save parts first to avoid inconsistent message is loaded
- // while saving the parts.
- long dummyId = System.currentTimeMillis(); // Dummy ID of the msg.
- // Get body if the PDU is a RetrieveConf or SendReq.
- if (pdu instanceof MultimediaMessagePdu) {
- body = ((MultimediaMessagePdu) pdu).getBody();
- // Start saving parts if necessary.
- if (body != null) {
- int partsNum = body.getPartsNum();
- for (int i = 0; i < partsNum; i++) {
- PduPart part = body.getPart(i);
- persistPart(part, dummyId);
- }
- }
- }
-
- Uri res = null;
- if (existingUri) {
- res = uri;
- SqliteWrapper.update(mContext, mContentResolver, res, values, null, null);
- } else {
- res = SqliteWrapper.insert(mContext, mContentResolver, uri, values);
- if (res == null) {
- throw new MmsException("persist() failed: return null.");
- }
- // Get the real ID of the PDU and update all parts which were
- // saved with the dummy ID.
- msgId = ContentUris.parseId(res);
- }
-
- values = new ContentValues(1);
- values.put(Part.MSG_ID, msgId);
- SqliteWrapper.update(mContext, mContentResolver,
- Uri.parse("content://mms/" + dummyId + "/part"),
- values, null, null);
- // We should return the longest URI of the persisted PDU, for
- // example, if input URI is "content://mms/inbox" and the _ID of
- // persisted PDU is '8', we should return "content://mms/inbox/8"
- // instead of "content://mms/8".
- // FIXME: Should the MmsProvider be responsible for this???
- if (!existingUri) {
- res = Uri.parse(uri + "/" + msgId);
- }
-
- // Save address information.
- for (int addrType : ADDRESS_FIELDS) {
- EncodedStringValue[] array = addressMap.get(addrType);
- if (array != null) {
- persistAddress(msgId, addrType, array);
- }
- }
-
- return res;
- }
-
- /**
- * Move a PDU object from one location to another.
- *
- * @param from Specify the PDU object to be moved.
- * @param to The destination location, should be one of the following:
- * "content://mms/inbox", "content://mms/sent",
- * "content://mms/drafts", "content://mms/outbox",
- * "content://mms/trash".
- * @return New Uri of the moved PDU.
- * @throws MmsException Error occurred while moving the message.
- */
- public Uri move(Uri from, Uri to) throws MmsException {
- // Check whether the 'msgId' has been assigned a valid value.
- long msgId = ContentUris.parseId(from);
- if (msgId == -1L) {
- throw new MmsException("Error! ID of the message: -1.");
- }
-
- // Get corresponding int value of destination box.
- Integer msgBox = MESSAGE_BOX_MAP.get(to);
- if (msgBox == null) {
- throw new MmsException(
- "Bad destination, must be one of "
- + "content://mms/inbox, content://mms/sent, "
- + "content://mms/drafts, content://mms/outbox, "
- + "content://mms/temp.");
- }
-
- ContentValues values = new ContentValues(1);
- values.put(Mms.MESSAGE_BOX, msgBox);
- SqliteWrapper.update(mContext, mContentResolver, from, values, null, null);
- return ContentUris.withAppendedId(to, msgId);
- }
-
- /**
- * Wrap a byte[] into a String.
- */
- public static String toIsoString(byte[] bytes) {
- try {
- return new String(bytes, CharacterSets.MIMENAME_ISO_8859_1);
- } catch (UnsupportedEncodingException e) {
- // Impossible to reach here!
- Log.e(TAG, "ISO_8859_1 must be supported!", e);
- return "";
- }
- }
-
- /**
- * Unpack a given String into a byte[].
- */
- public static byte[] getBytes(String data) {
- try {
- return data.getBytes(CharacterSets.MIMENAME_ISO_8859_1);
- } catch (UnsupportedEncodingException e) {
- // Impossible to reach here!
- Log.e(TAG, "ISO_8859_1 must be supported!", e);
- return new byte[0];
- }
- }
-
- /**
- * Remove all objects in the temporary path.
- */
- public void release() {
- Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI);
- SqliteWrapper.delete(mContext, mContentResolver, uri, null, null);
- }
-
- /**
- * Find all messages to be sent or downloaded before certain time.
- */
- public Cursor getPendingMessages(long dueTime) {
- Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon();
- uriBuilder.appendQueryParameter("protocol", "mms");
-
- String selection = PendingMessages.ERROR_TYPE + " < ?"
- + " AND " + PendingMessages.DUE_TIME + " <= ?";
-
- String[] selectionArgs = new String[] {
- String.valueOf(MmsSms.ERR_TYPE_GENERIC_PERMANENT),
- String.valueOf(dueTime)
- };
-
- return SqliteWrapper.query(mContext, mContentResolver,
- uriBuilder.build(), null, selection, selectionArgs,
- PendingMessages.DUE_TIME);
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/QuotedPrintable.java b/core/java/com/google/android/mms/pdu/QuotedPrintable.java
deleted file mode 100644
index a34ed12..0000000
--- a/core/java/com/google/android/mms/pdu/QuotedPrintable.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import java.io.ByteArrayOutputStream;
-
-public class QuotedPrintable {
- private static byte ESCAPE_CHAR = '=';
-
- /**
- * Decodes an array quoted-printable characters into an array of original bytes.
- * Escaped characters are converted back to their original representation.
- *
- * <p>
- * This function implements a subset of
- * quoted-printable encoding specification (rule #1 and rule #2)
- * as defined in RFC 1521.
- * </p>
- *
- * @param bytes array of quoted-printable characters
- * @return array of original bytes,
- * null if quoted-printable decoding is unsuccessful.
- */
- public static final byte[] decodeQuotedPrintable(byte[] bytes) {
- if (bytes == null) {
- return null;
- }
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- for (int i = 0; i < bytes.length; i++) {
- int b = bytes[i];
- if (b == ESCAPE_CHAR) {
- try {
- if('\r' == (char)bytes[i + 1] &&
- '\n' == (char)bytes[i + 2]) {
- i += 2;
- continue;
- }
- int u = Character.digit((char) bytes[++i], 16);
- int l = Character.digit((char) bytes[++i], 16);
- if (u == -1 || l == -1) {
- return null;
- }
- buffer.write((char) ((u << 4) + l));
- } catch (ArrayIndexOutOfBoundsException e) {
- return null;
- }
- } else {
- buffer.write(b);
- }
- }
- return buffer.toByteArray();
- }
-}
diff --git a/core/java/com/google/android/mms/pdu/ReadOrigInd.java b/core/java/com/google/android/mms/pdu/ReadOrigInd.java
deleted file mode 100644
index 1bfc0bb..0000000
--- a/core/java/com/google/android/mms/pdu/ReadOrigInd.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class ReadOrigInd extends GenericPdu {
- /**
- * Empty constructor.
- * Since the Pdu corresponding to this class is constructed
- * by the Proxy-Relay server, this class is only instantiated
- * by the Pdu Parser.
- *
- * @throws InvalidHeaderValueException if error occurs.
- */
- public ReadOrigInd() throws InvalidHeaderValueException {
- super();
- setMessageType(PduHeaders.MESSAGE_TYPE_READ_ORIG_IND);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- ReadOrigInd(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Get Date value.
- *
- * @return the value
- */
- public long getDate() {
- return mPduHeaders.getLongInteger(PduHeaders.DATE);
- }
-
- /**
- * Set Date value.
- *
- * @param value the value
- */
- public void setDate(long value) {
- mPduHeaders.setLongInteger(value, PduHeaders.DATE);
- }
-
- /**
- * Get From value.
- * From-value = Value-length
- * (Address-present-token Encoded-string-value | Insert-address-token)
- *
- * @return the value
- */
- public EncodedStringValue getFrom() {
- return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
- }
-
- /**
- * Set From value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setFrom(EncodedStringValue value) {
- mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
- }
-
- /**
- * Get Message-ID value.
- *
- * @return the value
- */
- public byte[] getMessageId() {
- return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Set Message-ID value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setMessageId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Get X-MMS-Read-status value.
- *
- * @return the value
- */
- public int getReadStatus() {
- return mPduHeaders.getOctet(PduHeaders.READ_STATUS);
- }
-
- /**
- * Set X-MMS-Read-status value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setReadStatus(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.READ_STATUS);
- }
-
- /**
- * Get To value.
- *
- * @return the value
- */
- public EncodedStringValue[] getTo() {
- return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
- }
-
- /**
- * Set To value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setTo(EncodedStringValue[] value) {
- mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
- }
-
- /*
- * Optional, not supported header fields:
- *
- * public byte[] getApplicId() {return null;}
- * public void setApplicId(byte[] value) {}
- *
- * public byte[] getAuxApplicId() {return null;}
- * public void getAuxApplicId(byte[] value) {}
- *
- * public byte[] getReplyApplicId() {return 0x00;}
- * public void setReplyApplicId(byte[] value) {}
- */
-}
diff --git a/core/java/com/google/android/mms/pdu/ReadRecInd.java b/core/java/com/google/android/mms/pdu/ReadRecInd.java
deleted file mode 100644
index 880e3ac..0000000
--- a/core/java/com/google/android/mms/pdu/ReadRecInd.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class ReadRecInd extends GenericPdu {
- /**
- * Constructor, used when composing a M-ReadRec.ind pdu.
- *
- * @param from the from value
- * @param messageId the message ID value
- * @param mmsVersion current viersion of mms
- * @param readStatus the read status value
- * @param to the to value
- * @throws InvalidHeaderValueException if parameters are invalid.
- * NullPointerException if messageId or to is null.
- */
- public ReadRecInd(EncodedStringValue from,
- byte[] messageId,
- int mmsVersion,
- int readStatus,
- EncodedStringValue[] to) throws InvalidHeaderValueException {
- super();
- setMessageType(PduHeaders.MESSAGE_TYPE_READ_REC_IND);
- setFrom(from);
- setMessageId(messageId);
- setMmsVersion(mmsVersion);
- setTo(to);
- setReadStatus(readStatus);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- ReadRecInd(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Get Date value.
- *
- * @return the value
- */
- public long getDate() {
- return mPduHeaders.getLongInteger(PduHeaders.DATE);
- }
-
- /**
- * Set Date value.
- *
- * @param value the value
- */
- public void setDate(long value) {
- mPduHeaders.setLongInteger(value, PduHeaders.DATE);
- }
-
- /**
- * Get Message-ID value.
- *
- * @return the value
- */
- public byte[] getMessageId() {
- return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Set Message-ID value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setMessageId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Get To value.
- *
- * @return the value
- */
- public EncodedStringValue[] getTo() {
- return mPduHeaders.getEncodedStringValues(PduHeaders.TO);
- }
-
- /**
- * Set To value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setTo(EncodedStringValue[] value) {
- mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
- }
-
- /**
- * Get X-MMS-Read-status value.
- *
- * @return the value
- */
- public int getReadStatus() {
- return mPduHeaders.getOctet(PduHeaders.READ_STATUS);
- }
-
- /**
- * Set X-MMS-Read-status value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setReadStatus(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.READ_STATUS);
- }
-
- /*
- * Optional, not supported header fields:
- *
- * public byte[] getApplicId() {return null;}
- * public void setApplicId(byte[] value) {}
- *
- * public byte[] getAuxApplicId() {return null;}
- * public void getAuxApplicId(byte[] value) {}
- *
- * public byte[] getReplyApplicId() {return 0x00;}
- * public void setReplyApplicId(byte[] value) {}
- */
-}
diff --git a/core/java/com/google/android/mms/pdu/RetrieveConf.java b/core/java/com/google/android/mms/pdu/RetrieveConf.java
deleted file mode 100644
index 98e67c0..0000000
--- a/core/java/com/google/android/mms/pdu/RetrieveConf.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-/**
- * M-Retrive.conf Pdu.
- */
-public class RetrieveConf extends MultimediaMessagePdu {
- /**
- * Empty constructor.
- * Since the Pdu corresponding to this class is constructed
- * by the Proxy-Relay server, this class is only instantiated
- * by the Pdu Parser.
- *
- * @throws InvalidHeaderValueException if error occurs.
- */
- public RetrieveConf() throws InvalidHeaderValueException {
- super();
- setMessageType(PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- RetrieveConf(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Constructor with given headers and body
- *
- * @param headers Headers for this PDU.
- * @param body Body of this PDu.
- */
- RetrieveConf(PduHeaders headers, PduBody body) {
- super(headers, body);
- }
-
- /**
- * Get CC value.
- *
- * @return the value
- */
- public EncodedStringValue[] getCc() {
- return mPduHeaders.getEncodedStringValues(PduHeaders.CC);
- }
-
- /**
- * Add a "CC" value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void addCc(EncodedStringValue value) {
- mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC);
- }
-
- /**
- * Get Content-type value.
- *
- * @return the value
- */
- public byte[] getContentType() {
- return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE);
- }
-
- /**
- * Set Content-type value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setContentType(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE);
- }
-
- /**
- * Get X-Mms-Delivery-Report value.
- *
- * @return the value
- */
- public int getDeliveryReport() {
- return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
- }
-
- /**
- * Set X-Mms-Delivery-Report value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setDeliveryReport(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
- }
-
- /**
- * Get From value.
- * From-value = Value-length
- * (Address-present-token Encoded-string-value | Insert-address-token)
- *
- * @return the value
- */
- public EncodedStringValue getFrom() {
- return mPduHeaders.getEncodedStringValue(PduHeaders.FROM);
- }
-
- /**
- * Set From value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setFrom(EncodedStringValue value) {
- mPduHeaders.setEncodedStringValue(value, PduHeaders.FROM);
- }
-
- /**
- * Get X-Mms-Message-Class value.
- * Message-class-value = Class-identifier | Token-text
- * Class-identifier = Personal | Advertisement | Informational | Auto
- *
- * @return the value
- */
- public byte[] getMessageClass() {
- return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
- }
-
- /**
- * Set X-Mms-Message-Class value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setMessageClass(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
- }
-
- /**
- * Get Message-ID value.
- *
- * @return the value
- */
- public byte[] getMessageId() {
- return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Set Message-ID value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setMessageId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Get X-Mms-Read-Report value.
- *
- * @return the value
- */
- public int getReadReport() {
- return mPduHeaders.getOctet(PduHeaders.READ_REPORT);
- }
-
- /**
- * Set X-Mms-Read-Report value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setReadReport(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.READ_REPORT);
- }
-
- /**
- * Get X-Mms-Retrieve-Status value.
- *
- * @return the value
- */
- public int getRetrieveStatus() {
- return mPduHeaders.getOctet(PduHeaders.RETRIEVE_STATUS);
- }
-
- /**
- * Set X-Mms-Retrieve-Status value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setRetrieveStatus(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.RETRIEVE_STATUS);
- }
-
- /**
- * Get X-Mms-Retrieve-Text value.
- *
- * @return the value
- */
- public EncodedStringValue getRetrieveText() {
- return mPduHeaders.getEncodedStringValue(PduHeaders.RETRIEVE_TEXT);
- }
-
- /**
- * Set X-Mms-Retrieve-Text value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setRetrieveText(EncodedStringValue value) {
- mPduHeaders.setEncodedStringValue(value, PduHeaders.RETRIEVE_TEXT);
- }
-
- /**
- * Get X-Mms-Transaction-Id.
- *
- * @return the value
- */
- public byte[] getTransactionId() {
- return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
- }
-
- /**
- * Set X-Mms-Transaction-Id.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setTransactionId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
- }
-
- /*
- * Optional, not supported header fields:
- *
- * public byte[] getApplicId() {return null;}
- * public void setApplicId(byte[] value) {}
- *
- * public byte[] getAuxApplicId() {return null;}
- * public void getAuxApplicId(byte[] value) {}
- *
- * public byte getContentClass() {return 0x00;}
- * public void setApplicId(byte value) {}
- *
- * public byte getDrmContent() {return 0x00;}
- * public void setDrmContent(byte value) {}
- *
- * public byte getDistributionIndicator() {return 0x00;}
- * public void setDistributionIndicator(byte value) {}
- *
- * public PreviouslySentByValue getPreviouslySentBy() {return null;}
- * public void setPreviouslySentBy(PreviouslySentByValue value) {}
- *
- * public PreviouslySentDateValue getPreviouslySentDate() {}
- * public void setPreviouslySentDate(PreviouslySentDateValue value) {}
- *
- * public MmFlagsValue getMmFlags() {return null;}
- * public void setMmFlags(MmFlagsValue value) {}
- *
- * public MmStateValue getMmState() {return null;}
- * public void getMmState(MmStateValue value) {}
- *
- * public byte[] getReplaceId() {return 0x00;}
- * public void setReplaceId(byte[] value) {}
- *
- * public byte[] getReplyApplicId() {return 0x00;}
- * public void setReplyApplicId(byte[] value) {}
- *
- * public byte getReplyCharging() {return 0x00;}
- * public void setReplyCharging(byte value) {}
- *
- * public byte getReplyChargingDeadline() {return 0x00;}
- * public void setReplyChargingDeadline(byte value) {}
- *
- * public byte[] getReplyChargingId() {return 0x00;}
- * public void setReplyChargingId(byte[] value) {}
- *
- * public long getReplyChargingSize() {return 0;}
- * public void setReplyChargingSize(long value) {}
- */
-}
diff --git a/core/java/com/google/android/mms/pdu/SendConf.java b/core/java/com/google/android/mms/pdu/SendConf.java
deleted file mode 100644
index 0568fe79..0000000
--- a/core/java/com/google/android/mms/pdu/SendConf.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class SendConf extends GenericPdu {
- /**
- * Empty constructor.
- * Since the Pdu corresponding to this class is constructed
- * by the Proxy-Relay server, this class is only instantiated
- * by the Pdu Parser.
- *
- * @throws InvalidHeaderValueException if error occurs.
- */
- public SendConf() throws InvalidHeaderValueException {
- super();
- setMessageType(PduHeaders.MESSAGE_TYPE_SEND_CONF);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- SendConf(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Get Message-ID value.
- *
- * @return the value
- */
- public byte[] getMessageId() {
- return mPduHeaders.getTextString(PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Set Message-ID value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setMessageId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.MESSAGE_ID);
- }
-
- /**
- * Get X-Mms-Response-Status.
- *
- * @return the value
- */
- public int getResponseStatus() {
- return mPduHeaders.getOctet(PduHeaders.RESPONSE_STATUS);
- }
-
- /**
- * Set X-Mms-Response-Status.
- *
- * @param value the values
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setResponseStatus(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.RESPONSE_STATUS);
- }
-
- /**
- * Get X-Mms-Transaction-Id field value.
- *
- * @return the X-Mms-Report-Allowed value
- */
- public byte[] getTransactionId() {
- return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
- }
-
- /**
- * Set X-Mms-Transaction-Id field value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setTransactionId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
- }
-
- /*
- * Optional, not supported header fields:
- *
- * public byte[] getContentLocation() {return null;}
- * public void setContentLocation(byte[] value) {}
- *
- * public EncodedStringValue getResponseText() {return null;}
- * public void setResponseText(EncodedStringValue value) {}
- *
- * public byte getStoreStatus() {return 0x00;}
- * public void setStoreStatus(byte value) {}
- *
- * public byte[] getStoreStatusText() {return null;}
- * public void setStoreStatusText(byte[] value) {}
- */
-}
diff --git a/core/java/com/google/android/mms/pdu/SendReq.java b/core/java/com/google/android/mms/pdu/SendReq.java
deleted file mode 100644
index 597cd00..0000000
--- a/core/java/com/google/android/mms/pdu/SendReq.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Esmertec AG.
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.pdu;
-
-import android.util.Log;
-
-import com.google.android.mms.InvalidHeaderValueException;
-
-public class SendReq extends MultimediaMessagePdu {
- private static final String TAG = "SendReq";
-
- public SendReq() {
- super();
-
- try {
- setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ);
- setMmsVersion(PduHeaders.CURRENT_MMS_VERSION);
- // FIXME: Content-type must be decided according to whether
- // SMIL part present.
- setContentType("application/vnd.wap.multipart.related".getBytes());
- setFrom(new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()));
- setTransactionId(generateTransactionId());
- } catch (InvalidHeaderValueException e) {
- // Impossible to reach here since all headers we set above are valid.
- Log.e(TAG, "Unexpected InvalidHeaderValueException.", e);
- throw new RuntimeException(e);
- }
- }
-
- private byte[] generateTransactionId() {
- String transactionId = "T" + Long.toHexString(System.currentTimeMillis());
- return transactionId.getBytes();
- }
-
- /**
- * Constructor, used when composing a M-Send.req pdu.
- *
- * @param contentType the content type value
- * @param from the from value
- * @param mmsVersion current viersion of mms
- * @param transactionId the transaction-id value
- * @throws InvalidHeaderValueException if parameters are invalid.
- * NullPointerException if contentType, form or transactionId is null.
- */
- public SendReq(byte[] contentType,
- EncodedStringValue from,
- int mmsVersion,
- byte[] transactionId) throws InvalidHeaderValueException {
- super();
- setMessageType(PduHeaders.MESSAGE_TYPE_SEND_REQ);
- setContentType(contentType);
- setFrom(from);
- setMmsVersion(mmsVersion);
- setTransactionId(transactionId);
- }
-
- /**
- * Constructor with given headers.
- *
- * @param headers Headers for this PDU.
- */
- SendReq(PduHeaders headers) {
- super(headers);
- }
-
- /**
- * Constructor with given headers and body
- *
- * @param headers Headers for this PDU.
- * @param body Body of this PDu.
- */
- SendReq(PduHeaders headers, PduBody body) {
- super(headers, body);
- }
-
- /**
- * Get Bcc value.
- *
- * @return the value
- */
- public EncodedStringValue[] getBcc() {
- return mPduHeaders.getEncodedStringValues(PduHeaders.BCC);
- }
-
- /**
- * Add a "BCC" value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void addBcc(EncodedStringValue value) {
- mPduHeaders.appendEncodedStringValue(value, PduHeaders.BCC);
- }
-
- /**
- * Set "BCC" value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setBcc(EncodedStringValue[] value) {
- mPduHeaders.setEncodedStringValues(value, PduHeaders.BCC);
- }
-
- /**
- * Get CC value.
- *
- * @return the value
- */
- public EncodedStringValue[] getCc() {
- return mPduHeaders.getEncodedStringValues(PduHeaders.CC);
- }
-
- /**
- * Add a "CC" value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void addCc(EncodedStringValue value) {
- mPduHeaders.appendEncodedStringValue(value, PduHeaders.CC);
- }
-
- /**
- * Set "CC" value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setCc(EncodedStringValue[] value) {
- mPduHeaders.setEncodedStringValues(value, PduHeaders.CC);
- }
-
- /**
- * Get Content-type value.
- *
- * @return the value
- */
- public byte[] getContentType() {
- return mPduHeaders.getTextString(PduHeaders.CONTENT_TYPE);
- }
-
- /**
- * Set Content-type value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setContentType(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.CONTENT_TYPE);
- }
-
- /**
- * Get X-Mms-Delivery-Report value.
- *
- * @return the value
- */
- public int getDeliveryReport() {
- return mPduHeaders.getOctet(PduHeaders.DELIVERY_REPORT);
- }
-
- /**
- * Set X-Mms-Delivery-Report value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setDeliveryReport(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.DELIVERY_REPORT);
- }
-
- /**
- * Get X-Mms-Expiry value.
- *
- * Expiry-value = Value-length
- * (Absolute-token Date-value | Relative-token Delta-seconds-value)
- *
- * @return the value
- */
- public long getExpiry() {
- return mPduHeaders.getLongInteger(PduHeaders.EXPIRY);
- }
-
- /**
- * Set X-Mms-Expiry value.
- *
- * @param value the value
- */
- public void setExpiry(long value) {
- mPduHeaders.setLongInteger(value, PduHeaders.EXPIRY);
- }
-
- /**
- * Get X-Mms-MessageSize value.
- *
- * Expiry-value = size of message
- *
- * @return the value
- */
- public long getMessageSize() {
- return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE);
- }
-
- /**
- * Set X-Mms-MessageSize value.
- *
- * @param value the value
- */
- public void setMessageSize(long value) {
- mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE);
- }
-
- /**
- * Get X-Mms-Message-Class value.
- * Message-class-value = Class-identifier | Token-text
- * Class-identifier = Personal | Advertisement | Informational | Auto
- *
- * @return the value
- */
- public byte[] getMessageClass() {
- return mPduHeaders.getTextString(PduHeaders.MESSAGE_CLASS);
- }
-
- /**
- * Set X-Mms-Message-Class value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setMessageClass(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.MESSAGE_CLASS);
- }
-
- /**
- * Get X-Mms-Read-Report value.
- *
- * @return the value
- */
- public int getReadReport() {
- return mPduHeaders.getOctet(PduHeaders.READ_REPORT);
- }
-
- /**
- * Set X-Mms-Read-Report value.
- *
- * @param value the value
- * @throws InvalidHeaderValueException if the value is invalid.
- */
- public void setReadReport(int value) throws InvalidHeaderValueException {
- mPduHeaders.setOctet(value, PduHeaders.READ_REPORT);
- }
-
- /**
- * Set "To" value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setTo(EncodedStringValue[] value) {
- mPduHeaders.setEncodedStringValues(value, PduHeaders.TO);
- }
-
- /**
- * Get X-Mms-Transaction-Id field value.
- *
- * @return the X-Mms-Report-Allowed value
- */
- public byte[] getTransactionId() {
- return mPduHeaders.getTextString(PduHeaders.TRANSACTION_ID);
- }
-
- /**
- * Set X-Mms-Transaction-Id field value.
- *
- * @param value the value
- * @throws NullPointerException if the value is null.
- */
- public void setTransactionId(byte[] value) {
- mPduHeaders.setTextString(value, PduHeaders.TRANSACTION_ID);
- }
-
- /*
- * Optional, not supported header fields:
- *
- * public byte getAdaptationAllowed() {return 0};
- * public void setAdaptationAllowed(btye value) {};
- *
- * public byte[] getApplicId() {return null;}
- * public void setApplicId(byte[] value) {}
- *
- * public byte[] getAuxApplicId() {return null;}
- * public void getAuxApplicId(byte[] value) {}
- *
- * public byte getContentClass() {return 0x00;}
- * public void setApplicId(byte value) {}
- *
- * public long getDeliveryTime() {return 0};
- * public void setDeliveryTime(long value) {};
- *
- * public byte getDrmContent() {return 0x00;}
- * public void setDrmContent(byte value) {}
- *
- * public MmFlagsValue getMmFlags() {return null;}
- * public void setMmFlags(MmFlagsValue value) {}
- *
- * public MmStateValue getMmState() {return null;}
- * public void getMmState(MmStateValue value) {}
- *
- * public byte[] getReplyApplicId() {return 0x00;}
- * public void setReplyApplicId(byte[] value) {}
- *
- * public byte getReplyCharging() {return 0x00;}
- * public void setReplyCharging(byte value) {}
- *
- * public byte getReplyChargingDeadline() {return 0x00;}
- * public void setReplyChargingDeadline(byte value) {}
- *
- * public byte[] getReplyChargingId() {return 0x00;}
- * public void setReplyChargingId(byte[] value) {}
- *
- * public long getReplyChargingSize() {return 0;}
- * public void setReplyChargingSize(long value) {}
- *
- * public byte[] getReplyApplicId() {return 0x00;}
- * public void setReplyApplicId(byte[] value) {}
- *
- * public byte getStore() {return 0x00;}
- * public void setStore(byte value) {}
- */
-}
diff --git a/core/java/com/google/android/mms/pdu/package.html b/core/java/com/google/android/mms/pdu/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/pdu/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/com/google/android/mms/util/AbstractCache.java b/core/java/com/google/android/mms/util/AbstractCache.java
deleted file mode 100644
index 39b2abf..0000000
--- a/core/java/com/google/android/mms/util/AbstractCache.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.util;
-
-import android.util.Log;
-
-import java.util.HashMap;
-
-public abstract class AbstractCache<K, V> {
- private static final String TAG = "AbstractCache";
- private static final boolean DEBUG = false;
- private static final boolean LOCAL_LOGV = false;
-
- private static final int MAX_CACHED_ITEMS = 500;
-
- private final HashMap<K, CacheEntry<V>> mCacheMap;
-
- protected AbstractCache() {
- mCacheMap = new HashMap<K, CacheEntry<V>>();
- }
-
- public boolean put(K key, V value) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "Trying to put " + key + " into cache.");
- }
-
- if (mCacheMap.size() >= MAX_CACHED_ITEMS) {
- // TODO Should remove the oldest or least hit cached entry
- // and then cache the new one.
- if (LOCAL_LOGV) {
- Log.v(TAG, "Failed! size limitation reached.");
- }
- return false;
- }
-
- if (key != null) {
- CacheEntry<V> cacheEntry = new CacheEntry<V>();
- cacheEntry.value = value;
- mCacheMap.put(key, cacheEntry);
-
- if (LOCAL_LOGV) {
- Log.v(TAG, key + " cached, " + mCacheMap.size() + " items total.");
- }
- return true;
- }
- return false;
- }
-
- public V get(K key) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "Trying to get " + key + " from cache.");
- }
-
- if (key != null) {
- CacheEntry<V> cacheEntry = mCacheMap.get(key);
- if (cacheEntry != null) {
- cacheEntry.hit++;
- if (LOCAL_LOGV) {
- Log.v(TAG, key + " hit " + cacheEntry.hit + " times.");
- }
- return cacheEntry.value;
- }
- }
- return null;
- }
-
- public V purge(K key) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "Trying to purge " + key);
- }
-
- CacheEntry<V> v = mCacheMap.remove(key);
-
- if (LOCAL_LOGV) {
- Log.v(TAG, mCacheMap.size() + " items cached.");
- }
-
- return v != null ? v.value : null;
- }
-
- public void purgeAll() {
- if (LOCAL_LOGV) {
- Log.v(TAG, "Purging cache, " + mCacheMap.size()
- + " items dropped.");
- }
- mCacheMap.clear();
- }
-
- public int size() {
- return mCacheMap.size();
- }
-
- private static class CacheEntry<V> {
- int hit;
- V value;
- }
-}
diff --git a/core/java/com/google/android/mms/util/DownloadDrmHelper.java b/core/java/com/google/android/mms/util/DownloadDrmHelper.java
deleted file mode 100644
index 6852eca..0000000
--- a/core/java/com/google/android/mms/util/DownloadDrmHelper.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package com.google.android.mms.util;
-
-import android.content.Context;
-import android.drm.DrmManagerClient;
-import android.util.Log;
-
-public class DownloadDrmHelper {
- private static final String TAG = "DownloadDrmHelper";
-
- /** The MIME type of special DRM files */
- public static final String MIMETYPE_DRM_MESSAGE = "application/vnd.oma.drm.message";
-
- /** The extensions of special DRM files */
- public static final String EXTENSION_DRM_MESSAGE = ".dm";
-
- public static final String EXTENSION_INTERNAL_FWDL = ".fl";
-
- /**
- * Checks if the Media Type is a DRM Media Type
- *
- * @param drmManagerClient A DrmManagerClient
- * @param mimetype Media Type to check
- * @return True if the Media Type is DRM else false
- */
- public static boolean isDrmMimeType(Context context, String mimetype) {
- boolean result = false;
- if (context != null) {
- try {
- DrmManagerClient drmClient = new DrmManagerClient(context);
- if (drmClient != null && mimetype != null && mimetype.length() > 0) {
- result = drmClient.canHandle("", mimetype);
- }
- } catch (IllegalArgumentException e) {
- Log.w(TAG,
- "DrmManagerClient instance could not be created, context is Illegal.");
- } catch (IllegalStateException e) {
- Log.w(TAG, "DrmManagerClient didn't initialize properly.");
- }
- }
- return result;
- }
-
- /**
- * Checks if the Media Type needs to be DRM converted
- *
- * @param mimetype Media type of the content
- * @return True if convert is needed else false
- */
- public static boolean isDrmConvertNeeded(String mimetype) {
- return MIMETYPE_DRM_MESSAGE.equals(mimetype);
- }
-
- /**
- * Modifies the file extension for a DRM Forward Lock file NOTE: This
- * function shouldn't be called if the file shouldn't be DRM converted
- */
- public static String modifyDrmFwLockFileExtension(String filename) {
- if (filename != null) {
- int extensionIndex;
- extensionIndex = filename.lastIndexOf(".");
- if (extensionIndex != -1) {
- filename = filename.substring(0, extensionIndex);
- }
- filename = filename.concat(EXTENSION_INTERNAL_FWDL);
- }
- return filename;
- }
-
- /**
- * Gets the original mime type of DRM protected content.
- *
- * @param context The context
- * @param path Path to the file
- * @param containingMime The current mime type of of the file i.e. the
- * containing mime type
- * @return The original mime type of the file if DRM protected else the
- * currentMime
- */
- public static String getOriginalMimeType(Context context, String path, String containingMime) {
- String result = containingMime;
- DrmManagerClient drmClient = new DrmManagerClient(context);
- try {
- if (drmClient.canHandle(path, null)) {
- result = drmClient.getOriginalMimeType(path);
- }
- } catch (IllegalArgumentException ex) {
- Log.w(TAG,
- "Can't get original mime type since path is null or empty string.");
- } catch (IllegalStateException ex) {
- Log.w(TAG, "DrmManagerClient didn't initialize properly.");
- }
- return result;
- }
-}
diff --git a/core/java/com/google/android/mms/util/DrmConvertSession.java b/core/java/com/google/android/mms/util/DrmConvertSession.java
deleted file mode 100644
index 2d8f274..0000000
--- a/core/java/com/google/android/mms/util/DrmConvertSession.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package com.google.android.mms.util;
-
-import android.content.Context;
-import android.drm.DrmConvertedStatus;
-import android.drm.DrmManagerClient;
-import android.util.Log;
-import android.provider.Downloads;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-
-
-public class DrmConvertSession {
- private DrmManagerClient mDrmClient;
- private int mConvertSessionId;
- private static final String TAG = "DrmConvertSession";
-
- private DrmConvertSession(DrmManagerClient drmClient, int convertSessionId) {
- mDrmClient = drmClient;
- mConvertSessionId = convertSessionId;
- }
-
- /**
- * Start of converting a file.
- *
- * @param context The context of the application running the convert session.
- * @param mimeType Mimetype of content that shall be converted.
- * @return A convert session or null in case an error occurs.
- */
- public static DrmConvertSession open(Context context, String mimeType) {
- DrmManagerClient drmClient = null;
- int convertSessionId = -1;
- if (context != null && mimeType != null && !mimeType.equals("")) {
- try {
- drmClient = new DrmManagerClient(context);
- try {
- convertSessionId = drmClient.openConvertSession(mimeType);
- } catch (IllegalArgumentException e) {
- Log.w(TAG, "Conversion of Mimetype: " + mimeType
- + " is not supported.", e);
- } catch (IllegalStateException e) {
- Log.w(TAG, "Could not access Open DrmFramework.", e);
- }
- } catch (IllegalArgumentException e) {
- Log.w(TAG,
- "DrmManagerClient instance could not be created, context is Illegal.");
- } catch (IllegalStateException e) {
- Log.w(TAG, "DrmManagerClient didn't initialize properly.");
- }
- }
-
- if (drmClient == null || convertSessionId < 0) {
- return null;
- } else {
- return new DrmConvertSession(drmClient, convertSessionId);
- }
- }
- /**
- * Convert a buffer of data to protected format.
- *
- * @param buffer Buffer filled with data to convert.
- * @param size The number of bytes that shall be converted.
- * @return A Buffer filled with converted data, if execution is ok, in all
- * other case null.
- */
- public byte [] convert(byte[] inBuffer, int size) {
- byte[] result = null;
- if (inBuffer != null) {
- DrmConvertedStatus convertedStatus = null;
- try {
- if (size != inBuffer.length) {
- byte[] buf = new byte[size];
- System.arraycopy(inBuffer, 0, buf, 0, size);
- convertedStatus = mDrmClient.convertData(mConvertSessionId, buf);
- } else {
- convertedStatus = mDrmClient.convertData(mConvertSessionId, inBuffer);
- }
-
- if (convertedStatus != null &&
- convertedStatus.statusCode == DrmConvertedStatus.STATUS_OK &&
- convertedStatus.convertedData != null) {
- result = convertedStatus.convertedData;
- }
- } catch (IllegalArgumentException e) {
- Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: "
- + mConvertSessionId, e);
- } catch (IllegalStateException e) {
- Log.w(TAG, "Could not convert data. Convertsession: " +
- mConvertSessionId, e);
- }
- } else {
- throw new IllegalArgumentException("Parameter inBuffer is null");
- }
- return result;
- }
-
- /**
- * Ends a conversion session of a file.
- *
- * @param fileName The filename of the converted file.
- * @return Downloads.Impl.STATUS_SUCCESS if execution is ok.
- * Downloads.Impl.STATUS_FILE_ERROR in case converted file can not
- * be accessed. Downloads.Impl.STATUS_NOT_ACCEPTABLE if a problem
- * occurs when accessing drm framework.
- * Downloads.Impl.STATUS_UNKNOWN_ERROR if a general error occurred.
- */
- public int close(String filename) {
- DrmConvertedStatus convertedStatus = null;
- int result = Downloads.Impl.STATUS_UNKNOWN_ERROR;
- if (mDrmClient != null && mConvertSessionId >= 0) {
- try {
- convertedStatus = mDrmClient.closeConvertSession(mConvertSessionId);
- if (convertedStatus == null ||
- convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
- convertedStatus.convertedData == null) {
- result = Downloads.Impl.STATUS_NOT_ACCEPTABLE;
- } else {
- RandomAccessFile rndAccessFile = null;
- try {
- rndAccessFile = new RandomAccessFile(filename, "rw");
- rndAccessFile.seek(convertedStatus.offset);
- rndAccessFile.write(convertedStatus.convertedData);
- result = Downloads.Impl.STATUS_SUCCESS;
- } catch (FileNotFoundException e) {
- result = Downloads.Impl.STATUS_FILE_ERROR;
- Log.w(TAG, "File: " + filename + " could not be found.", e);
- } catch (IOException e) {
- result = Downloads.Impl.STATUS_FILE_ERROR;
- Log.w(TAG, "Could not access File: " + filename + " .", e);
- } catch (IllegalArgumentException e) {
- result = Downloads.Impl.STATUS_FILE_ERROR;
- Log.w(TAG, "Could not open file in mode: rw", e);
- } catch (SecurityException e) {
- Log.w(TAG, "Access to File: " + filename +
- " was denied denied by SecurityManager.", e);
- } finally {
- if (rndAccessFile != null) {
- try {
- rndAccessFile.close();
- } catch (IOException e) {
- result = Downloads.Impl.STATUS_FILE_ERROR;
- Log.w(TAG, "Failed to close File:" + filename
- + ".", e);
- }
- }
- }
- }
- } catch (IllegalStateException e) {
- Log.w(TAG, "Could not close convertsession. Convertsession: " +
- mConvertSessionId, e);
- }
- }
- return result;
- }
-}
diff --git a/core/java/com/google/android/mms/util/PduCache.java b/core/java/com/google/android/mms/util/PduCache.java
deleted file mode 100644
index de83124..0000000
--- a/core/java/com/google/android/mms/util/PduCache.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.util;
-
-import android.content.ContentUris;
-import android.content.UriMatcher;
-import android.net.Uri;
-import android.provider.Telephony.Mms;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.HashSet;
-
-public final class PduCache extends AbstractCache<Uri, PduCacheEntry> {
- private static final String TAG = "PduCache";
- private static final boolean DEBUG = false;
- private static final boolean LOCAL_LOGV = false;
-
- private static final int MMS_ALL = 0;
- private static final int MMS_ALL_ID = 1;
- private static final int MMS_INBOX = 2;
- private static final int MMS_INBOX_ID = 3;
- private static final int MMS_SENT = 4;
- private static final int MMS_SENT_ID = 5;
- private static final int MMS_DRAFTS = 6;
- private static final int MMS_DRAFTS_ID = 7;
- private static final int MMS_OUTBOX = 8;
- private static final int MMS_OUTBOX_ID = 9;
- private static final int MMS_CONVERSATION = 10;
- private static final int MMS_CONVERSATION_ID = 11;
-
- private static final UriMatcher URI_MATCHER;
- private static final HashMap<Integer, Integer> MATCH_TO_MSGBOX_ID_MAP;
-
- private static PduCache sInstance;
-
- static {
- URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
- URI_MATCHER.addURI("mms", null, MMS_ALL);
- URI_MATCHER.addURI("mms", "#", MMS_ALL_ID);
- URI_MATCHER.addURI("mms", "inbox", MMS_INBOX);
- URI_MATCHER.addURI("mms", "inbox/#", MMS_INBOX_ID);
- URI_MATCHER.addURI("mms", "sent", MMS_SENT);
- URI_MATCHER.addURI("mms", "sent/#", MMS_SENT_ID);
- URI_MATCHER.addURI("mms", "drafts", MMS_DRAFTS);
- URI_MATCHER.addURI("mms", "drafts/#", MMS_DRAFTS_ID);
- URI_MATCHER.addURI("mms", "outbox", MMS_OUTBOX);
- URI_MATCHER.addURI("mms", "outbox/#", MMS_OUTBOX_ID);
- URI_MATCHER.addURI("mms-sms", "conversations", MMS_CONVERSATION);
- URI_MATCHER.addURI("mms-sms", "conversations/#", MMS_CONVERSATION_ID);
-
- MATCH_TO_MSGBOX_ID_MAP = new HashMap<Integer, Integer>();
- MATCH_TO_MSGBOX_ID_MAP.put(MMS_INBOX, Mms.MESSAGE_BOX_INBOX);
- MATCH_TO_MSGBOX_ID_MAP.put(MMS_SENT, Mms.MESSAGE_BOX_SENT);
- MATCH_TO_MSGBOX_ID_MAP.put(MMS_DRAFTS, Mms.MESSAGE_BOX_DRAFTS);
- MATCH_TO_MSGBOX_ID_MAP.put(MMS_OUTBOX, Mms.MESSAGE_BOX_OUTBOX);
- }
-
- private final HashMap<Integer, HashSet<Uri>> mMessageBoxes;
- private final HashMap<Long, HashSet<Uri>> mThreads;
- private final HashSet<Uri> mUpdating;
-
- private PduCache() {
- mMessageBoxes = new HashMap<Integer, HashSet<Uri>>();
- mThreads = new HashMap<Long, HashSet<Uri>>();
- mUpdating = new HashSet<Uri>();
- }
-
- synchronized public static final PduCache getInstance() {
- if (sInstance == null) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "Constructing new PduCache instance.");
- }
- sInstance = new PduCache();
- }
- return sInstance;
- }
-
- @Override
- synchronized public boolean put(Uri uri, PduCacheEntry entry) {
- int msgBoxId = entry.getMessageBox();
- HashSet<Uri> msgBox = mMessageBoxes.get(msgBoxId);
- if (msgBox == null) {
- msgBox = new HashSet<Uri>();
- mMessageBoxes.put(msgBoxId, msgBox);
- }
-
- long threadId = entry.getThreadId();
- HashSet<Uri> thread = mThreads.get(threadId);
- if (thread == null) {
- thread = new HashSet<Uri>();
- mThreads.put(threadId, thread);
- }
-
- Uri finalKey = normalizeKey(uri);
- boolean result = super.put(finalKey, entry);
- if (result) {
- msgBox.add(finalKey);
- thread.add(finalKey);
- }
- setUpdating(uri, false);
- return result;
- }
-
- synchronized public void setUpdating(Uri uri, boolean updating) {
- if (updating) {
- mUpdating.add(uri);
- } else {
- mUpdating.remove(uri);
- }
- }
-
- synchronized public boolean isUpdating(Uri uri) {
- return mUpdating.contains(uri);
- }
-
- @Override
- synchronized public PduCacheEntry purge(Uri uri) {
- int match = URI_MATCHER.match(uri);
- switch (match) {
- case MMS_ALL_ID:
- return purgeSingleEntry(uri);
- case MMS_INBOX_ID:
- case MMS_SENT_ID:
- case MMS_DRAFTS_ID:
- case MMS_OUTBOX_ID:
- String msgId = uri.getLastPathSegment();
- return purgeSingleEntry(Uri.withAppendedPath(Mms.CONTENT_URI, msgId));
- // Implicit batch of purge, return null.
- case MMS_ALL:
- case MMS_CONVERSATION:
- purgeAll();
- return null;
- case MMS_INBOX:
- case MMS_SENT:
- case MMS_DRAFTS:
- case MMS_OUTBOX:
- purgeByMessageBox(MATCH_TO_MSGBOX_ID_MAP.get(match));
- return null;
- case MMS_CONVERSATION_ID:
- purgeByThreadId(ContentUris.parseId(uri));
- return null;
- default:
- return null;
- }
- }
-
- private PduCacheEntry purgeSingleEntry(Uri key) {
- mUpdating.remove(key);
- PduCacheEntry entry = super.purge(key);
- if (entry != null) {
- removeFromThreads(key, entry);
- removeFromMessageBoxes(key, entry);
- return entry;
- }
- return null;
- }
-
- @Override
- synchronized public void purgeAll() {
- super.purgeAll();
-
- mMessageBoxes.clear();
- mThreads.clear();
- mUpdating.clear();
- }
-
- /**
- * @param uri The Uri to be normalized.
- * @return Uri The normalized key of cached entry.
- */
- private Uri normalizeKey(Uri uri) {
- int match = URI_MATCHER.match(uri);
- Uri normalizedKey = null;
-
- switch (match) {
- case MMS_ALL_ID:
- normalizedKey = uri;
- break;
- case MMS_INBOX_ID:
- case MMS_SENT_ID:
- case MMS_DRAFTS_ID:
- case MMS_OUTBOX_ID:
- String msgId = uri.getLastPathSegment();
- normalizedKey = Uri.withAppendedPath(Mms.CONTENT_URI, msgId);
- break;
- default:
- return null;
- }
-
- if (LOCAL_LOGV) {
- Log.v(TAG, uri + " -> " + normalizedKey);
- }
- return normalizedKey;
- }
-
- private void purgeByMessageBox(Integer msgBoxId) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "Purge cache in message box: " + msgBoxId);
- }
-
- if (msgBoxId != null) {
- HashSet<Uri> msgBox = mMessageBoxes.remove(msgBoxId);
- if (msgBox != null) {
- for (Uri key : msgBox) {
- mUpdating.remove(key);
- PduCacheEntry entry = super.purge(key);
- if (entry != null) {
- removeFromThreads(key, entry);
- }
- }
- }
- }
- }
-
- private void removeFromThreads(Uri key, PduCacheEntry entry) {
- HashSet<Uri> thread = mThreads.get(entry.getThreadId());
- if (thread != null) {
- thread.remove(key);
- }
- }
-
- private void purgeByThreadId(long threadId) {
- if (LOCAL_LOGV) {
- Log.v(TAG, "Purge cache in thread: " + threadId);
- }
-
- HashSet<Uri> thread = mThreads.remove(threadId);
- if (thread != null) {
- for (Uri key : thread) {
- mUpdating.remove(key);
- PduCacheEntry entry = super.purge(key);
- if (entry != null) {
- removeFromMessageBoxes(key, entry);
- }
- }
- }
- }
-
- private void removeFromMessageBoxes(Uri key, PduCacheEntry entry) {
- HashSet<Uri> msgBox = mThreads.get(Long.valueOf(entry.getMessageBox()));
- if (msgBox != null) {
- msgBox.remove(key);
- }
- }
-}
diff --git a/core/java/com/google/android/mms/util/PduCacheEntry.java b/core/java/com/google/android/mms/util/PduCacheEntry.java
deleted file mode 100644
index 8b41386..0000000
--- a/core/java/com/google/android/mms/util/PduCacheEntry.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.util;
-
-import com.google.android.mms.pdu.GenericPdu;
-
-public final class PduCacheEntry {
- private final GenericPdu mPdu;
- private final int mMessageBox;
- private final long mThreadId;
-
- public PduCacheEntry(GenericPdu pdu, int msgBox, long threadId) {
- mPdu = pdu;
- mMessageBox = msgBox;
- mThreadId = threadId;
- }
-
- public GenericPdu getPdu() {
- return mPdu;
- }
-
- public int getMessageBox() {
- return mMessageBox;
- }
-
- public long getThreadId() {
- return mThreadId;
- }
-}
diff --git a/core/java/com/google/android/mms/util/SqliteWrapper.java b/core/java/com/google/android/mms/util/SqliteWrapper.java
deleted file mode 100644
index bcdac22..0000000
--- a/core/java/com/google/android/mms/util/SqliteWrapper.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2008 Esmertec AG.
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.mms.util;
-
-import android.app.ActivityManager;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.net.Uri;
-import android.util.Log;
-import android.widget.Toast;
-
-public final class SqliteWrapper {
- private static final String TAG = "SqliteWrapper";
- private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE
- = "unable to open database file";
-
- private SqliteWrapper() {
- // Forbidden being instantiated.
- }
-
- // FIXME: It looks like outInfo.lowMemory does not work well as we expected.
- // after run command: adb shell fillup -p 100, outInfo.lowMemory is still false.
- private static boolean isLowMemory(Context context) {
- if (null == context) {
- return false;
- }
-
- ActivityManager am = (ActivityManager)
- context.getSystemService(Context.ACTIVITY_SERVICE);
- ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
- am.getMemoryInfo(outInfo);
-
- return outInfo.lowMemory;
- }
-
- // FIXME: need to optimize this method.
- private static boolean isLowMemory(SQLiteException e) {
- return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE);
- }
-
- public static void checkSQLiteException(Context context, SQLiteException e) {
- if (isLowMemory(e)) {
- Toast.makeText(context, com.android.internal.R.string.low_memory,
- Toast.LENGTH_SHORT).show();
- } else {
- throw e;
- }
- }
-
- public static Cursor query(Context context, ContentResolver resolver, Uri uri,
- String[] projection, String selection, String[] selectionArgs, String sortOrder) {
- try {
- return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
- } catch (SQLiteException e) {
- Log.e(TAG, "Catch a SQLiteException when query: ", e);
- checkSQLiteException(context, e);
- return null;
- }
- }
-
- public static boolean requery(Context context, Cursor cursor) {
- try {
- return cursor.requery();
- } catch (SQLiteException e) {
- Log.e(TAG, "Catch a SQLiteException when requery: ", e);
- checkSQLiteException(context, e);
- return false;
- }
- }
- public static int update(Context context, ContentResolver resolver, Uri uri,
- ContentValues values, String where, String[] selectionArgs) {
- try {
- return resolver.update(uri, values, where, selectionArgs);
- } catch (SQLiteException e) {
- Log.e(TAG, "Catch a SQLiteException when update: ", e);
- checkSQLiteException(context, e);
- return -1;
- }
- }
-
- public static int delete(Context context, ContentResolver resolver, Uri uri,
- String where, String[] selectionArgs) {
- try {
- return resolver.delete(uri, where, selectionArgs);
- } catch (SQLiteException e) {
- Log.e(TAG, "Catch a SQLiteException when delete: ", e);
- checkSQLiteException(context, e);
- return -1;
- }
- }
-
- public static Uri insert(Context context, ContentResolver resolver,
- Uri uri, ContentValues values) {
- try {
- return resolver.insert(uri, values);
- } catch (SQLiteException e) {
- Log.e(TAG, "Catch a SQLiteException when insert: ", e);
- checkSQLiteException(context, e);
- return null;
- }
- }
-}
diff --git a/core/java/com/google/android/mms/util/package.html b/core/java/com/google/android/mms/util/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/com/google/android/mms/util/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index c24f6c6..6f3653d 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -66,7 +66,7 @@
android_os_MessageQueue.cpp \
android_os_ParcelFileDescriptor.cpp \
android_os_Parcel.cpp \
- android_os_StatFs.cpp \
+ android_os_SELinux.cpp \
android_os_SystemClock.cpp \
android_os_SystemProperties.cpp \
android_os_Trace.cpp \
@@ -218,6 +218,12 @@
libharfbuzz \
libz
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_C_INCLUDES += external/libselinux/include
+LOCAL_SHARED_LIBRARIES += libselinux
+LOCAL_CFLAGS += -DHAVE_SELINUX
+endif # HAVE_SELINUX
+
ifeq ($(USE_OPENGL_RENDERER),true)
LOCAL_SHARED_LIBRARIES += libhwui
endif
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 241a905..d08e651 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -133,7 +133,7 @@
extern int register_android_os_MessageQueue(JNIEnv* env);
extern int register_android_os_Parcel(JNIEnv* env);
extern int register_android_os_ParcelFileDescriptor(JNIEnv *env);
-extern int register_android_os_StatFs(JNIEnv *env);
+extern int register_android_os_SELinux(JNIEnv* env);
extern int register_android_os_SystemProperties(JNIEnv *env);
extern int register_android_os_SystemClock(JNIEnv* env);
extern int register_android_os_Trace(JNIEnv* env);
@@ -1146,7 +1146,7 @@
REG_JNI(register_android_os_FileUtils),
REG_JNI(register_android_os_MessageQueue),
REG_JNI(register_android_os_ParcelFileDescriptor),
- REG_JNI(register_android_os_StatFs),
+ REG_JNI(register_android_os_SELinux),
REG_JNI(register_android_os_Trace),
REG_JNI(register_android_os_UEventObserver),
REG_JNI(register_android_net_LocalSocketImpl),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 3c27caf..1bba5b4 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -298,8 +298,18 @@
}
bool success = false;
- SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
- if (NULL != strm) {
+ if (NULL != bitmap) {
+ SkAutoLockPixels alp(*bitmap);
+
+ if (NULL == bitmap->getPixels()) {
+ return false;
+ }
+
+ SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
+ if (NULL == strm) {
+ return false;
+ }
+
SkImageEncoder* encoder = SkImageEncoder::Create(fm);
if (NULL != encoder) {
success = encoder->encodeStream(strm, *bitmap, quality);
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
index 6ce3f51..aa4cbde 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -164,7 +164,7 @@
RETURN_NULL_IF_NULL(gInputStream_resetMethodID);
RETURN_NULL_IF_NULL(gInputStream_markMethodID);
RETURN_NULL_IF_NULL(gInputStream_availableMethodID);
- RETURN_NULL_IF_NULL(gInputStream_availableMethodID);
+ RETURN_NULL_IF_NULL(gInputStream_readMethodID);
RETURN_NULL_IF_NULL(gInputStream_skipMethodID);
gInited = true;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 8f68ae3..315f2d5 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -751,7 +751,7 @@
static void doTextBounds(JNIEnv* env, const jchar* text, int count,
jobject bounds, const SkPaint& paint)
{
- SkRect r;
+ SkRect r{0,0,0,0};
SkIRect ir;
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp
index 8d65cbc..a07f5b7 100644
--- a/core/jni/android_os_FileUtils.cpp
+++ b/core/jni/android_os_FileUtils.cpp
@@ -33,19 +33,6 @@
namespace android {
-static jfieldID gFileStatusDevFieldID;
-static jfieldID gFileStatusInoFieldID;
-static jfieldID gFileStatusModeFieldID;
-static jfieldID gFileStatusNlinkFieldID;
-static jfieldID gFileStatusUidFieldID;
-static jfieldID gFileStatusGidFieldID;
-static jfieldID gFileStatusSizeFieldID;
-static jfieldID gFileStatusBlksizeFieldID;
-static jfieldID gFileStatusBlocksFieldID;
-static jfieldID gFileStatusAtimeFieldID;
-static jfieldID gFileStatusMtimeFieldID;
-static jfieldID gFileStatusCtimeFieldID;
-
jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
jstring file, jint mode,
jint uid, jint gid)
@@ -68,44 +55,6 @@
return chmod(file8.string(), mode) == 0 ? 0 : errno;
}
-jint android_os_FileUtils_getPermissions(JNIEnv* env, jobject clazz,
- jstring file, jintArray outArray)
-{
- const jchar* str = env->GetStringCritical(file, 0);
- String8 file8;
- if (str) {
- file8 = String8(str, env->GetStringLength(file));
- env->ReleaseStringCritical(file, str);
- }
- if (file8.size() <= 0) {
- return ENOENT;
- }
- struct stat st;
- if (stat(file8.string(), &st) != 0) {
- return errno;
- }
- jint* array = (jint*)env->GetPrimitiveArrayCritical(outArray, 0);
- if (array) {
- int len = env->GetArrayLength(outArray);
- if (len >= 1) {
- array[0] = st.st_mode;
- }
- if (len >= 2) {
- array[1] = st.st_uid;
- }
- if (len >= 3) {
- array[2] = st.st_gid;
- }
- }
- env->ReleasePrimitiveArrayCritical(outArray, array, 0);
- return 0;
-}
-
-jint android_os_FileUtils_setUMask(JNIEnv* env, jobject clazz, jint mask)
-{
- return umask(mask);
-}
-
jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path)
{
if (path == NULL) {
@@ -127,63 +76,15 @@
return result;
}
-jboolean android_os_FileUtils_getFileStatus(JNIEnv* env, jobject clazz, jstring path, jobject fileStatus) {
- const char* pathStr = env->GetStringUTFChars(path, NULL);
- jboolean ret = false;
-
- struct stat s;
- int res = stat(pathStr, &s);
- if (res == 0) {
- ret = true;
- if (fileStatus != NULL) {
- env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev);
- env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino);
- env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode);
- env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink);
- env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid);
- env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid);
- env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size);
- env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize);
- env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks);
- env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime);
- env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
- env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
- }
- }
-
- env->ReleaseStringUTFChars(path, pathStr);
-
- return ret;
-}
-
static const JNINativeMethod methods[] = {
{"setPermissions", "(Ljava/lang/String;III)I", (void*)android_os_FileUtils_setPermissions},
- {"getPermissions", "(Ljava/lang/String;[I)I", (void*)android_os_FileUtils_getPermissions},
- {"setUMask", "(I)I", (void*)android_os_FileUtils_setUMask},
{"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId},
- {"getFileStatusNative", "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z", (void*)android_os_FileUtils_getFileStatus},
};
static const char* const kFileUtilsPathName = "android/os/FileUtils";
int register_android_os_FileUtils(JNIEnv* env)
{
- jclass fileStatusClass = env->FindClass("android/os/FileUtils$FileStatus");
- LOG_FATAL_IF(fileStatusClass == NULL, "Unable to find class android.os.FileUtils$FileStatus");
-
- gFileStatusDevFieldID = env->GetFieldID(fileStatusClass, "dev", "I");
- gFileStatusInoFieldID = env->GetFieldID(fileStatusClass, "ino", "I");
- gFileStatusModeFieldID = env->GetFieldID(fileStatusClass, "mode", "I");
- gFileStatusNlinkFieldID = env->GetFieldID(fileStatusClass, "nlink", "I");
- gFileStatusUidFieldID = env->GetFieldID(fileStatusClass, "uid", "I");
- gFileStatusGidFieldID = env->GetFieldID(fileStatusClass, "gid", "I");
- gFileStatusSizeFieldID = env->GetFieldID(fileStatusClass, "size", "J");
- gFileStatusBlksizeFieldID = env->GetFieldID(fileStatusClass, "blksize", "I");
- gFileStatusBlocksFieldID = env->GetFieldID(fileStatusClass, "blocks", "J");
- gFileStatusAtimeFieldID = env->GetFieldID(fileStatusClass, "atime", "J");
- gFileStatusMtimeFieldID = env->GetFieldID(fileStatusClass, "mtime", "J");
- gFileStatusCtimeFieldID = env->GetFieldID(fileStatusClass, "ctime", "J");
-
return AndroidRuntime::registerNativeMethods(
env, kFileUtilsPathName,
methods, NELEM(methods));
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
new file mode 100644
index 0000000..e813c38
--- /dev/null
+++ b/core/jni/android_os_SELinux.cpp
@@ -0,0 +1,541 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SELinuxJNI"
+#include <utils/Log.h>
+
+#include "JNIHelp.h"
+#include "jni.h"
+#include "android_runtime/AndroidRuntime.h"
+#ifdef HAVE_SELINUX
+#include "selinux/selinux.h"
+#include "selinux/android.h"
+#endif
+#include <errno.h>
+
+namespace android {
+
+ static jboolean isSELinuxDisabled = true;
+
+ static void throw_NullPointerException(JNIEnv *env, const char* msg) {
+ jclass clazz;
+ clazz = env->FindClass("java/lang/NullPointerException");
+ env->ThrowNew(clazz, msg);
+ }
+
+ /*
+ * Function: isSELinuxEnabled
+ * Purpose: checks whether SELinux is enabled/disbaled
+ * Parameters: none
+ * Return value : true (enabled) or false (disabled)
+ * Exceptions: none
+ */
+ static jboolean isSELinuxEnabled(JNIEnv *env, jobject classz) {
+
+ return !isSELinuxDisabled;
+ }
+
+ /*
+ * Function: isSELinuxEnforced
+ * Purpose: return the current SELinux enforce mode
+ * Parameters: none
+ * Return value: true (enforcing) or false (permissive)
+ * Exceptions: none
+ */
+ static jboolean isSELinuxEnforced(JNIEnv *env, jobject clazz) {
+#ifdef HAVE_SELINUX
+ return (security_getenforce() == 1) ? true : false;
+#else
+ return false;
+#endif
+ }
+
+ /*
+ * Function: setSELinuxEnforce
+ * Purpose: set the SE Linux enforcing mode
+ * Parameters: true (enforcing) or false (permissive)
+ * Return value: true (success) or false (fail)
+ * Exceptions: none
+ */
+ static jboolean setSELinuxEnforce(JNIEnv *env, jobject clazz, jboolean value) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return false;
+
+ int enforce = (value) ? 1 : 0;
+
+ return (security_setenforce(enforce) != -1) ? true : false;
+#else
+ return false;
+#endif
+ }
+
+ /*
+ * Function: getPeerCon
+ * Purpose: retrieves security context of peer socket
+ * Parameters:
+ * fileDescriptor: peer socket file as a FileDescriptor object
+ * Returns: jstring representing the security_context of socket or NULL if error
+ * Exceptions: NullPointerException if fileDescriptor object is NULL
+ */
+ static jstring getPeerCon(JNIEnv *env, jobject clazz, jobject fileDescriptor) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return NULL;
+
+ if (fileDescriptor == NULL) {
+ throw_NullPointerException(env, "Trying to check security context of a null peer socket.");
+ return NULL;
+ }
+
+ security_context_t context = NULL;
+ jstring securityString = NULL;
+
+ int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+ if (env->ExceptionOccurred() != NULL) {
+ ALOGE("There was an issue with retrieving the file descriptor");
+ goto bail;
+ }
+
+ if (getpeercon(fd, &context) == -1)
+ goto bail;
+
+ ALOGV("getPeerCon: Successfully retrived context of peer socket '%s'", context);
+
+ securityString = env->NewStringUTF(context);
+
+ bail:
+ if (context != NULL)
+ freecon(context);
+
+ return securityString;
+#else
+ return NULL;
+#endif
+ }
+
+ /*
+ * Function: setFSCreateCon
+ * Purpose: set security context used for creating a new file system object
+ * Parameters:
+ * context: security_context_t representing the new context of a file system object,
+ * set to NULL to return to the default policy behavior
+ * Returns: true on success, false on error
+ * Exception: none
+ */
+ static jboolean setFSCreateCon(JNIEnv *env, jobject clazz, jstring context) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return false;
+
+ char * securityContext = NULL;
+ const char *constant_securityContext = NULL;
+
+ if (context != NULL) {
+ constant_securityContext = env->GetStringUTFChars(context, NULL);
+
+ // GetStringUTFChars returns const char * yet setfscreatecon needs char *
+ securityContext = const_cast<char *>(constant_securityContext);
+ }
+
+ int ret;
+ if ((ret = setfscreatecon(securityContext)) == -1)
+ goto bail;
+
+ ALOGV("setFSCreateCon: set new security context to '%s' ", context == NULL ? "default", context);
+
+ bail:
+ if (constant_securityContext != NULL)
+ env->ReleaseStringUTFChars(context, constant_securityContext);
+
+ return (ret == 0) ? true : false;
+#else
+ return false;
+#endif
+ }
+
+ /*
+ * Function: setFileCon
+ * Purpose: set the security context of a file object
+ * Parameters:
+ * path: the location of the file system object
+ * con: the new security context of the file system object
+ * Returns: true on success, false on error
+ * Exception: NullPointerException is thrown if either path or context strign are NULL
+ */
+ static jboolean setFileCon(JNIEnv *env, jobject clazz, jstring path, jstring con) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return false;
+
+ if (path == NULL) {
+ throw_NullPointerException(env, "Trying to change the security context of a NULL file object.");
+ return false;
+ }
+
+ if (con == NULL) {
+ throw_NullPointerException(env, "Trying to set the security context of a file object with NULL.");
+ return false;
+ }
+
+ const char *objectPath = env->GetStringUTFChars(path, NULL);
+ const char *constant_con = env->GetStringUTFChars(con, NULL);
+
+ // GetStringUTFChars returns const char * yet setfilecon needs char *
+ char *newCon = const_cast<char *>(constant_con);
+
+ int ret;
+ if ((ret = setfilecon(objectPath, newCon)) == -1)
+ goto bail;
+
+ ALOGV("setFileCon: Succesfully set security context '%s' for '%s'", newCon, objectPath);
+
+ bail:
+ env->ReleaseStringUTFChars(path, objectPath);
+ env->ReleaseStringUTFChars(con, constant_con);
+ return (ret == 0) ? true : false;
+#else
+ return false;
+#endif
+ }
+
+ /*
+ * Function: getFileCon
+ * Purpose: retrieves the context associated with the given path in the file system
+ * Parameters:
+ * path: given path in the file system
+ * Returns:
+ * string representing the security context string of the file object
+ * the string may be NULL if an error occured
+ * Exceptions: NullPointerException if the path object is null
+ */
+ static jstring getFileCon(JNIEnv *env, jobject clazz, jstring path) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return NULL;
+
+ if (path == NULL) {
+ throw_NullPointerException(env, "Trying to check security context of a null path.");
+ return NULL;
+ }
+
+ const char *objectPath = env->GetStringUTFChars(path, NULL);
+
+ security_context_t context = NULL;
+ jstring securityString = NULL;
+
+ if (getfilecon(objectPath, &context) == -1)
+ goto bail;
+
+ ALOGV("getFileCon: Successfully retrived context '%s' for file '%s'", context, objectPath);
+
+ securityString = env->NewStringUTF(context);
+
+ bail:
+ if (context != NULL)
+ freecon(context);
+
+ env->ReleaseStringUTFChars(path, objectPath);
+
+ return securityString;
+#else
+ return NULL;
+#endif
+ }
+
+ /*
+ * Function: getCon
+ * Purpose: Get the context of the current process.
+ * Parameters: none
+ * Returns: a jstring representing the security context of the process,
+ * the jstring may be NULL if there was an error
+ * Exceptions: none
+ */
+ static jstring getCon(JNIEnv *env, jobject clazz) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return NULL;
+
+ security_context_t context = NULL;
+ jstring securityString = NULL;
+
+ if (getcon(&context) == -1)
+ goto bail;
+
+ ALOGV("getCon: Successfully retrieved context '%s'", context);
+
+ securityString = env->NewStringUTF(context);
+
+ bail:
+ if (context != NULL)
+ freecon(context);
+
+ return securityString;
+#else
+ return NULL;
+#endif
+ }
+
+ /*
+ * Function: getPidCon
+ * Purpose: Get the context of a process identified by its pid
+ * Parameters:
+ * pid: a jint representing the process
+ * Returns: a jstring representing the security context of the pid,
+ * the jstring may be NULL if there was an error
+ * Exceptions: none
+ */
+ static jstring getPidCon(JNIEnv *env, jobject clazz, jint pid) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return NULL;
+
+ security_context_t context = NULL;
+ jstring securityString = NULL;
+
+ pid_t checkPid = (pid_t)pid;
+
+ if (getpidcon(checkPid, &context) == -1)
+ goto bail;
+
+ ALOGV("getPidCon: Successfully retrived context '%s' for pid '%d'", context, checkPid);
+
+ securityString = env->NewStringUTF(context);
+
+ bail:
+ if (context != NULL)
+ freecon(context);
+
+ return securityString;
+#else
+ return NULL;
+#endif
+ }
+
+ /*
+ * Function: getBooleanNames
+ * Purpose: Gets a list of the SELinux boolean names.
+ * Parameters: None
+ * Returns: an array of strings containing the SELinux boolean names.
+ * returns NULL string on error
+ * Exceptions: None
+ */
+ static jobjectArray getBooleanNames(JNIEnv *env, JNIEnv clazz) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return NULL;
+
+ char **list;
+ int i, len, ret;
+ jclass stringClass;
+ jobjectArray stringArray = NULL;
+
+ if (security_get_boolean_names(&list, &len) == -1)
+ return NULL;
+
+ stringClass = env->FindClass("java/lang/String");
+ stringArray = env->NewObjectArray(len, stringClass, env->NewStringUTF(""));
+ for (i = 0; i < len; i++) {
+ jstring obj;
+ obj = env->NewStringUTF(list[i]);
+ env->SetObjectArrayElement(stringArray, i, obj);
+ env->DeleteLocalRef(obj);
+ free(list[i]);
+ }
+ free(list);
+
+ return stringArray;
+#else
+ return NULL;
+#endif
+ }
+
+ /*
+ * Function: getBooleanValue
+ * Purpose: Gets the value for the given SELinux boolean name.
+ * Parameters:
+ * String: The name of the SELinux boolean.
+ * Returns: a boolean: (true) boolean is set or (false) it is not.
+ * Exceptions: None
+ */
+ static jboolean getBooleanValue(JNIEnv *env, jobject clazz, jstring name) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return false;
+
+ const char *boolean_name;
+ int ret;
+
+ if (name == NULL)
+ return false;
+ boolean_name = env->GetStringUTFChars(name, NULL);
+ ret = security_get_boolean_active(boolean_name);
+ env->ReleaseStringUTFChars(name, boolean_name);
+ return (ret == 1) ? true : false;
+#else
+ return false;
+#endif
+ }
+
+ /*
+ * Function: setBooleanNames
+ * Purpose: Sets the value for the given SELinux boolean name.
+ * Parameters:
+ * String: The name of the SELinux boolean.
+ * Boolean: The new value of the SELinux boolean.
+ * Returns: a boolean indicating whether or not the operation succeeded.
+ * Exceptions: None
+ */
+ static jboolean setBooleanValue(JNIEnv *env, jobject clazz, jstring name, jboolean value) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return false;
+
+ const char *boolean_name = NULL;
+ int ret;
+
+ if (name == NULL)
+ return false;
+ boolean_name = env->GetStringUTFChars(name, NULL);
+ ret = security_set_boolean(boolean_name, (value) ? 1 : 0);
+ env->ReleaseStringUTFChars(name, boolean_name);
+ if (ret)
+ return false;
+
+ if (security_commit_booleans() == -1)
+ return false;
+
+ return true;
+#else
+ return false;
+#endif
+ }
+
+ /*
+ * Function: checkSELinuxAccess
+ * Purpose: Check permissions between two security contexts.
+ * Parameters: scon: subject security context as a string
+ * tcon: object security context as a string
+ * tclass: object's security class name as a string
+ * perm: permission name as a string
+ * Returns: boolean: (true) if permission was granted, (false) otherwise
+ * Exceptions: None
+ */
+ static jboolean checkSELinuxAccess(JNIEnv *env, jobject clazz, jstring scon, jstring tcon, jstring tclass, jstring perm) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return true;
+
+ int accessGranted = -1;
+
+ const char *const_scon, *const_tcon, *mytclass, *myperm;
+ char *myscon, *mytcon;
+
+ if (scon == NULL || tcon == NULL || tclass == NULL || perm == NULL)
+ goto bail;
+
+ const_scon = env->GetStringUTFChars(scon, NULL);
+ const_tcon = env->GetStringUTFChars(tcon, NULL);
+ mytclass = env->GetStringUTFChars(tclass, NULL);
+ myperm = env->GetStringUTFChars(perm, NULL);
+
+ // selinux_check_access needs char* for some
+ myscon = const_cast<char *>(const_scon);
+ mytcon = const_cast<char *>(const_tcon);
+
+ accessGranted = selinux_check_access(myscon, mytcon, mytclass, myperm, NULL);
+
+ ALOGV("selinux_check_access returned %d", accessGranted);
+
+ env->ReleaseStringUTFChars(scon, const_scon);
+ env->ReleaseStringUTFChars(tcon, const_tcon);
+ env->ReleaseStringUTFChars(tclass, mytclass);
+ env->ReleaseStringUTFChars(perm, myperm);
+
+ bail:
+ return (accessGranted == 0) ? true : false;
+
+#else
+ return true;
+#endif
+ }
+
+ /*
+ * Function: native_restorecon
+ * Purpose: restore default SELinux security context
+ * Parameters: pathname: the pathname for the file to be relabeled
+ * Returns: boolean: (true) file label successfully restored, (false) otherwise
+ * Exceptions: none
+ */
+ static jboolean native_restorecon(JNIEnv *env, jobject clazz, jstring pathname) {
+#ifdef HAVE_SELINUX
+ if (isSELinuxDisabled)
+ return true;
+
+ const char *file = const_cast<char *>(env->GetStringUTFChars(pathname, NULL));
+ int ret = selinux_android_restorecon(file);
+ env->ReleaseStringUTFChars(pathname, file);
+ return (ret == 0);
+#else
+ return true;
+#endif
+ }
+
+ /*
+ * JNI registration.
+ */
+ static JNINativeMethod method_table[] = {
+
+ /* name, signature, funcPtr */
+ { "checkSELinuxAccess" , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess },
+ { "getBooleanNames" , "()[Ljava/lang/String;" , (void*)getBooleanNames },
+ { "getBooleanValue" , "(Ljava/lang/String;)Z" , (void*)getBooleanValue },
+ { "getContext" , "()Ljava/lang/String;" , (void*)getCon },
+ { "getFileContext" , "(Ljava/lang/String;)Ljava/lang/String;" , (void*)getFileCon },
+ { "getPeerContext" , "(Ljava/io/FileDescriptor;)Ljava/lang/String;" , (void*)getPeerCon },
+ { "getPidContext" , "(I)Ljava/lang/String;" , (void*)getPidCon },
+ { "isSELinuxEnforced" , "()Z" , (void*)isSELinuxEnforced},
+ { "isSELinuxEnabled" , "()Z" , (void*)isSELinuxEnabled },
+ { "native_restorecon" , "(Ljava/lang/String;)Z" , (void*)native_restorecon},
+ { "setBooleanValue" , "(Ljava/lang/String;Z)Z" , (void*)setBooleanValue },
+ { "setFileContext" , "(Ljava/lang/String;Ljava/lang/String;)Z" , (void*)setFileCon },
+ { "setFSCreateContext" , "(Ljava/lang/String;)Z" , (void*)setFSCreateCon },
+ { "setSELinuxEnforce" , "(Z)Z" , (void*)setSELinuxEnforce},
+ };
+
+ static int log_callback(int type, const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ LOG_PRI_VA(ANDROID_LOG_ERROR, "SELinux", fmt, ap);
+ va_end(ap);
+ return 0;
+ }
+
+ int register_android_os_SELinux(JNIEnv *env) {
+#ifdef HAVE_SELINUX
+ union selinux_callback cb;
+ cb.func_log = log_callback;
+ selinux_set_callback(SELINUX_CB_LOG, cb);
+
+ isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false;
+
+#endif
+ return AndroidRuntime::registerNativeMethods(
+ env, "android/os/SELinux",
+ method_table, NELEM(method_table));
+ }
+}
diff --git a/core/jni/android_os_StatFs.cpp b/core/jni/android_os_StatFs.cpp
deleted file mode 100644
index 79d8fef..0000000
--- a/core/jni/android_os_StatFs.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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
- *
- * 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.
- */
-
-#if INCLUDE_SYS_MOUNT_FOR_STATFS
-#include <sys/mount.h>
-#else
-#include <sys/statfs.h>
-#endif
-
-#include <errno.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
-
-
-namespace android
-{
-
-// ----------------------------------------------------------------------------
-
-struct fields_t {
- jfieldID context;
-};
-static fields_t fields;
-
-// ----------------------------------------------------------------------------
-
-static jint
-android_os_StatFs_getBlockSize(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- return stat->f_bsize;
-}
-
-static jint
-android_os_StatFs_getBlockCount(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- return stat->f_blocks;
-}
-
-static jint
-android_os_StatFs_getFreeBlocks(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- return stat->f_bfree;
-}
-
-static jint
-android_os_StatFs_getAvailableBlocks(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- return stat->f_bavail;
-}
-
-static void
-android_os_StatFs_native_restat(JNIEnv *env, jobject thiz, jstring path)
-{
- if (path == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- return;
- }
-
- // get the object handle
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- if (stat == NULL) {
- jniThrowException(env, "java/lang/NoSuchFieldException", NULL);
- return;
- }
-
- const char* pathstr = env->GetStringUTFChars(path, NULL);
- if (pathstr == NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
- return;
- }
-
- // note that stat will contain the new file data corresponding to
- // pathstr
- if (statfs(pathstr, stat) != 0) {
- ALOGE("statfs %s failed, errno: %d", pathstr, errno);
- delete stat;
- env->SetIntField(thiz, fields.context, 0);
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- }
- // Release pathstr
- env->ReleaseStringUTFChars(path, pathstr);
-}
-
-static void
-android_os_StatFs_native_setup(JNIEnv *env, jobject thiz, jstring path)
-{
- if (path == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- return;
- }
-
- struct statfs* stat = new struct statfs;
- if (stat == NULL) {
- jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
- return;
- }
- env->SetIntField(thiz, fields.context, (int)stat);
- android_os_StatFs_native_restat(env, thiz, path);
-}
-
-static void
-android_os_StatFs_native_finalize(JNIEnv *env, jobject thiz)
-{
- struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
- if (stat != NULL) {
- delete stat;
- env->SetIntField(thiz, fields.context, 0);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-static JNINativeMethod gMethods[] = {
- {"getBlockSize", "()I", (void *)android_os_StatFs_getBlockSize},
- {"getBlockCount", "()I", (void *)android_os_StatFs_getBlockCount},
- {"getFreeBlocks", "()I", (void *)android_os_StatFs_getFreeBlocks},
- {"getAvailableBlocks", "()I", (void *)android_os_StatFs_getAvailableBlocks},
- {"native_setup", "(Ljava/lang/String;)V", (void *)android_os_StatFs_native_setup},
- {"native_finalize", "()V", (void *)android_os_StatFs_native_finalize},
- {"native_restat", "(Ljava/lang/String;)V", (void *)android_os_StatFs_native_restat},
-};
-
-
-int register_android_os_StatFs(JNIEnv *env)
-{
- jclass clazz;
-
- clazz = env->FindClass("android/os/StatFs");
- if (clazz == NULL) {
- ALOGE("Can't find android/os/StatFs");
- return -1;
- }
-
- fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
- if (fields.context == NULL) {
- ALOGE("Can't find StatFs.mNativeContext");
- return -1;
- }
-
- return AndroidRuntime::registerNativeMethods(env,
- "android/os/StatFs", gMethods, NELEM(gMethods));
-}
-
-} // namespace android
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
index 9c18b7e..2a2dc31 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
@@ -119,6 +119,6 @@
android:drawablePadding="8dip"
android:visibility="gone"/>
- </RelativeLayout>>
+ </RelativeLayout>
</LinearLayout>
diff --git a/core/res/res/layout/transient_notification.xml b/core/res/res/layout/transient_notification.xml
index 21d58aa..5523807 100644
--- a/core/res/res/layout/transient_notification.xml
+++ b/core/res/res/layout/transient_notification.xml
@@ -29,6 +29,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
+ android:layout_gravity="center_horizontal"
android:textAppearance="@style/TextAppearance.Small"
android:textColor="@color/bright_foreground_dark"
android:shadowColor="#BB000000"
diff --git a/core/res/res/raw-ar/loaderror.html b/core/res/res/raw-ar/loaderror.html
index aa9805c..5b88558 100644
--- a/core/res/res/raw-ar/loaderror.html
+++ b/core/res/res/raw-ar/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>صفحة الويب غير متوفرة</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; direction: rtl; }
diff --git a/core/res/res/raw-ar/nodomain.html b/core/res/res/raw-ar/nodomain.html
index 2e5849f..613c230 100644
--- a/core/res/res/raw-ar/nodomain.html
+++ b/core/res/res/raw-ar/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>صفحة الويب غير متوفرة</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; direction: rtl; }
diff --git a/core/res/res/raw-cs/loaderror.html b/core/res/res/raw-cs/loaderror.html
index ce88981..a07970b 100644
--- a/core/res/res/raw-cs/loaderror.html
+++ b/core/res/res/raw-cs/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Webová stránka není dostupná</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-cs/nodomain.html b/core/res/res/raw-cs/nodomain.html
index 26479a9..bd78ca3 100644
--- a/core/res/res/raw-cs/nodomain.html
+++ b/core/res/res/raw-cs/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Webová stránka není dostupná</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-da/loaderror.html b/core/res/res/raw-da/loaderror.html
index 12a75c6c..8065f1a 100644
--- a/core/res/res/raw-da/loaderror.html
+++ b/core/res/res/raw-da/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Websiden er ikke tilgængelig</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-da/nodomain.html b/core/res/res/raw-da/nodomain.html
index 3b8fe78..b24de2b 100644
--- a/core/res/res/raw-da/nodomain.html
+++ b/core/res/res/raw-da/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Websiden er ikke tilgængelig</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-de/loaderror.html b/core/res/res/raw-de/loaderror.html
index bece2d7..62d7a13 100644
--- a/core/res/res/raw-de/loaderror.html
+++ b/core/res/res/raw-de/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Webseite nicht verfügbar</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-de/nodomain.html b/core/res/res/raw-de/nodomain.html
index 9fd8094..7ea8d86d 100644
--- a/core/res/res/raw-de/nodomain.html
+++ b/core/res/res/raw-de/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Webseite nicht verfügbar</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-en-rGB/loaderror.html b/core/res/res/raw-en-rGB/loaderror.html
index 359a1e7..fd3d766 100644
--- a/core/res/res/raw-en-rGB/loaderror.html
+++ b/core/res/res/raw-en-rGB/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Web page not available</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-en-rGB/nodomain.html b/core/res/res/raw-en-rGB/nodomain.html
index 01dd603..4ca403b 100644
--- a/core/res/res/raw-en-rGB/nodomain.html
+++ b/core/res/res/raw-en-rGB/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Web page not available</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-es/loaderror.html b/core/res/res/raw-es/loaderror.html
index 8829bf5..0102b8a 100644
--- a/core/res/res/raw-es/loaderror.html
+++ b/core/res/res/raw-es/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Página web no disponible</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-es/nodomain.html b/core/res/res/raw-es/nodomain.html
index a11333e..03a9855 100644
--- a/core/res/res/raw-es/nodomain.html
+++ b/core/res/res/raw-es/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Página web no disponible</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-fi/loaderror.html b/core/res/res/raw-fi/loaderror.html
index 3b1ec97..2ef97f4 100644
--- a/core/res/res/raw-fi/loaderror.html
+++ b/core/res/res/raw-fi/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Verkkosivu ei ole käytettävissä</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-fi/nodomain.html b/core/res/res/raw-fi/nodomain.html
index 84fedb4..58abc2d 100644
--- a/core/res/res/raw-fi/nodomain.html
+++ b/core/res/res/raw-fi/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Verkkosivu ei ole käytettävissä</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-fr/loaderror.html b/core/res/res/raw-fr/loaderror.html
index f61f50b..f22d1b1 100644
--- a/core/res/res/raw-fr/loaderror.html
+++ b/core/res/res/raw-fr/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Page Web non disponible</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-fr/nodomain.html b/core/res/res/raw-fr/nodomain.html
index b3b93b3..3c62aee 100644
--- a/core/res/res/raw-fr/nodomain.html
+++ b/core/res/res/raw-fr/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Page Web non disponible</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-hu/loaderror.html b/core/res/res/raw-hu/loaderror.html
index 6b3d45e..4eccb24 100644
--- a/core/res/res/raw-hu/loaderror.html
+++ b/core/res/res/raw-hu/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>A weboldal nem érhető el</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-hu/nodomain.html b/core/res/res/raw-hu/nodomain.html
index d3465ff..08399e2 100644
--- a/core/res/res/raw-hu/nodomain.html
+++ b/core/res/res/raw-hu/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>A weboldal nem érhető el</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-it/loaderror.html b/core/res/res/raw-it/loaderror.html
index e81466a..9f78d08 100644
--- a/core/res/res/raw-it/loaderror.html
+++ b/core/res/res/raw-it/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Pagina web non disponibile</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-it/nodomain.html b/core/res/res/raw-it/nodomain.html
index a2321c7..6e1876c 100644
--- a/core/res/res/raw-it/nodomain.html
+++ b/core/res/res/raw-it/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Pagina web non disponibile</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-iw/loaderror.html b/core/res/res/raw-iw/loaderror.html
index 8d5a53f..08ff28e 100644
--- a/core/res/res/raw-iw/loaderror.html
+++ b/core/res/res/raw-iw/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>דף אינטרנט לא זמין</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; direction: rtl; }
diff --git a/core/res/res/raw-iw/nodomain.html b/core/res/res/raw-iw/nodomain.html
index 0dcd7f8..fd89aa0 100644
--- a/core/res/res/raw-iw/nodomain.html
+++ b/core/res/res/raw-iw/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>דף אינטרנט לא זמין</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; direction: rtl; }
diff --git a/core/res/res/raw-ja/loaderror.html b/core/res/res/raw-ja/loaderror.html
index 68e568b..819859e 100644
--- a/core/res/res/raw-ja/loaderror.html
+++ b/core/res/res/raw-ja/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>ページが見つかりませんでした</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ja/nodomain.html b/core/res/res/raw-ja/nodomain.html
index 1dff1d4..75495db 100644
--- a/core/res/res/raw-ja/nodomain.html
+++ b/core/res/res/raw-ja/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>ページが見つかりませんでした</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ko/loaderror.html b/core/res/res/raw-ko/loaderror.html
index 59f0f25..0ae687d 100644
--- a/core/res/res/raw-ko/loaderror.html
+++ b/core/res/res/raw-ko/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>웹페이지를 표시할 수 없습니다.</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ko/nodomain.html b/core/res/res/raw-ko/nodomain.html
index 0eadc39..f014845 100644
--- a/core/res/res/raw-ko/nodomain.html
+++ b/core/res/res/raw-ko/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>웹페이지를 표시할 수 없습니다.</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-nl/loaderror.html b/core/res/res/raw-nl/loaderror.html
index 76bb07c..819c3ba 100644
--- a/core/res/res/raw-nl/loaderror.html
+++ b/core/res/res/raw-nl/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Webpagina niet beschikbaar</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-nl/nodomain.html b/core/res/res/raw-nl/nodomain.html
index ffac947..52c50e8 100644
--- a/core/res/res/raw-nl/nodomain.html
+++ b/core/res/res/raw-nl/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Webpagina niet beschikbaar</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-pl/loaderror.html b/core/res/res/raw-pl/loaderror.html
index 9cc1342..085d69d 100644
--- a/core/res/res/raw-pl/loaderror.html
+++ b/core/res/res/raw-pl/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Strona internetowa jest niedostępna</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-pl/nodomain.html b/core/res/res/raw-pl/nodomain.html
index 23f529d..c994abe 100644
--- a/core/res/res/raw-pl/nodomain.html
+++ b/core/res/res/raw-pl/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Strona internetowa jest niedostępna</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-pt-rBR/loaderror.html b/core/res/res/raw-pt-rBR/loaderror.html
index 3476239..9f363c5 100644
--- a/core/res/res/raw-pt-rBR/loaderror.html
+++ b/core/res/res/raw-pt-rBR/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Página da web não disponível</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-pt-rBR/nodomain.html b/core/res/res/raw-pt-rBR/nodomain.html
index 546c610..33b76f9 100644
--- a/core/res/res/raw-pt-rBR/nodomain.html
+++ b/core/res/res/raw-pt-rBR/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Página da web não disponível</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-rm/loaderror.html b/core/res/res/raw-rm/loaderror.html
index 8e4a3fe..e09ed49 100644
--- a/core/res/res/raw-rm/loaderror.html
+++ b/core/res/res/raw-rm/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Pagina d'internet betg disponibla</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-rm/nodomain.html b/core/res/res/raw-rm/nodomain.html
index 1e2833b..964f7f4 100644
--- a/core/res/res/raw-rm/nodomain.html
+++ b/core/res/res/raw-rm/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Pagina d'internet betg disponibla</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ru/loaderror.html b/core/res/res/raw-ru/loaderror.html
index 5a0312e..8faf416 100644
--- a/core/res/res/raw-ru/loaderror.html
+++ b/core/res/res/raw-ru/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Веб-страница недоступна</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-ru/nodomain.html b/core/res/res/raw-ru/nodomain.html
index 86a42a1..3f606f9 100644
--- a/core/res/res/raw-ru/nodomain.html
+++ b/core/res/res/raw-ru/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Веб-страница недоступна</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-th/loaderror.html b/core/res/res/raw-th/loaderror.html
index 05310a7..7e12c57 100644
--- a/core/res/res/raw-th/loaderror.html
+++ b/core/res/res/raw-th/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>ไม่มีเว็บเพจนี้</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-th/nodomain.html b/core/res/res/raw-th/nodomain.html
index 37b8593..b94e4a9 100644
--- a/core/res/res/raw-th/nodomain.html
+++ b/core/res/res/raw-th/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>ไม่มีเว็บเพจนี้</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-tr/loaderror.html b/core/res/res/raw-tr/loaderror.html
index b6f4890..665c9a8 100644
--- a/core/res/res/raw-tr/loaderror.html
+++ b/core/res/res/raw-tr/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Web sayfası yok</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-tr/nodomain.html b/core/res/res/raw-tr/nodomain.html
index a79c21b..90545da 100644
--- a/core/res/res/raw-tr/nodomain.html
+++ b/core/res/res/raw-tr/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Web sayfası yok</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-zh-rCN/loaderror.html b/core/res/res/raw-zh-rCN/loaderror.html
index 809d31f..cab447b 100644
--- a/core/res/res/raw-zh-rCN/loaderror.html
+++ b/core/res/res/raw-zh-rCN/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>找不到网页</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-zh-rCN/nodomain.html b/core/res/res/raw-zh-rCN/nodomain.html
index eb03187..ba74131 100644
--- a/core/res/res/raw-zh-rCN/nodomain.html
+++ b/core/res/res/raw-zh-rCN/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>找不到网页</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-zh-rTW/loaderror.html b/core/res/res/raw-zh-rTW/loaderror.html
index 0b4695a..cb86ae6 100644
--- a/core/res/res/raw-zh-rTW/loaderror.html
+++ b/core/res/res/raw-zh-rTW/loaderror.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>您所查詢的網頁不存在或已移除</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/raw-zh-rTW/nodomain.html b/core/res/res/raw-zh-rTW/nodomain.html
index 3577a9d..18d786c 100644
--- a/core/res/res/raw-zh-rTW/nodomain.html
+++ b/core/res/res/raw-zh-rTW/nodomain.html
@@ -1,5 +1,6 @@
<html>
<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>您所查詢的網頁不存在或已移除</title>
<style type="text/css">
body { margin-top: 0px; padding-top: 0px; }
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9cd04e4..aa8b643 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2498,7 +2498,7 @@
<!-- The minimal period in milliseconds between two accessibility events of the same type
are sent to this serivce. This setting can be changed at runtime by calling
{@link android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)
- android.accessibilityservice.AccessibilityService.setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->>
+ android.accessibilityservice.AccessibilityService.setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->
<attr name="notificationTimeout" format="integer" />
<!-- Additional flags as specified in
{@link android.accessibilityservice.AccessibilityServiceInfo}.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a2e15e6..4d54fd2 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -868,4 +868,7 @@
<!-- Set to true to add links to Cell Broadcast app from Settings and MMS app. -->
<bool name="config_cellBroadcastAppLinks">false</bool>
+
+ <!-- The default value if the SyncStorageEngine should sync automatically or not -->
+ <bool name="config_syncstorageengine_masterSyncAutomatically">true</bool>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0bae0cb..6334f88 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -253,6 +253,7 @@
<java-symbol type="bool" name="config_sms_capable" />
<java-symbol type="bool" name="config_sms_utf8_support" />
<java-symbol type="bool" name="config_swipeDisambiguation" />
+ <java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
<java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" />
<java-symbol type="bool" name="config_ui_enableFadingMarquee" />
<java-symbol type="bool" name="config_use_strict_phone_number_comparation" />
@@ -815,6 +816,13 @@
<java-symbol type="string" name="sms_control_title" />
<java-symbol type="string" name="sms_control_no" />
<java-symbol type="string" name="sms_control_yes" />
+ <java-symbol type="string" name="sms_premium_short_code_confirm_message" />
+ <java-symbol type="string" name="sms_premium_short_code_confirm_title" />
+ <java-symbol type="string" name="sms_short_code_confirm_allow" />
+ <java-symbol type="string" name="sms_short_code_confirm_deny" />
+ <java-symbol type="string" name="sms_short_code_confirm_message" />
+ <java-symbol type="string" name="sms_short_code_confirm_report" />
+ <java-symbol type="string" name="sms_short_code_confirm_title" />
<java-symbol type="string" name="submit" />
<java-symbol type="string" name="sync_binding_label" />
<java-symbol type="string" name="sync_do_nothing" />
@@ -1139,6 +1147,7 @@
<java-symbol type="xml" name="password_kbd_symbols_shift" />
<java-symbol type="xml" name="power_profile" />
<java-symbol type="xml" name="time_zones_by_country" />
+ <java-symbol type="xml" name="sms_short_codes" />
<java-symbol type="raw" name="accessibility_gestures" />
<java-symbol type="raw" name="incognito_mode_start_page" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 325b6fe..3582768 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2923,6 +2923,22 @@
<!-- See SMS_DIALOG. This is a button choice to disallow sending the SMSes. [CHAR LIMIT=30] -->
<string name="sms_control_no">Deny</string>
+ <!-- SMS short code verification dialog. --> <skip />
+ <!-- The dialog title for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_title">Send SMS to short code?</string>
+ <!-- The dialog title for the SMS premium short code confirmation dialog. [CHAR LIMIT=30] -->
+ <string name="sms_premium_short_code_confirm_title">Send premium SMS?</string>
+ <!-- The message text for the SMS short code confirmation dialog. [CHAR LIMIT=NONE] -->
+ <string name="sms_short_code_confirm_message"><b><xliff:g id="app_name">%1$s</xliff:g></b> would like to send a text message to <b><xliff:g id="dest_address">%2$s</xliff:g></b>, which appears to be an SMS short code.<p>Sending text messages to some short codes may cause your mobile account to be billed for premium services.<p>Do you want to allow this app to send the message?</string>
+ <!-- The message text for the SMS short code confirmation dialog. [CHAR LIMIT=NONE] -->
+ <string name="sms_premium_short_code_confirm_message"><b><xliff:g id="app_name">%1$s</xliff:g></b> would like to send a text message to <b><xliff:g id="dest_address">%2$s</xliff:g></b>, which is a premium SMS short code.<p><b>Sending a message to this destination will cause your mobile account to be billed for premium services.</b><p>Do you want to allow this app to send the message?</string>
+ <!-- Text of the approval button for the SMS short code confirmation dialog. [CHAR LIMIT=50] -->
+ <string name="sms_short_code_confirm_allow">Send message</string>
+ <!-- Text of the cancel button for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_deny">Don\'t send</string>
+ <!-- Text of the button for the SMS short code confirmation dialog to report a malicious app. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_report">Report malicious app</string>
+
<!-- SIM swap and device reboot Dialog --> <skip />
<!-- See SIM_REMOVED_DIALOG. This is the title of that dialog. -->
<string name="sim_removed_title">SIM card removed</string>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
new file mode 100644
index 0000000..8b395af
--- /dev/null
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- Regex patterns for SMS short codes by country. -->
+<shortcodes>
+
+ <!-- The country attribute is the ISO country code of the user's account (from SIM card or NV).
+ The pattern attribute is a regex that matches all SMS short codes for the country.
+ The premium attribute is a regex that matches premium rate SMS short codes.
+ The free attribute matches short codes that we know will not cost the user, such as
+ emergency numbers. The standard attribute matches short codes that are billed at the
+ standard SMS rate. The user is warned when the destination phone number matches the
+ "pattern" or "premium" regexes, and does not match the "free" or "standard" regexes. -->
+
+ <!-- Harmonised European Short Codes are 6 digit numbers starting with 116 (free helplines).
+ Premium patterns include short codes from: http://aonebill.com/coverage&tariffs
+ and http://mobilcent.com/info-worldwide.asp and extracted from:
+ http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ -->
+
+ <!-- Albania: 5 digits, known short codes listed -->
+ <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
+
+ <!-- Armenia: 3-4 digits, emergency numbers 10[123] -->
+ <shortcode country="am" pattern="\\d{3,4}" premium="11[2456]1|3024" free="10[123]" />
+
+ <!-- Austria: 10 digits, premium prefix 09xx, plus EU -->
+ <shortcode country="at" pattern="11\\d{4}" premium="09.*" free="116\\d{3}" />
+
+ <!-- Australia: 6 or 8 digits starting with "19" -->
+ <shortcode country="au" pattern="19(?:\\d{4}|\\d{6})" premium="19998882" />
+
+ <!-- Azerbaijan: 4-5 digits, known premium codes listed -->
+ <shortcode country="az" pattern="\\d{4,5}" premium="330[12]|87744|901[234]|93(?:94|101)|9426|9525" />
+
+ <!-- Belgium: 4 digits, plus EU: http://www.mobileweb.be/en/mobileweb/sms-numberplan.asp -->
+ <shortcode country="be" premium="\\d{4}" free="8\\d{3}|116\\d{3}" />
+
+ <!-- Bulgaria: 4-5 digits, plus EU -->
+ <shortcode country="bg" pattern="\\d{4,5}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}" />
+
+ <!-- Belarus: 4 digits -->
+ <shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" />
+
+ <!-- Canada: 5-6 digits -->
+ <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188" />
+
+ <!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf -->
+ <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111" />
+
+ <!-- China: premium shortcodes start with "1066", free shortcodes start with "1065":
+ http://clients.txtnation.com/entries/197192-china-premium-sms-short-code-requirements -->
+ <shortcode country="cn" premium="1066.*" free="1065.*" />
+
+ <!-- Cyprus: 4-6 digits (not confirmed), known premium codes listed, plus EU -->
+ <shortcode country="cy" pattern="\\d{4,6}" premium="7510" free="116\\d{3}" />
+
+ <!-- Czech Republic: 7-8 digits, starting with 9, plus EU:
+ http://www.o2.cz/osobni/en/services-by-alphabet/91670-premium_sms.html -->
+ <shortcode country="cz" premium="9\\d{6,7}" free="116\\d{3}" />
+
+ <!-- Germany: 4-5 digits plus 1232xxx (premium codes from http://www.vodafone.de/infofaxe/537.pdf and http://premiumdienste.eplus.de/pdf/kodex.pdf), plus EU. To keep the premium regex from being too large, it only includes payment processors that have been used by SMS malware, with the regular pattern matching the other premium short codes. -->
+ <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}" />
+
+ <!-- Denmark: see http://iprs.webspacecommerce.com/Denmark-Premium-Rate-Numbers -->
+ <shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}" />
+
+ <!-- Estonia: short codes 3-5 digits starting with 1, plus premium 7 digit numbers starting with 90, plus EU.
+ http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
+ <shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}" />
+
+ <!-- Spain: 5-6 digits: 25xxx, 27xxx, 280xx, 35xxx, 37xxx, 795xxx, 797xxx, 995xxx, 997xxx, plus EU.
+ http://www.legallink.es/?q=en/content/which-current-regulatory-status-premium-rate-services-spain -->
+ <shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}" />
+
+ <!-- Finland: 5-6 digits, premium 0600, 0700: http://en.wikipedia.org/wiki/Telephone_numbers_in_Finland -->
+ <shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}" />
+
+ <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
+ http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements -->
+ <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}" />
+
+ <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
+ http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf -->
+ <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}" />
+
+ <!-- Georgia: 4 digits, known premium codes listed -->
+ <shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
+
+ <!-- Greece: 5 digits (54xxx, 19yxx, x=0-9, y=0-5): http://www.cmtelecom.com/premium-sms/greece -->
+ <shortcode country="gr" pattern="\\d{5}" premium="54\\d{3}|19[0-5]\\d{2}" free="116\\d{3}" />
+
+ <!-- Hungary: 4 or 10 digits starting with 1 or 0, plus EU:
+ http://clients.txtnation.com/entries/209633-hungary-premium-sms-short-code-regulations -->
+ <shortcode country="hu" pattern="[01](?:\\d{3}|\\d{9})" premium="0691227910|1784" free="116\\d{3}" />
+
+ <!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU:
+ http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf -->
+ <shortcode country="ie" pattern="\\d{5}" premium="5[3-9]\\d{3}" free="50\\d{3}|116\\d{3}" standard="5[12]\\d{3}" />
+
+ <!-- Israel: 4 digits, known premium codes listed -->
+ <shortcode country="il" pattern="\\d{4}" premium="4422|4545" />
+
+ <!-- Italy: 5 digits (premium=4xxxx), plus EU:
+ http://clients.txtnation.com/attachments/token/di5kfblvubttvlw/?name=Italy_CASP_EN.pdf -->
+ <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}" />
+
+ <!-- Kyrgyzstan: 4 digits, known premium codes listed -->
+ <shortcode country="kg" pattern="\\d{4}" premium="415[2367]|444[69]" />
+
+ <!-- Kazakhstan: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-kazakhstan/ -->
+ <shortcode country="kz" pattern="\\d{4}" premium="335[02]|4161|444[469]|77[2359]0|8444|919[3-5]|968[2-5]" />
+
+ <!-- Lithuania: 3-5 digits, known premium codes listed, plus EU -->
+ <shortcode country="lt" pattern="\\d{3,5}" premium="13[89]1|1394|16[34]5" free="116\\d{3}" />
+
+ <!-- Luxembourg: 5 digits, 6xxxx, plus EU:
+ http://www.luxgsm.lu/assets/files/filepage/file_1253803400.pdf -->
+ <shortcode country="lu" premium="6\\d{4}" free="116\\d{3}" />
+
+ <!-- Latvia: 4 digits, known premium codes listed, plus EU -->
+ <shortcode country="lv" pattern="\\d{4}" premium="18(?:19|63|7[1-4])" free="116\\d{3}" />
+
+ <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed -->
+ <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" />
+
+ <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
+ <shortcode country="my" pattern="\\d{5}" premium="32298|33776" />
+
+ <!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
+ <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}" />
+
+ <!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
+ <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" />
+
+ <!-- New Zealand: 3-4 digits, known premium codes listed -->
+ <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995" />
+
+ <!-- Poland: 4-5 digits (not confirmed), known premium codes listed, plus EU -->
+ <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}" />
+
+ <!-- Portugal: 5 digits, plus EU:
+ http://clients.txtnation.com/entries/158326-portugal-premium-sms-short-code-regulations -->
+ <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}" />
+
+ <!-- Romania: 4 digits, plus EU: http://www.simplus.ro/en/resources/glossary-of-terms/ -->
+ <shortcode country="ro" pattern="\\d{4}" premium="12(?:63|66|88)|13(?:14|80)" free="116\\d{3}" />
+
+ <!-- Russia: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-russia/ -->
+ <shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)" />
+
+ <!-- Sweden: 5 digits (72xxx), plus EU: http://www.viatel.se/en/premium-sms/ -->
+ <shortcode country="se" premium="72\\d{3}" free="116\\d{3}" />
+
+ <!-- Singapore: 5 digits: http://clients.txtnation.com/entries/306442-singapore-premium-sms-short-code-requirements
+ Free government directory info at 74688: http://app.sgdi.gov.sg/sms_help.asp -->
+ <shortcode country="sg" pattern="7\\d{4}" premium="73800" standard="74688" />
+
+ <!-- Slovenia: 4 digits (premium=3xxx, 6xxx, 8xxx), plus EU: http://www.cmtelecom.com/premium-sms/slovenia -->
+ <shortcode country="si" pattern="\\d{4}" premium="[368]\\d{3}" free="116\\d{3}" />
+
+ <!-- Slovakia: 4 digits (premium), plus EU: http://www.cmtelecom.com/premium-sms/slovakia -->
+ <shortcode country="sk" premium="\\d{4}" free="116\\d{3}" />
+
+ <!-- Tajikistan: 4 digits, known premium codes listed -->
+ <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
+
+ <!-- Ukraine: 4 digits, known premium codes listed -->
+ <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
+
+ <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm) -->
+ <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" />
+
+</shortcodes>
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 88f3f34..b6b15c4 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -23,7 +23,7 @@
LOCAL_DX_FLAGS := --core-library
LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib mockwebserver guava littlemock
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
LOCAL_PACKAGE_NAME := FrameworksCoreTests
LOCAL_CERTIFICATE := platform
diff --git a/core/tests/coretests/apks/install_complete_package_info/Android.mk b/core/tests/coretests/apks/install_complete_package_info/Android.mk
new file mode 100644
index 0000000..1edccb4
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/Android.mk
@@ -0,0 +1,11 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_complete_package_info
+
+include $(BUILD_PACKAGE)
+
diff --git a/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml b/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
new file mode 100644
index 0000000..4b01736
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.install_complete_package_info">
+
+<!--
+ This manifest declares at least one of each of the components that
+ can be retrieved by PackageManager.getInstalledPackages.
+ All the implementing classes are empty implementations
+-->
+
+ <uses-feature
+ android:name="com.android.frameworks.coretests.nonexistent" />
+ <uses-configuration
+ android:reqFiveWayNav="false" />
+
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.frameworks.coretests"
+ android:label="Frameworks Core Tests" />
+
+ <permission
+ android:label="test permission"
+ android:name="test_permission"
+ android:protectionLevel="normal" />
+
+ <application
+ android:hasCode="true">
+ <activity
+ android:name="com.android.frameworks.coretests.TestActivity">
+ </activity>
+ <provider
+ android:name="com.android.frameworks.coretests.TestProvider"
+ android:authorities="com.android.frameworks.coretests.testprovider" />
+ <receiver
+ android:name="com.android.frameworks.coretests.TestReceiver" />
+ <service
+ android:name="com.android.frameworks.coretests.TestService" />
+ </application>
+</manifest>
diff --git a/telephony/java/com/android/internal/telephony/IccException.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
similarity index 68%
rename from telephony/java/com/android/internal/telephony/IccException.java
rename to core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
index 1659a4e..10d0551 100644
--- a/telephony/java/com/android/internal/telephony/IccException.java
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -12,19 +12,13 @@
* 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;
+package com.android.frameworks.coretests;
-/**
- * {@hide}
- */
-public class IccException extends Exception {
- public IccException() {
+import android.app.Activity;
- }
+public class TestActivity extends Activity {
- public IccException(String s) {
- super(s);
- }
}
diff --git a/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
new file mode 100644
index 0000000..59f9f10
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 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.frameworks.coretests;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class TestProvider extends ContentProvider {
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
new file mode 100644
index 0000000..21f6263
--- /dev/null
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestReceiver.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 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.frameworks.coretests;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class TestReceiver extends ContentProvider {
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatException.java b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
similarity index 65%
rename from telephony/java/com/android/internal/telephony/cat/CatException.java
rename to core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
index 1bf1369..b330e75 100644
--- a/telephony/java/com/android/internal/telephony/cat/CatException.java
+++ b/core/tests/coretests/apks/install_complete_package_info/src/com/android/frameworks/coretests/TestService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -12,20 +12,19 @@
* 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.cat;
-
-import android.util.AndroidException;
-
-
-/**
- * Base class for all the exceptions in CAT service.
*
- * {@hide}
*/
-class CatException extends AndroidException {
- public CatException() {
- super();
+
+package com.android.frameworks.coretests;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class TestService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
}
}
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 77e4986..6e1b9d6 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
@@ -50,6 +51,8 @@
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
+
public class PackageManagerTests extends AndroidTestCase {
private static final boolean localLOGV = true;
public static final String TAG="PackageManagerTests";
@@ -3162,6 +3165,92 @@
assertNotNull("Verifier device identity should not be null", id);
}
+ public void testGetInstalledPackages() {
+ List<PackageInfo> packages = getPm().getInstalledPackages(0);
+ assertNotNull("installed packages cannot be null", packages);
+ assertTrue("installed packages cannot be empty", packages.size() > 0);
+ }
+
+ public void testGetUnInstalledPackages() {
+ List<PackageInfo> packages = getPm().getInstalledPackages(
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ assertNotNull("installed packages cannot be null", packages);
+ assertTrue("installed packages cannot be empty", packages.size() > 0);
+ }
+
+ /**
+ * Test that getInstalledPackages returns all the data specified in
+ * flags.
+ */
+ public void testGetInstalledPackagesAll() {
+ int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
+ | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
+ | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
+ | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
+ | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
+
+ List<PackageInfo> packages = getPm().getInstalledPackages(flags);
+ assertNotNull("installed packages cannot be null", packages);
+ assertTrue("installed packages cannot be empty", packages.size() > 0);
+
+ PackageInfo packageInfo = null;
+
+ // Find the package with all components specified in the AndroidManifest
+ // to ensure no null values
+ for (PackageInfo pi : packages) {
+ if ("com.android.frameworks.coretests.install_complete_package_info"
+ .equals(pi.packageName)) {
+ packageInfo = pi;
+ break;
+ }
+ }
+ assertNotNull("activities should not be null", packageInfo.activities);
+ assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
+ assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
+ assertNotNull("permissions should not be null", packageInfo.permissions);
+ assertNotNull("providers should not be null", packageInfo.providers);
+ assertNotNull("receivers should not be null", packageInfo.receivers);
+ assertNotNull("services should not be null", packageInfo.services);
+ assertNotNull("signatures should not be null", packageInfo.signatures);
+ }
+
+ /**
+ * Test that getInstalledPackages returns all the data specified in
+ * flags when the GET_UNINSTALLED_PACKAGES flag is set.
+ */
+ public void testGetUnInstalledPackagesAll() {
+ int flags = PackageManager.GET_UNINSTALLED_PACKAGES
+ | PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
+ | PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
+ | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
+ | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
+ | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
+
+ List<PackageInfo> packages = getPm().getInstalledPackages(flags);
+ assertNotNull("installed packages cannot be null", packages);
+ assertTrue("installed packages cannot be empty", packages.size() > 0);
+
+ PackageInfo packageInfo = null;
+
+ // Find the package with all components specified in the AndroidManifest
+ // to ensure no null values
+ for (PackageInfo pi : packages) {
+ if ("com.android.frameworks.coretests.install_complete_package_info"
+ .equals(pi.packageName)) {
+ packageInfo = pi;
+ break;
+ }
+ }
+ assertNotNull("activities should not be null", packageInfo.activities);
+ assertNotNull("configPreferences should not be null", packageInfo.configPreferences);
+ assertNotNull("instrumentation should not be null", packageInfo.instrumentation);
+ assertNotNull("permissions should not be null", packageInfo.permissions);
+ assertNotNull("providers should not be null", packageInfo.providers);
+ assertNotNull("receivers should not be null", packageInfo.receivers);
+ assertNotNull("services should not be null", packageInfo.services);
+ assertNotNull("signatures should not be null", packageInfo.signatures);
+ }
+
/*---------- Recommended install location tests ----*/
/*
* TODO's
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index f12cbe1..4d0b892 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -17,21 +17,13 @@
package android.os;
import android.content.Context;
-import android.os.FileUtils;
-import android.os.FileUtils.FileStatus;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.FileWriter;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-import java.io.IOException;
-
-import junit.framework.Assert;
+import java.io.FileWriter;
public class FileUtilsTest extends AndroidTestCase {
private static final String TEST_DATA =
@@ -60,60 +52,6 @@
if (mCopyFile.exists()) mCopyFile.delete();
}
- @LargeTest
- public void testGetFileStatus() {
- final byte[] MAGIC = { 0xB, 0xE, 0x0, 0x5 };
-
- try {
- // truncate test file and write MAGIC (4 bytes) to it.
- FileOutputStream os = new FileOutputStream(mTestFile, false);
- os.write(MAGIC, 0, 4);
- os.flush();
- os.close();
- } catch (FileNotFoundException e) {
- Assert.fail("File was removed durning test" + e);
- } catch (IOException e) {
- Assert.fail("Unexpected IOException: " + e);
- }
-
- Assert.assertTrue(mTestFile.exists());
- Assert.assertTrue(FileUtils.getFileStatus(mTestFile.getPath(), null));
-
- FileStatus status1 = new FileStatus();
- FileUtils.getFileStatus(mTestFile.getPath(), status1);
-
- Assert.assertEquals(4, status1.size);
-
- // Sleep for at least one second so that the modification time will be different.
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
-
- try {
- // append so we don't change the creation time.
- FileOutputStream os = new FileOutputStream(mTestFile, true);
- os.write(MAGIC, 0, 4);
- os.flush();
- os.close();
- } catch (FileNotFoundException e) {
- Assert.fail("File was removed durning test" + e);
- } catch (IOException e) {
- Assert.fail("Unexpected IOException: " + e);
- }
-
- FileStatus status2 = new FileStatus();
- FileUtils.getFileStatus(mTestFile.getPath(), status2);
-
- Assert.assertEquals(8, status2.size);
- Assert.assertTrue(status2.mtime > status1.mtime);
-
- mTestFile.delete();
-
- Assert.assertFalse(mTestFile.exists());
- Assert.assertFalse(FileUtils.getFileStatus(mTestFile.getPath(), null));
- }
-
// TODO: test setPermissions(), getPermissions()
@MediumTest
diff --git a/core/tests/coretests/src/android/os/SELinuxTest.java b/core/tests/coretests/src/android/os/SELinuxTest.java
new file mode 100644
index 0000000..9b63a6b
--- /dev/null
+++ b/core/tests/coretests/src/android/os/SELinuxTest.java
@@ -0,0 +1,45 @@
+package android.os;
+
+import android.os.Process;
+import android.os.SELinux;
+import android.test.AndroidTestCase;
+import static junit.framework.Assert.assertEquals;
+
+public class SELinuxTest extends AndroidTestCase {
+
+ public void testgetFileCon() {
+ if(SELinux.isSELinuxEnabled() == false)
+ return;
+
+ String ctx = SELinux.getFileContext("/system/bin/toolbox");
+ assertEquals(ctx, "u:object_r:system_file:s0");
+ }
+
+ public void testgetCon() {
+ if(SELinux.isSELinuxEnabled() == false)
+ return;
+
+ String mycon = SELinux.getContext();
+ assertEquals(mycon, "u:r:untrusted_app:s0:c33");
+ }
+
+ public void testgetPidCon() {
+ if(SELinux.isSELinuxEnabled() == false)
+ return;
+
+ String mycon = SELinux.getPidContext(Process.myPid());
+ assertEquals(mycon, "u:r:untrusted_app:s0:c33");
+ }
+
+ public void testcheckSELinuxAccess() {
+ if(SELinux.isSELinuxEnabled() == false)
+ return;
+
+ String mycon = SELinux.getContext();
+ boolean ret;
+ ret = SELinux.checkSELinuxAccess(mycon, mycon, "process", "fork");
+ assertEquals(ret,"true");
+ ret = SELinux.checkSELinuxAccess(mycon, mycon, "memprotect", "mmap_zero");
+ assertEquals(ret,"true");
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
index ab6b2b6..418bbd6 100644
--- a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
@@ -24,7 +24,7 @@
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
-import com.android.internal.util.StateMachine.ProcessedMessageInfo;
+import com.android.internal.util.StateMachine.LogRec;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -36,6 +36,10 @@
* Test for StateMachine.
*/
public class StateMachineTest extends TestCase {
+ private static final String ENTER = "enter";
+ private static final String EXIT = "exit";
+ private static final String ON_QUITTING = "ON_QUITTING";
+
private static final int TEST_CMD_1 = 1;
private static final int TEST_CMD_2 = 2;
private static final int TEST_CMD_3 = 3;
@@ -47,11 +51,18 @@
private static final boolean WAIT_FOR_DEBUGGER = false;
private static final String TAG = "StateMachineTest";
+ private void sleep(int millis) {
+ try {
+ Thread.sleep(millis);
+ } catch(InterruptedException e) {
+ }
+ }
+
/**
- * Tests that we can quit the state machine.
+ * Tests {@link StateMachine#quit()}.
*/
class StateMachineQuitTest extends StateMachine {
- private int mQuitCount = 0;
+ Object mWaitUntilTestDone = new Object();
StateMachineQuitTest(String name) {
super(name);
@@ -65,29 +76,45 @@
setInitialState(mS1);
}
- class S1 extends State {
- @Override
- public boolean processMessage(Message message) {
- if (isQuit(message)) {
- mQuitCount += 1;
- if (mQuitCount > 2) {
- // Returning NOT_HANDLED to actually quit
- return NOT_HANDLED;
- } else {
- // Do NOT quit
- return HANDLED;
- }
- } else {
- // All other message are handled
- return HANDLED;
+ @Override
+ public void onQuitting() {
+ Log.d(TAG, "onQuitting");
+ addLogRec(ON_QUITTING);
+ synchronized (mThisSm) {
+ mThisSm.notifyAll();
+ }
+
+ // Don't leave onQuitting before the test is done as everything is cleared
+ // including the log records.
+ synchronized (mWaitUntilTestDone) {
+ try {
+ mWaitUntilTestDone.wait();
+ } catch(InterruptedException e) {
}
}
}
- @Override
- protected void quitting() {
- synchronized (mThisSm) {
- mThisSm.notifyAll();
+ class S1 extends State {
+ public void exit() {
+ Log.d(TAG, "S1.exit");
+ addLogRec(EXIT, mS1);
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ switch(message.what) {
+ // Sleep and assume the other messages will be queued up.
+ case TEST_CMD_1: {
+ Log.d(TAG, "TEST_CMD_1");
+ sleep(500);
+ quit();
+ break;
+ }
+ default: {
+ Log.d(TAG, "default what=" + message.what);
+ break;
+ }
+ }
+ return HANDLED;
}
}
@@ -96,62 +123,167 @@
}
@SmallTest
- public void testStateMachineQuitTest() throws Exception {
+ public void testStateMachineQuit() throws Exception {
if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
smQuitTest.start();
- if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuitTest E");
+ if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit E");
synchronized (smQuitTest) {
- // Send 6 messages
+
+ // Send 6 message we'll quit on the first but all 6 should be processed before quitting.
for (int i = 1; i <= 6; i++) {
- smQuitTest.sendMessage(i);
+ smQuitTest.sendMessage(smQuitTest.obtainMessage(i));
}
- // First two are ignored
- smQuitTest.quit();
- smQuitTest.quit();
-
- // Now we will quit
- smQuitTest.quit();
-
try {
// wait for the messages to be handled
smQuitTest.wait();
} catch (InterruptedException e) {
- Log.e(TAG, "testStateMachineQuitTest: exception while waiting " + e.getMessage());
+ Log.e(TAG, "testStateMachineQuit: exception while waiting " + e.getMessage());
}
}
- assertTrue(smQuitTest.getProcessedMessagesCount() == 9);
+ assertEquals(8, smQuitTest.getLogRecCount());
- ProcessedMessageInfo pmi;
+ LogRec lr;
- // The first two message didn't quit and were handled by mS1
- pmi = smQuitTest.getProcessedMessageInfo(6);
- assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
- assertEquals(smQuitTest.mS1, pmi.getState());
- assertEquals(smQuitTest.mS1, pmi.getOriginalState());
+ for (int i = 0; i < 6; i++) {
+ lr = smQuitTest.getLogRec(i);
+ assertEquals(i+1, lr.getWhat());
+ assertEquals(smQuitTest.mS1, lr.getState());
+ assertEquals(smQuitTest.mS1, lr.getOriginalState());
+ }
+ lr = smQuitTest.getLogRec(6);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smQuitTest.mS1, lr.getState());
- pmi = smQuitTest.getProcessedMessageInfo(7);
- assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
- assertEquals(smQuitTest.mS1, pmi.getState());
- assertEquals(smQuitTest.mS1, pmi.getOriginalState());
+ lr = smQuitTest.getLogRec(7);
+ assertEquals(ON_QUITTING, lr.getInfo());
- // The last message was never handled so the states are null
- pmi = smQuitTest.getProcessedMessageInfo(8);
- assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
- assertEquals(null, pmi.getState());
- assertEquals(null, pmi.getOriginalState());
+ synchronized (smQuitTest.mWaitUntilTestDone) {
+ smQuitTest.mWaitUntilTestDone.notifyAll();
+ }
+ if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit X");
+ }
- if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuitTest X");
+ /**
+ * Tests {@link StateMachine#quitNow()}
+ */
+ class StateMachineQuitNowTest extends StateMachine {
+ Object mWaitUntilTestDone = new Object();
+
+ StateMachineQuitNowTest(String name) {
+ super(name);
+ mThisSm = this;
+ setDbg(DBG);
+
+ // Setup state machine with 1 state
+ addState(mS1);
+
+ // Set the initial state
+ setInitialState(mS1);
+ }
+
+ @Override
+ public void onQuitting() {
+ Log.d(TAG, "onQuitting");
+ addLogRec(ON_QUITTING);
+ synchronized (mThisSm) {
+ mThisSm.notifyAll();
+ }
+
+ // Don't leave onQuitting before the test is done as everything is cleared
+ // including the log records.
+ synchronized (mWaitUntilTestDone) {
+ try {
+ mWaitUntilTestDone.wait();
+ } catch(InterruptedException e) {
+ }
+ }
+ }
+
+ class S1 extends State {
+ public void exit() {
+ Log.d(TAG, "S1.exit");
+ addLogRec(EXIT, mS1);
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ switch(message.what) {
+ // Sleep and assume the other messages will be queued up.
+ case TEST_CMD_1: {
+ Log.d(TAG, "TEST_CMD_1");
+ sleep(500);
+ quitNow();
+ break;
+ }
+ default: {
+ Log.d(TAG, "default what=" + message.what);
+ break;
+ }
+ }
+ return HANDLED;
+ }
+ }
+
+ private StateMachineQuitNowTest mThisSm;
+ private S1 mS1 = new S1();
+ }
+
+ @SmallTest
+ public void testStateMachineQuitNow() throws Exception {
+ if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
+
+ StateMachineQuitNowTest smQuitNowTest = new StateMachineQuitNowTest("smQuitNowTest");
+ smQuitNowTest.start();
+ if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow E");
+
+ synchronized (smQuitNowTest) {
+
+ // Send 6 messages but we'll QuitNow on the first so even though
+ // we send 6 only one will be processed.
+ for (int i = 1; i <= 6; i++) {
+ smQuitNowTest.sendMessage(smQuitNowTest.obtainMessage(i));
+ }
+
+ try {
+ // wait for the messages to be handled
+ smQuitNowTest.wait();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "testStateMachineQuitNow: exception while waiting " + e.getMessage());
+ }
+ }
+
+ // Only three records because we executed quitNow.
+ assertEquals(3, smQuitNowTest.getLogRecCount());
+
+ LogRec lr;
+
+ lr = smQuitNowTest.getLogRec(0);
+ assertEquals(1, lr.getWhat());
+ assertEquals(smQuitNowTest.mS1, lr.getState());
+ assertEquals(smQuitNowTest.mS1, lr.getOriginalState());
+
+ lr = smQuitNowTest.getLogRec(1);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smQuitNowTest.mS1, lr.getState());
+
+ lr = smQuitNowTest.getLogRec(2);
+ assertEquals(ON_QUITTING, lr.getInfo());
+
+ synchronized (smQuitNowTest.mWaitUntilTestDone) {
+ smQuitNowTest.mWaitUntilTestDone.notifyAll();
+ }
+ if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow X");
}
/**
* Test enter/exit can use transitionTo
*/
class StateMachineEnterExitTransitionToTest extends StateMachine {
+
StateMachineEnterExitTransitionToTest(String name) {
super(name);
mThisSm = this;
@@ -170,20 +302,15 @@
class S1 extends State {
@Override
public void enter() {
- // Test that message is HSM_INIT_CMD
- assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
- // Test that a transition in enter and the initial state works
- mS1EnterCount += 1;
+ // Test transitions in enter on the initial state work
+ addLogRec(ENTER, mS1);
transitionTo(mS2);
Log.d(TAG, "S1.enter");
}
@Override
public void exit() {
// Test that message is HSM_INIT_CMD
- assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
- mS1ExitCount += 1;
+ addLogRec(EXIT, mS1);
Log.d(TAG, "S1.exit");
}
}
@@ -191,19 +318,15 @@
class S2 extends State {
@Override
public void enter() {
- // Test that message is HSM_INIT_CMD
- assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
- mS2EnterCount += 1;
+ addLogRec(ENTER, mS2);
Log.d(TAG, "S2.enter");
}
@Override
public void exit() {
- // Test that message is TEST_CMD_1
+ addLogRec(EXIT, mS2);
assertEquals(TEST_CMD_1, getCurrentMessage().what);
// Test transition in exit work
- mS2ExitCount += 1;
transitionTo(mS4);
Log.d(TAG, "S2.exit");
}
@@ -220,36 +343,33 @@
class S3 extends State {
@Override
public void enter() {
- // Test that we can do halting in an enter/exit
- transitionToHaltingState();
- mS3EnterCount += 1;
+ addLogRec(ENTER, mS3);
Log.d(TAG, "S3.enter");
}
@Override
public void exit() {
- mS3ExitCount += 1;
+ addLogRec(EXIT, mS3);
Log.d(TAG, "S3.exit");
}
}
-
class S4 extends State {
@Override
public void enter() {
+ addLogRec(ENTER, mS4);
// Test that we can do halting in an enter/exit
transitionToHaltingState();
- mS4EnterCount += 1;
Log.d(TAG, "S4.enter");
}
@Override
public void exit() {
- mS4ExitCount += 1;
+ addLogRec(EXIT, mS4);
Log.d(TAG, "S4.exit");
}
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -260,14 +380,6 @@
private S2 mS2 = new S2();
private S3 mS3 = new S3();
private S4 mS4 = new S4();
- private int mS1EnterCount = 0;
- private int mS1ExitCount = 0;
- private int mS2EnterCount = 0;
- private int mS2ExitCount = 0;
- private int mS3EnterCount = 0;
- private int mS3ExitCount = 0;
- private int mS4EnterCount = 0;
- private int mS4ExitCount = 0;
}
@SmallTest
@@ -293,24 +405,46 @@
}
}
- assertTrue(smEnterExitTranstionToTest.getProcessedMessagesCount() == 1);
+ assertEquals(smEnterExitTranstionToTest.getLogRecCount(), 9);
- ProcessedMessageInfo pmi;
+ LogRec lr;
- // Message should be handled by mS2.
- pmi = smEnterExitTranstionToTest.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(smEnterExitTranstionToTest.mS2, pmi.getState());
- assertEquals(smEnterExitTranstionToTest.mS2, pmi.getOriginalState());
+ lr = smEnterExitTranstionToTest.getLogRec(0);
+ assertEquals(ENTER, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
- assertEquals(smEnterExitTranstionToTest.mS1EnterCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS1ExitCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS2EnterCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS2ExitCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS3EnterCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS3ExitCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS3EnterCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS3ExitCount, 1);
+ lr = smEnterExitTranstionToTest.getLogRec(1);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(2);
+ assertEquals(ENTER, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(3);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+ assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(4);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(5);
+ assertEquals(ENTER, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(6);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(7);
+ assertEquals(ENTER, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(8);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
if (smEnterExitTranstionToTest.isDbg()) {
Log.d(TAG, "testStateMachineEnterExitTransitionToTest X");
@@ -325,7 +459,7 @@
super(name);
mThisSm = this;
setDbg(DBG);
- setProcessedMessagesSize(3);
+ setLogRecSize(3);
// Setup state machine with 1 state
addState(mS1);
@@ -345,7 +479,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -377,24 +511,24 @@
}
}
- assertTrue(sm0.getProcessedMessagesCount() == 6);
- assertTrue(sm0.getProcessedMessagesSize() == 3);
+ assertEquals(6, sm0.getLogRecCount());
+ assertEquals(3, sm0.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm0.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_4, pmi.getWhat());
- assertEquals(sm0.mS1, pmi.getState());
- assertEquals(sm0.mS1, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm0.getLogRec(0);
+ assertEquals(TEST_CMD_4, lr.getWhat());
+ assertEquals(sm0.mS1, lr.getState());
+ assertEquals(sm0.mS1, lr.getOriginalState());
- pmi = sm0.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_5, pmi.getWhat());
- assertEquals(sm0.mS1, pmi.getState());
- assertEquals(sm0.mS1, pmi.getOriginalState());
+ lr = sm0.getLogRec(1);
+ assertEquals(TEST_CMD_5, lr.getWhat());
+ assertEquals(sm0.mS1, lr.getState());
+ assertEquals(sm0.mS1, lr.getOriginalState());
- pmi = sm0.getProcessedMessageInfo(2);
- assertEquals(TEST_CMD_6, pmi.getWhat());
- assertEquals(sm0.mS1, pmi.getState());
- assertEquals(sm0.mS1, pmi.getOriginalState());
+ lr = sm0.getLogRec(2);
+ assertEquals(TEST_CMD_6, lr.getWhat());
+ assertEquals(sm0.mS1, lr.getState());
+ assertEquals(sm0.mS1, lr.getOriginalState());
if (sm0.isDbg()) Log.d(TAG, "testStateMachine0 X");
}
@@ -444,7 +578,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -479,18 +613,18 @@
assertEquals(2, sm1.mEnterCount);
assertEquals(2, sm1.mExitCount);
- assertTrue(sm1.getProcessedMessagesSize() == 2);
+ assertEquals(2, sm1.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm1.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm1.mS1, pmi.getState());
- assertEquals(sm1.mS1, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm1.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm1.mS1, lr.getState());
+ assertEquals(sm1.mS1, lr.getOriginalState());
- pmi = sm1.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm1.mS1, pmi.getState());
- assertEquals(sm1.mS1, pmi.getOriginalState());
+ lr = sm1.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm1.mS1, lr.getState());
+ assertEquals(sm1.mS1, lr.getOriginalState());
assertEquals(2, sm1.mEnterCount);
assertEquals(2, sm1.mExitCount);
@@ -550,7 +684,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -583,24 +717,24 @@
}
}
- assertTrue(sm2.getProcessedMessagesSize() == 4);
+ assertEquals(4, sm2.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm2.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm2.mS1, pmi.getState());
+ LogRec lr;
+ lr = sm2.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm2.mS1, lr.getState());
- pmi = sm2.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm2.mS1, pmi.getState());
+ lr = sm2.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm2.mS1, lr.getState());
- pmi = sm2.getProcessedMessageInfo(2);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm2.mS2, pmi.getState());
+ lr = sm2.getLogRec(2);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm2.mS2, lr.getState());
- pmi = sm2.getProcessedMessageInfo(3);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm2.mS2, pmi.getState());
+ lr = sm2.getLogRec(3);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm2.mS2, lr.getState());
assertTrue(sm2.mDidEnter);
assertTrue(sm2.mDidExit);
@@ -647,7 +781,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -677,18 +811,18 @@
}
}
- assertTrue(sm3.getProcessedMessagesSize() == 2);
+ assertEquals(2, sm3.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm3.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm3.mParentState, pmi.getState());
- assertEquals(sm3.mChildState, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm3.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm3.mParentState, lr.getState());
+ assertEquals(sm3.mChildState, lr.getOriginalState());
- pmi = sm3.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm3.mParentState, pmi.getState());
- assertEquals(sm3.mChildState, pmi.getOriginalState());
+ lr = sm3.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm3.mParentState, lr.getState());
+ assertEquals(sm3.mChildState, lr.getOriginalState());
if (sm3.isDbg()) Log.d(TAG, "testStateMachine3 X");
}
@@ -742,7 +876,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -774,18 +908,18 @@
}
- assertTrue(sm4.getProcessedMessagesSize() == 2);
+ assertEquals(2, sm4.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm4.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm4.mChildState1, pmi.getState());
- assertEquals(sm4.mChildState1, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm4.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm4.mChildState1, lr.getState());
+ assertEquals(sm4.mChildState1, lr.getOriginalState());
- pmi = sm4.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm4.mParentState, pmi.getState());
- assertEquals(sm4.mChildState2, pmi.getOriginalState());
+ lr = sm4.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm4.mParentState, lr.getState());
+ assertEquals(sm4.mChildState2, lr.getOriginalState());
if (sm4.isDbg()) Log.d(TAG, "testStateMachine4 X");
}
@@ -1018,7 +1152,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -1073,7 +1207,7 @@
}
- assertTrue(sm5.getProcessedMessagesSize() == 6);
+ assertEquals(6, sm5.getLogRecSize());
assertEquals(1, sm5.mParentState1EnterCount);
assertEquals(1, sm5.mParentState1ExitCount);
@@ -1090,36 +1224,36 @@
assertEquals(1, sm5.mChildState5EnterCount);
assertEquals(1, sm5.mChildState5ExitCount);
- ProcessedMessageInfo pmi;
- pmi = sm5.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm5.mChildState1, pmi.getState());
- assertEquals(sm5.mChildState1, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm5.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm5.mChildState1, lr.getState());
+ assertEquals(sm5.mChildState1, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm5.mChildState2, pmi.getState());
- assertEquals(sm5.mChildState2, pmi.getOriginalState());
+ lr = sm5.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm5.mChildState2, lr.getState());
+ assertEquals(sm5.mChildState2, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(2);
- assertEquals(TEST_CMD_3, pmi.getWhat());
- assertEquals(sm5.mChildState5, pmi.getState());
- assertEquals(sm5.mChildState5, pmi.getOriginalState());
+ lr = sm5.getLogRec(2);
+ assertEquals(TEST_CMD_3, lr.getWhat());
+ assertEquals(sm5.mChildState5, lr.getState());
+ assertEquals(sm5.mChildState5, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(3);
- assertEquals(TEST_CMD_4, pmi.getWhat());
- assertEquals(sm5.mChildState3, pmi.getState());
- assertEquals(sm5.mChildState3, pmi.getOriginalState());
+ lr = sm5.getLogRec(3);
+ assertEquals(TEST_CMD_4, lr.getWhat());
+ assertEquals(sm5.mChildState3, lr.getState());
+ assertEquals(sm5.mChildState3, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(4);
- assertEquals(TEST_CMD_5, pmi.getWhat());
- assertEquals(sm5.mChildState4, pmi.getState());
- assertEquals(sm5.mChildState4, pmi.getOriginalState());
+ lr = sm5.getLogRec(4);
+ assertEquals(TEST_CMD_5, lr.getWhat());
+ assertEquals(sm5.mChildState4, lr.getState());
+ assertEquals(sm5.mChildState4, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(5);
- assertEquals(TEST_CMD_6, pmi.getWhat());
- assertEquals(sm5.mParentState2, pmi.getState());
- assertEquals(sm5.mParentState2, pmi.getOriginalState());
+ lr = sm5.getLogRec(5);
+ assertEquals(TEST_CMD_6, lr.getWhat());
+ assertEquals(sm5.mParentState2, lr.getState());
+ assertEquals(sm5.mParentState2, lr.getOriginalState());
if (sm5.isDbg()) Log.d(TAG, "testStateMachine5 X");
}
@@ -1161,7 +1295,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -1176,7 +1310,6 @@
@MediumTest
public void testStateMachine6() throws Exception {
- long sentTimeMsg2;
final int DELAY_TIME = 250;
final int DELAY_FUDGE = 20;
@@ -1186,7 +1319,6 @@
synchronized (sm6) {
// Send a message
- sentTimeMsg2 = SystemClock.elapsedRealtime();
sm6.sendMessageDelayed(TEST_CMD_2, DELAY_TIME);
try {
@@ -1268,7 +1400,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -1285,7 +1417,6 @@
@MediumTest
public void testStateMachine7() throws Exception {
- long sentTimeMsg2;
final int SM7_DELAY_FUDGE = 20;
StateMachine7 sm7 = new StateMachine7("sm7");
@@ -1294,7 +1425,6 @@
synchronized (sm7) {
// Send a message
- sentTimeMsg2 = SystemClock.elapsedRealtime();
sm7.sendMessage(TEST_CMD_1);
try {
@@ -1350,7 +1480,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -1383,7 +1513,7 @@
}
}
- assertTrue(sm.getProcessedMessagesCount() == 2);
+ assertEquals(sm.getLogRecCount(), 2);
assertEquals(2, sm.mUnhandledMessageCount);
if (sm.isDbg()) Log.d(TAG, "testStateMachineUnhandledMessage X");
@@ -1420,7 +1550,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
// Update the shared counter, which is OK since all state
// machines are using the same thread.
sharedCounter += 1;
@@ -1470,12 +1600,12 @@
}
for (StateMachineSharedThread sm : sms) {
- assertTrue(sm.getProcessedMessagesCount() == 4);
- for (int i = 0; i < sm.getProcessedMessagesCount(); i++) {
- ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(i);
- assertEquals(i+1, pmi.getWhat());
- assertEquals(sm.mS1, pmi.getState());
- assertEquals(sm.mS1, pmi.getOriginalState());
+ assertEquals(sm.getLogRecCount(), 4);
+ for (int i = 0; i < sm.getLogRecCount(); i++) {
+ LogRec lr = sm.getLogRec(i);
+ assertEquals(i+1, lr.getWhat());
+ assertEquals(sm.mS1, lr.getState());
+ assertEquals(sm.mS1, lr.getOriginalState());
}
}
@@ -1501,41 +1631,41 @@
}
}
- assertEquals(7, sm.getProcessedMessagesCount());
- ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(0);
- assertEquals(Hsm1.CMD_1, pmi.getWhat());
- assertEquals(sm.mS1, pmi.getState());
- assertEquals(sm.mS1, pmi.getOriginalState());
+ assertEquals(7, sm.getLogRecCount());
+ LogRec lr = sm.getLogRec(0);
+ assertEquals(Hsm1.CMD_1, lr.getWhat());
+ assertEquals(sm.mS1, lr.getState());
+ assertEquals(sm.mS1, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(1);
- assertEquals(Hsm1.CMD_2, pmi.getWhat());
- assertEquals(sm.mP1, pmi.getState());
- assertEquals(sm.mS1, pmi.getOriginalState());
+ lr = sm.getLogRec(1);
+ assertEquals(Hsm1.CMD_2, lr.getWhat());
+ assertEquals(sm.mP1, lr.getState());
+ assertEquals(sm.mS1, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(2);
- assertEquals(Hsm1.CMD_2, pmi.getWhat());
- assertEquals(sm.mS2, pmi.getState());
- assertEquals(sm.mS2, pmi.getOriginalState());
+ lr = sm.getLogRec(2);
+ assertEquals(Hsm1.CMD_2, lr.getWhat());
+ assertEquals(sm.mS2, lr.getState());
+ assertEquals(sm.mS2, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(3);
- assertEquals(Hsm1.CMD_3, pmi.getWhat());
- assertEquals(sm.mS2, pmi.getState());
- assertEquals(sm.mS2, pmi.getOriginalState());
+ lr = sm.getLogRec(3);
+ assertEquals(Hsm1.CMD_3, lr.getWhat());
+ assertEquals(sm.mS2, lr.getState());
+ assertEquals(sm.mS2, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(4);
- assertEquals(Hsm1.CMD_3, pmi.getWhat());
- assertEquals(sm.mP2, pmi.getState());
- assertEquals(sm.mP2, pmi.getOriginalState());
+ lr = sm.getLogRec(4);
+ assertEquals(Hsm1.CMD_3, lr.getWhat());
+ assertEquals(sm.mP2, lr.getState());
+ assertEquals(sm.mP2, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(5);
- assertEquals(Hsm1.CMD_4, pmi.getWhat());
- assertEquals(sm.mP2, pmi.getState());
- assertEquals(sm.mP2, pmi.getOriginalState());
+ lr = sm.getLogRec(5);
+ assertEquals(Hsm1.CMD_4, lr.getWhat());
+ assertEquals(sm.mP2, lr.getState());
+ assertEquals(sm.mP2, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(6);
- assertEquals(Hsm1.CMD_5, pmi.getWhat());
- assertEquals(sm.mP2, pmi.getState());
- assertEquals(sm.mP2, pmi.getOriginalState());
+ lr = sm.getLogRec(6);
+ assertEquals(Hsm1.CMD_5, lr.getWhat());
+ assertEquals(sm.mP2, lr.getState());
+ assertEquals(sm.mP2, lr.getOriginalState());
if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
}
@@ -1684,7 +1814,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
Log.d(TAG, "halting");
synchronized (this) {
this.notifyAll();
diff --git a/core/tests/overlaytests/OverlayTestOverlay/Android.mk b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
index cf32c9f..b1327f71 100644
--- a/core/tests/overlaytests/OverlayTestOverlay/Android.mk
+++ b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
@@ -9,6 +9,4 @@
LOCAL_PACKAGE_NAME := com.android.overlaytest.overlay
-LOCAL_AAPT_FLAGS := -o
-
include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/OverlayTestOverlay/res/drawable/default_wallpaper.jpg b/core/tests/overlaytests/OverlayTestOverlay/res/drawable-nodpi/default_wallpaper.jpg
similarity index 100%
rename from core/tests/overlaytests/OverlayTestOverlay/res/drawable/default_wallpaper.jpg
rename to core/tests/overlaytests/OverlayTestOverlay/res/drawable-nodpi/default_wallpaper.jpg
Binary files differ
diff --git a/core/tests/overlaytests/runtests.sh b/core/tests/overlaytests/runtests.sh
index 0ad9efb..0a721ad40 100755
--- a/core/tests/overlaytests/runtests.sh
+++ b/core/tests/overlaytests/runtests.sh
@@ -18,7 +18,6 @@
log=$(mktemp)
trap "atexit" EXIT
-failures=0
function compile_module()
{
@@ -38,6 +37,37 @@
$adb wait-for-device logcat | grep -m 1 -e 'PowerManagerService.*bootCompleted' >/dev/null
}
+function mkdir_if_needed()
+{
+ local path="$1"
+
+ if [[ "${path:0:1}" != "/" ]]; then
+ echo "mkdir_if_needed: error: path '$path' does not begin with /" | tee -a $log
+ exit 1
+ fi
+
+ local basename=$(basename "$path")
+ local dirname=$(dirname "$path")
+ local t=$($adb shell ls -l $dirname | tr -d '\r' | grep -e "${basename}$" | grep -oe '^.')
+
+ case "$t" in
+ d) # File exists, and is a directory ...
+ # do nothing
+ ;;
+ l) # ... (or symbolic link possibly to a directory).
+ # do nothing
+ ;;
+ "") # File does not exist.
+ mkdir_if_needed "$dirname"
+ $adb shell mkdir "$path"
+ ;;
+ *) # File exists, but is not a directory.
+ echo "mkdir_if_needed: file '$path' exists, but is not a directory" | tee -a $log
+ exit 1
+ ;;
+ esac
+}
+
function disable_overlay()
{
echo "Disabling overlay"
@@ -48,6 +78,8 @@
function enable_overlay()
{
echo "Enabling overlay"
+ mkdir_if_needed "/system/vendor"
+ mkdir_if_needed "/vendor/overlay/framework"
$adb shell ln -s /data/app/com.android.overlaytest.overlay.apk /vendor/overlay/framework/framework-res.apk
}
@@ -59,13 +91,21 @@
$adb shell am instrument -w -e class $class com.android.overlaytest/android.test.InstrumentationTestRunner | tee -a $log
}
+function remount()
+{
+ echo "Remounting file system writable"
+ $adb remount | tee -a $log
+}
+
function sync()
{
echo "Syncing to device"
- $adb remount | tee -a $log
$adb sync data | tee -a $log
}
+# some commands require write access, remount once and for all
+remount
+
# build and sync
compile_module "$PWD/OverlayTest/Android.mk"
compile_module "$PWD/OverlayTestOverlay/Android.mk"
diff --git a/data/etc/Android.mk b/data/etc/Android.mk
index 71a9a15..134ac0c 100644
--- a/data/etc/Android.mk
+++ b/data/etc/Android.mk
@@ -21,8 +21,6 @@
LOCAL_MODULE := platform.xml
-LOCAL_MODULE_TAGS := user
-
LOCAL_MODULE_CLASS := ETC
# This will install the file in /system/etc/permissions
@@ -38,8 +36,6 @@
#LOCAL_MODULE := required_hardware.xml
-#LOCAL_MODULE_TAGS := user
-
#LOCAL_MODULE_CLASS := ETC
# This will install the file in /system/etc/permissions
diff --git a/drm/jni/Android.mk b/drm/jni/Android.mk
index f8ecc8c..fff7eee 100644
--- a/drm/jni/Android.mk
+++ b/drm/jni/Android.mk
@@ -35,7 +35,8 @@
$(JNI_H_INCLUDE) \
$(TOP)/frameworks/av/drm/libdrmframework/include \
$(TOP)/frameworks/av/drm/libdrmframework/plugins/common/include \
- $(TOP)/frameworks/av/include
+ $(TOP)/frameworks/av/include \
+ $(TOP)/libcore/include
diff --git a/drm/jni/android_drm_DrmManagerClient.cpp b/drm/jni/android_drm_DrmManagerClient.cpp
index 14ec4d6..fb685a2 100644
--- a/drm/jni/android_drm_DrmManagerClient.cpp
+++ b/drm/jni/android_drm_DrmManagerClient.cpp
@@ -20,6 +20,7 @@
#include <jni.h>
#include <JNIHelp.h>
+#include <ScopedLocalRef.h>
#include <android_runtime/AndroidRuntime.h>
#include <drm/DrmInfo.h>
@@ -250,16 +251,18 @@
= getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
jclass localRef = env->FindClass("android/content/ContentValues");
+ jmethodID ContentValues_putByteArray =
+ env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V");
+ jmethodID ContentValues_putString =
+ env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
+ jmethodID ContentValues_constructor = env->GetMethodID(localRef, "<init>", "()V");
jobject constraints = NULL;
if (NULL != localRef && NULL != pConstraints) {
- // Get the constructor id
- jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
// create the java DrmConstraints object
- constraints = env->NewObject(localRef, constructorId);
+ constraints = env->NewObject(localRef, ContentValues_constructor);
DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
-
while (keyIt.hasNext()) {
String8 key = keyIt.next();
@@ -267,18 +270,18 @@
if (DrmConstraints::EXTENDED_METADATA == key) {
const char* value = pConstraints->getAsByteArray(&key);
if (NULL != value) {
- jbyteArray dataArray = env->NewByteArray(strlen(value));
- env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
- env->CallVoidMethod(
- constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
- env->NewStringUTF(key.string()), dataArray);
+ ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(strlen(value)));
+ ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+ env->SetByteArrayRegion(dataArray.get(), 0, strlen(value), (jbyte*)value);
+ env->CallVoidMethod(constraints, ContentValues_putByteArray,
+ keyString.get(), dataArray.get());
}
} else {
String8 value = pConstraints->get(key);
- env->CallVoidMethod(
- constraints,
- env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
- env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+ ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+ ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
+ env->CallVoidMethod(constraints, ContentValues_putString,
+ keyString.get(), valueString.get());
}
}
}
@@ -297,8 +300,10 @@
jobject metadata = NULL;
- jclass localRef = NULL;
- localRef = env->FindClass("android/content/ContentValues");
+ jclass localRef = env->FindClass("android/content/ContentValues");
+ jmethodID ContentValues_putString =
+ env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
+
if (NULL != localRef && NULL != pMetadata) {
// Get the constructor id
jmethodID constructorId = NULL;
@@ -313,9 +318,10 @@
// insert the entry<constraintKey, constraintValue>
// to newly created java object
String8 value = pMetadata->get(key);
- env->CallVoidMethod(metadata, env->GetMethodID(localRef, "put",
- "(Ljava/lang/String;Ljava/lang/String;)V"),
- env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+ ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+ ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
+ env->CallVoidMethod(metadata, ContentValues_putString,
+ keyString.get(), valueString.get());
}
}
}
@@ -426,29 +432,30 @@
DrmInfo drmInfo(mInfoType, buffer, mMimeType);
jclass clazz = env->FindClass("android/drm/DrmInfo");
+ jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject keyIterator
= env->CallObjectMethod(drmInfoObject,
env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
- jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
+ jclass Iterator_class = env->FindClass("java/util/Iterator");
+ jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
+ jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
- while (env->CallBooleanMethod(keyIterator, hasNextId)) {
- jstring key = (jstring) env->CallObjectMethod(keyIterator,
- env->GetMethodID(env->FindClass("java/util/Iterator"),
- "next", "()Ljava/lang/Object;"));
+ jclass Object_class = env->FindClass("java/lang/Object");
+ jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;");
- jobject valueObject = env->CallObjectMethod(drmInfoObject,
- env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
-
- jstring valString = NULL;
- if (NULL != valueObject) {
- valString = (jstring) env->CallObjectMethod(valueObject,
- env->GetMethodID(env->FindClass("java/lang/Object"),
- "toString", "()Ljava/lang/String;"));
+ while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
+ ScopedLocalRef<jstring> key(env,
+ (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
+ ScopedLocalRef<jobject> valueObject(env,
+ env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get()));
+ ScopedLocalRef<jstring> valString(env, NULL);
+ if (NULL != valueObject.get()) {
+ valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString));
}
- String8 keyString = Utility::getStringValue(env, key);
- String8 valueString = Utility::getStringValue(env, valString);
+ String8 keyString = Utility::getStringValue(env, key.get());
+ String8 valueString = Utility::getStringValue(env, valString.get());
ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
drmInfo.put(keyString, valueString);
@@ -508,20 +515,21 @@
jobject keyIterator
= env->CallObjectMethod(drmInfoRequest,
env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
+ jmethodID DrmInfoRequest_get = env->GetMethodID(clazz,
+ "get", "(Ljava/lang/String;)Ljava/lang/Object;");
- jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
+ jclass Iterator_class = env->FindClass("java/util/Iterator");
+ jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
+ jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
- while (env->CallBooleanMethod(keyIterator, hasNextId)) {
- jstring key
- = (jstring) env->CallObjectMethod(keyIterator,
- env->GetMethodID(env->FindClass("java/util/Iterator"),
- "next", "()Ljava/lang/Object;"));
+ while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
+ ScopedLocalRef<jstring> key(env,
+ (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
+ ScopedLocalRef<jstring> value(env,
+ (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get()));
- jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
- env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
-
- String8 keyString = Utility::getStringValue(env, key);
- String8 valueString = Utility::getStringValue(env, value);
+ String8 keyString = Utility::getStringValue(env, key.get());
+ String8 valueString = Utility::getStringValue(env, value.get());
ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
drmInfoReq.put(keyString, valueString);
@@ -552,9 +560,10 @@
while (it.hasNext()) {
String8 key = it.next();
String8 value = pDrmInfo->get(key);
-
+ ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+ ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
env->CallVoidMethod(drmInfoObject, putMethodId,
- env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+ keyString.get(), valueString.get());
}
}
delete [] pDrmInfo->getData().data;
diff --git a/keystore/tests/AndroidManifest.xml b/keystore/tests/AndroidManifest.xml
index 1a5f065..415442f 100644
--- a/keystore/tests/AndroidManifest.xml
+++ b/keystore/tests/AndroidManifest.xml
@@ -22,7 +22,7 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name=".KeyStoreTestRunner"
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="android.security.tests"
android:label="KeyStore Tests">
</instrumentation>
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 32cd6e2..9f35b8d 100755
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.tests;
+package android.security;
import android.app.Activity;
import android.security.KeyStore;
@@ -29,7 +29,11 @@
*
* Running the test suite:
*
- * adb shell am instrument -w android.security.tests/.KeyStoreTestRunner
+ * runtest keystore-unit
+ *
+ * Or this individual test case:
+ *
+ * runtest --path frameworks/base/keystore/tests/src/android/security/KeyStoreTest.java
*/
@MediumTest
public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
diff --git a/keystore/tests/src/android/security/KeyStoreTestRunner.java b/keystore/tests/src/android/security/KeyStoreTestRunner.java
deleted file mode 100644
index c56eeb9..0000000
--- a/keystore/tests/src/android/security/KeyStoreTestRunner.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2009 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.security.tests;
-
-import junit.framework.TestSuite;
-
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-
-/**
- * Instrumentation Test Runner for all KeyStore unit tests.
- *
- * Running all tests:
- *
- * runtest keystore-unit
- * or
- * adb shell am instrument -w android.security.tests/.KeyStoreTestRunner
- */
-
-public class KeyStoreTestRunner extends InstrumentationTestRunner {
-
- @Override
- public TestSuite getAllTests() {
- TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(android.security.tests.KeyStoreTest.class);
- suite.addTestSuite(android.security.tests.SystemKeyStoreTest.class);
- return suite;
- }
-
- @Override
- public ClassLoader getLoader() {
- return KeyStoreTestRunner.class.getClassLoader();
- }
-}
diff --git a/keystore/tests/src/android/security/SystemKeyStoreTest.java b/keystore/tests/src/android/security/SystemKeyStoreTest.java
index a4d744b..ecf7cbc 100644
--- a/keystore/tests/src/android/security/SystemKeyStoreTest.java
+++ b/keystore/tests/src/android/security/SystemKeyStoreTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.tests;
+package android.security;
import android.app.Activity;
import android.security.SystemKeyStore;
@@ -26,7 +26,11 @@
*
* Running the test suite:
*
- * adb shell am instrument -w android.security.tests/.KeyStoreTestRunner
+ * runtest keystore-unit
+ *
+ * Or this individual test case:
+ *
+ * runtest --path frameworks/base/keystore/tests/src/android/security/SystemKeyStoreTest.java
*/
@MediumTest
public class SystemKeyStoreTest extends ActivityUnitTestCase<Activity> {
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index f3a1d9a..8cce191 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -5159,7 +5159,8 @@
const uint32_t pkg_id = pkg->package->id << 24;
for (size_t typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
- ssize_t offset = -1;
+ ssize_t first = -1;
+ ssize_t last = -1;
const Type* typeConfigs = pkg->getType(typeIndex);
ssize_t mapIndex = map.add();
if (mapIndex < 0) {
@@ -5167,12 +5168,14 @@
}
Vector<uint32_t>& vector = map.editItemAt(mapIndex);
for (size_t entryIndex = 0; entryIndex < typeConfigs->entryCount; ++entryIndex) {
- uint32_t resID = (0xff000000 & ((pkg->package->id)<<24))
+ uint32_t resID = pkg_id
| (0x00ff0000 & ((typeIndex+1)<<16))
| (0x0000ffff & (entryIndex));
resource_name resName;
if (!this->getResourceName(resID, &resName)) {
ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID);
+ // add dummy value, or trimming leading/trailing zeroes later will fail
+ vector.push(0);
continue;
}
@@ -5185,13 +5188,13 @@
overlayPackage.string(),
overlayPackage.size());
if (overlayResID != 0) {
- // overlay package has package ID == 0, use original package's ID instead
- overlayResID |= pkg_id;
+ overlayResID = pkg_id | (0x00ffffff & overlayResID);
+ last = Res_GETENTRY(resID);
+ if (first == -1) {
+ first = Res_GETENTRY(resID);
+ }
}
vector.push(overlayResID);
- if (overlayResID != 0 && offset == -1) {
- offset = Res_GETENTRY(resID);
- }
#if 0
if (overlayResID != 0) {
ALOGD("%s/%s 0x%08x -> 0x%08x\n",
@@ -5202,13 +5205,16 @@
#endif
}
- if (offset != -1) {
- // shave off leading and trailing entries which lack overlay values
- vector.removeItemsAt(0, offset);
- vector.insertAt((uint32_t)offset, 0, 1);
- while (vector.top() == 0) {
- vector.pop();
+ if (first != -1) {
+ // shave off trailing entries which lack overlay values
+ const size_t last_past_one = last + 1;
+ if (last_past_one < vector.size()) {
+ vector.removeItemsAt(last_past_one, vector.size() - last_past_one);
}
+ // shave off leading entries which lack overlay values
+ vector.removeItemsAt(0, first);
+ // store offset to first overlaid resource ID of this type
+ vector.insertAt((uint32_t)first, 0, 1);
// reserve space for number and offset of entries, and the actual entries
*outSize += (2 + vector.size()) * sizeof(uint32_t);
} else {
@@ -5246,6 +5252,10 @@
if (N == 0) {
continue;
}
+ if (N == 1) { // vector expected to hold (offset) + (N > 0 entries)
+ ALOGW("idmap: type %d supposedly has entries, but no entries found\n", i);
+ return UNKNOWN_ERROR;
+ }
*data++ = htodl(N - 1); // do not count the offset (which is vector's first element)
for (size_t j = 0; j < N; ++j) {
const uint32_t& overlayResID = vector.itemAt(j);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 0d6e62a..b51b1e1 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -617,7 +617,7 @@
uint32_t* retOriginX, uint32_t* retOriginY) {
cachedGlyph->mIsValid = false;
// If the glyph is too tall, don't cache it
- if (glyph.fHeight + TEXTURE_BORDER_SIZE > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
+ if (mCacheLines.size() != 0 && (glyph.fHeight + TEXTURE_BORDER_SIZE > mCacheLines[mCacheLines.size() - 1]->mMaxHeight)) {
ALOGE("Font size to large to fit in cache. width, height = %i, %i",
(int) glyph.fWidth, (int) glyph.fHeight);
return;
@@ -946,6 +946,11 @@
uint32_t FontRenderer::getRemainingCacheCapacity() {
uint32_t remainingCapacity = 0;
float totalPixels = 0;
+
+ //avoid divide by zero if the size is 0
+ if (mCacheLines.size() == 0) {
+ return 0;
+ }
for(uint32_t i = 0; i < mCacheLines.size(); i ++) {
remainingCapacity += (mCacheLines[i]->mMaxWidth - mCacheLines[i]->mCurrentCol);
totalPixels += mCacheLines[i]->mMaxWidth;
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 560c549..99db066 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -33,7 +33,6 @@
* codec.start();
* ByteBuffer[] inputBuffers = codec.getInputBuffers();
* ByteBuffer[] outputBuffers = codec.getOutputBuffers();
- * MediaFormat format = codec.getOutputFormat();
* for (;;) {
* int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
* if (inputBufferIndex >= 0) {
@@ -51,7 +50,7 @@
* outputBuffers = codec.getOutputBuffers();
* } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
* // Subsequent data will conform to new format.
- * format = codec.getOutputFormat();
+ * MediaFormat format = codec.getOutputFormat();
* ...
* }
* }
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index c9bec18..d21ada4 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -172,6 +172,7 @@
static {
addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
+ addFileType("MPGA", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3);
addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG);
addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav", MtpConstants.FORMAT_WAV);
addFileType("AMR", FILE_TYPE_AMR, "audio/amr");
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 9af201d..613354f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -351,12 +351,11 @@
*/
public void setCaptureRate(double fps) {
// Make sure that time lapse is enabled when this method is called.
- setParameter(String.format("time-lapse-enable=1"));
+ setParameter("time-lapse-enable=1");
double timeBetweenFrameCapture = 1 / fps;
int timeBetweenFrameCaptureMs = (int) (1000 * timeBetweenFrameCapture);
- setParameter(String.format("time-between-time-lapse-frame-capture=%d",
- timeBetweenFrameCaptureMs));
+ setParameter("time-between-time-lapse-frame-capture=" + timeBetweenFrameCaptureMs);
}
/**
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 6f8b809..fd37bcf 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1399,7 +1399,8 @@
long lastModifiedSeconds = file.lastModified() / 1000;
if (!MediaFile.isAudioFileType(fileType) && !MediaFile.isVideoFileType(fileType) &&
- !MediaFile.isImageFileType(fileType) && !MediaFile.isPlayListFileType(fileType)) {
+ !MediaFile.isImageFileType(fileType) && !MediaFile.isPlayListFileType(fileType) &&
+ !MediaFile.isDrmFileType(fileType)) {
// no need to use the media scanner, but we need to update last modified and file size
ContentValues values = new ContentValues();
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 7532d79..a0325dd 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -492,6 +492,7 @@
MtpConstants.FORMAT_MPEG,
MtpConstants.FORMAT_EXIF_JPEG,
MtpConstants.FORMAT_TIFF_EP,
+ MtpConstants.FORMAT_BMP,
MtpConstants.FORMAT_GIF,
MtpConstants.FORMAT_JFIF,
MtpConstants.FORMAT_PNG,
diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java
index 2f47aad..9cf65a3 100644
--- a/media/java/android/mtp/MtpStorage.java
+++ b/media/java/android/mtp/MtpStorage.java
@@ -39,7 +39,7 @@
mStorageId = volume.getStorageId();
mPath = volume.getPath();
mDescription = context.getResources().getString(volume.getDescriptionId());
- mReserveSpace = volume.getMtpReserveSpace();
+ mReserveSpace = volume.getMtpReserveSpace() * 1024 * 1024;
mRemovable = volume.isRemovable();
mMaxFileSize = volume.getMaxFileSize();
}
@@ -87,7 +87,7 @@
* Returns the amount of space to reserve on the storage file system.
* This can be set to a non-zero value to prevent MTP from filling up the entire storage.
*
- * @return the storage unit description
+ * @return reserved space in bytes.
*/
public final long getReserveSpace() {
return mReserveSpace;
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index e43e66e..4941ae5 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -96,7 +96,10 @@
}
JMediaCodec::~JMediaCodec() {
- mCodec->release();
+ if (mCodec != NULL) {
+ mCodec->release();
+ mCodec.clear();
+ }
JNIEnv *env = AndroidRuntime::getJNIEnv();
diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp
index 4e0e0f2..4982a47 100755
--- a/media/jni/mediaeditor/VideoEditorClasses.cpp
+++ b/media/jni/mediaeditor/VideoEditorClasses.cpp
@@ -1853,6 +1853,9 @@
// Get the clip settings.
videoEditClasses_getClipSettings(pResult, pEnv, clipSettings,
&pSettings->pClipList[i]);
+
+ // Free the local references to avoid memory leaks
+ pEnv->DeleteLocalRef(clipSettings);
}
}
}
@@ -1877,6 +1880,9 @@
// Get the transition settings.
videoEditClasses_getTransitionSettings(pResult, pEnv,
transitionSettings, &pSettings->pTransitionList[i]);
+
+ // Free the local references to avoid memory leaks
+ pEnv->DeleteLocalRef(transitionSettings);
}
}
}
@@ -1900,6 +1906,9 @@
// Get the effect settings.
videoEditClasses_getEffectSettings(pResult, pEnv, effectSettings,
&pSettings->Effects[i]);
+
+ // Free the local references to avoid memory leaks
+ pEnv->DeleteLocalRef(effectSettings);
}
}
}
diff --git a/media/jni/mediaeditor/VideoEditorJava.cpp b/media/jni/mediaeditor/VideoEditorJava.cpp
index ec8050f..bcf9099 100755
--- a/media/jni/mediaeditor/VideoEditorJava.cpp
+++ b/media/jni/mediaeditor/VideoEditorJava.cpp
@@ -387,6 +387,9 @@
(*pLength) = length;
}
}
+
+ // Delete local references to avoid memory leaks
+ pEnv->DeleteLocalRef(string);
}
// Return the string.
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 41ec120..41c28c0 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -380,6 +380,9 @@
pEnv->GetIntField(object,fid);
M4OSA_TRACE1_1("videoRotation = %d",
pSettings->ClipProperties.videoRotationDegrees);
+
+ // Free the local references to avoid memory leaks
+ pEnv->DeleteLocalRef(clazz);
}
static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType,
@@ -1849,7 +1852,9 @@
"not initialized");
if (needToBeLoaded) {
getClipSetting(pEnv,properties, pContext->pEditSettings->pClipList[i]);
+ pEnv->DeleteLocalRef(properties);
} else {
+ pEnv->DeleteLocalRef(properties);
goto videoEditor_populateSettings_cleanup;
}
}
diff --git a/media/libdrm/mobile1/src/objmng/drm_api.c b/media/libdrm/mobile1/src/objmng/drm_api.c
index 249cdbe..232d9f4 100644
--- a/media/libdrm/mobile1/src/objmng/drm_api.c
+++ b/media/libdrm/mobile1/src/objmng/drm_api.c
@@ -1478,13 +1478,13 @@
if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
if (leftLen <= s->readBufLen) {
- memcpy(mediaBuf, s->readBuf + s->readBufOff, leftLen);
+ memcpy(mediaBuf + readBytes, s->readBuf + s->readBufOff, leftLen);
s->readBufOff += leftLen;
s->readBufLen -= leftLen;
readBytes += leftLen;
leftLen = 0;
} else {
- memcpy(mediaBuf, s->readBuf + s->readBufOff, s->readBufLen);
+ memcpy(mediaBuf + readBytes, s->readBuf + s->readBufOff, s->readBufLen);
s->readBufOff += s->readBufLen;
leftLen -= s->readBufLen;
readBytes += s->readBufLen;
diff --git a/packages/SettingsProvider/Android.mk b/packages/SettingsProvider/Android.mk
index bf4ab1b..a2ea554 100644
--- a/packages/SettingsProvider/Android.mk
+++ b/packages/SettingsProvider/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAVA_LIBRARIES :=
+LOCAL_JAVA_LIBRARIES := telephony-common
LOCAL_PACKAGE_NAME := SettingsProvider
LOCAL_CERTIFICATE := platform
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index cd0da5a..2c9a6fe 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -46,6 +46,8 @@
<bool name="def_netstats_enabled">true</bool>
<bool name="def_usb_mass_storage_enabled">true</bool>
<bool name="def_wifi_on">false</bool>
+ <!-- 0 == default, 1 == never while plugged, 2 == never -->
+ <integer name="def_wifi_sleep_policy">0</integer>
<bool name="def_networks_available_notification_on">true</bool>
<bool name="def_backup_enabled">false</bool>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 384e8af..7430f57 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -33,12 +33,14 @@
import android.os.SystemProperties;
import android.provider.Settings;
import android.provider.Settings.Secure;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.content.PackageHelper;
import com.android.internal.telephony.BaseCommands;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RILConstants;
import com.android.internal.util.XmlUtils;
import com.android.internal.widget.LockPatternUtils;
@@ -1540,6 +1542,8 @@
loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
R.integer.def_pointer_speed);
+ loadIntegerSetting(stmt, Settings.System.WIFI_SLEEP_POLICY,
+ R.integer.def_wifi_sleep_policy);
} finally {
if (stmt != null) stmt.close();
}
@@ -1603,6 +1607,12 @@
SystemProperties.get("ro.com.android.dataroaming",
"false")) ? 1 : 0);
+ // Mobile Data default, based on build
+ loadSetting(stmt, Settings.Secure.MOBILE_DATA,
+ "true".equalsIgnoreCase(
+ SystemProperties.get("ro.com.android.mobiledata",
+ "true")) ? 1 : 0);
+
loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
R.bool.def_install_non_market_apps);
@@ -1630,7 +1640,7 @@
// Set the preferred network mode to 0 = Global, CDMA default
int type;
- if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
+ if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
type = Phone.NT_MODE_GLOBAL;
} else {
type = SystemProperties.getInt("ro.telephony.default_network",
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index c23a8a1..6026258 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -6,7 +6,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
../../../ex/carousel/java/com/android/ex/carousel/carousel.rs
-LOCAL_JAVA_LIBRARIES := services
+LOCAL_JAVA_LIBRARIES := services telephony-common
LOCAL_STATIC_JAVA_LIBRARIES := android-common-carousel
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 96f83c6..b0a7c4b 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -294,6 +294,13 @@
updateWallpaperLocked();
}
+ if (mBackground == null) {
+ // If we somehow got to this point after we have last flushed
+ // the wallpaper, well we really need it to draw again. So
+ // seems like we need to reload it. Ouch.
+ updateWallpaperLocked();
+ }
+
SurfaceHolder sh = getSurfaceHolder();
final Rect frame = sh.getSurfaceFrame();
final int dw = frame.width();
@@ -315,7 +322,6 @@
mLastXTranslation = xPixels;
mLastYTranslation = yPixels;
-
if (mIsHwAccelerated) {
if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
index 491fad1..66494e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
@@ -20,13 +20,14 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.provider.Telephony;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.View;
import android.widget.TextView;
+import com.android.internal.telephony.TelephonyIntents;
+
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
@@ -60,7 +61,7 @@
if (!mAttached) {
mAttached = true;
IntentFilter filter = new IntentFilter();
- filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
+ filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());
}
}
@@ -78,11 +79,11 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
- updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
- intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
- intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
- intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
+ if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
+ updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
+ intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
+ intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
+ intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
}
}
};
@@ -108,7 +109,7 @@
setText(str);
}
-
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 374226d..9b8bd22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -39,6 +39,7 @@
import android.util.Slog;
import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.internal.telephony.cdma.TtyIntent;
@@ -76,7 +77,7 @@
// Assume it's all good unless we hear otherwise. We don't always seem
// to get broadcasts that it *is* there.
- IccCard.State mSimState = IccCard.State.READY;
+ IccCardConstants.State mSimState = IccCardConstants.State.READY;
// ringer volume
private boolean mVolumeVisible;
@@ -205,26 +206,27 @@
}
private final void updateSimState(Intent intent) {
- String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
- if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
- mSimState = IccCard.State.ABSENT;
+ String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+ if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+ mSimState = IccCardConstants.State.ABSENT;
}
- else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
- mSimState = IccCard.State.READY;
+ else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+ mSimState = IccCardConstants.State.READY;
}
- 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 (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+ final String lockedReason =
+ intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+ if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+ mSimState = IccCardConstants.State.PIN_REQUIRED;
}
- else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
- mSimState = IccCard.State.PUK_REQUIRED;
+ else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+ mSimState = IccCardConstants.State.PUK_REQUIRED;
}
else {
- mSimState = IccCard.State.NETWORK_LOCKED;
+ mSimState = IccCardConstants.State.NETWORK_LOCKED;
}
} else {
- mSimState = IccCard.State.UNKNOWN;
+ mSimState = IccCardConstants.State.UNKNOWN;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 8cf7b4a..d94c6b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -51,6 +51,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.server.am.BatteryStatsService;
@@ -68,7 +69,7 @@
boolean mHspaDataDistinguishable;
final TelephonyManager mPhone;
boolean mDataConnected;
- IccCard.State mSimState = IccCard.State.READY;
+ IccCardConstants.State mSimState = IccCardConstants.State.READY;
int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
int mDataState = TelephonyManager.DATA_DISCONNECTED;
@@ -221,7 +222,7 @@
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
+ filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
@@ -344,11 +345,11 @@
updateSimState(intent);
updateDataIcon();
refreshViews();
- } else if (action.equals(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION)) {
- updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
- intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
- intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
- intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
+ } else if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
+ updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
+ intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
+ intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
+ intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
refreshViews();
} else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
@@ -431,26 +432,27 @@
};
private final void updateSimState(Intent intent) {
- String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
- if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
- mSimState = IccCard.State.ABSENT;
+ String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+ if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+ mSimState = IccCardConstants.State.ABSENT;
}
- else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
- mSimState = IccCard.State.READY;
+ else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+ mSimState = IccCardConstants.State.READY;
}
- 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 (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+ final String lockedReason =
+ intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+ if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+ mSimState = IccCardConstants.State.PIN_REQUIRED;
}
- else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
- mSimState = IccCard.State.PUK_REQUIRED;
+ else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+ mSimState = IccCardConstants.State.PUK_REQUIRED;
}
else {
- mSimState = IccCard.State.NETWORK_LOCKED;
+ mSimState = IccCardConstants.State.NETWORK_LOCKED;
}
} else {
- mSimState = IccCard.State.UNKNOWN;
+ mSimState = IccCardConstants.State.UNKNOWN;
}
}
@@ -655,7 +657,8 @@
if (!isCdma()) {
// GSM case, we have to check also the sim state
- if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
+ if (mSimState == IccCardConstants.State.READY ||
+ mSimState == IccCardConstants.State.UNKNOWN) {
if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
switch (mDataActivity) {
case TelephonyManager.DATA_ACTIVITY_IN:
@@ -985,6 +988,8 @@
combinedActivityIconId = mMobileActivityIconId;
combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
mContentDescriptionCombinedSignal = mContentDescriptionDataType;
+ } else {
+ mMobileActivityIconId = 0;
}
}
diff --git a/packages/WAPPushManager/Android.mk b/packages/WAPPushManager/Android.mk
index c1d8f4b..35ec647 100644
--- a/packages/WAPPushManager/Android.mk
+++ b/packages/WAPPushManager/Android.mk
@@ -10,6 +10,7 @@
LOCAL_PACKAGE_NAME := WAPPushManager
+LOCAL_JAVA_LIBRARIES += telephony-common
LOCAL_STATIC_JAVA_LIBRARIES += android-common
LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags
diff --git a/packages/WAPPushManager/tests/Android.mk b/packages/WAPPushManager/tests/Android.mk
index 0a95b52..7128b0d 100644
--- a/packages/WAPPushManager/tests/Android.mk
+++ b/packages/WAPPushManager/tests/Android.mk
@@ -18,7 +18,7 @@
# We only want this apk build for tests.
LOCAL_MODULE_TAGS := tests
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
# Include all test java files.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/policy/src/com/android/internal/policy/impl/IconUtilities.java b/policy/src/com/android/internal/policy/impl/IconUtilities.java
index e997355..a47c904 100644
--- a/policy/src/com/android/internal/policy/impl/IconUtilities.java
+++ b/policy/src/com/android/internal/policy/impl/IconUtilities.java
@@ -130,7 +130,7 @@
int sourceWidth = icon.getIntrinsicWidth();
int sourceHeight = icon.getIntrinsicHeight();
- if (sourceWidth > 0 && sourceWidth > 0) {
+ if (sourceWidth > 0 && sourceHeight > 0) {
// There are intrinsic sizes.
if (width < sourceWidth || height < sourceHeight) {
// It's too big, scale it down.
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index d0fe42d..c1fd515 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -17,8 +17,7 @@
package com.android.internal.policy.impl;
import com.android.internal.R;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCard.State;
+import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.DigitalClock;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.TransportControlView;
@@ -88,7 +87,7 @@
private int mBatteryLevel = 100;
// last known SIM state
- protected State mSimState;
+ protected IccCardConstants.State mSimState;
private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor;
@@ -435,17 +434,18 @@
/**
* Determine the current status of the lock screen given the sim state and other stuff.
*/
- public StatusMode getStatusForIccState(IccCard.State simState) {
+ public StatusMode getStatusForIccState(IccCardConstants.State simState) {
// Since reading the SIM may take a while, we assume it is present until told otherwise.
if (simState == null) {
return StatusMode.Normal;
}
final boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned()
- && (simState == IccCard.State.ABSENT || simState == IccCard.State.PERM_DISABLED));
+ && (simState == IccCardConstants.State.ABSENT ||
+ simState == IccCardConstants.State.PERM_DISABLED));
// Assume we're NETWORK_LOCKED if not provisioned
- simState = missingAndNotProvisioned ? State.NETWORK_LOCKED : simState;
+ simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
switch (simState) {
case ABSENT:
return StatusMode.SimMissing;
@@ -477,7 +477,7 @@
*
* @param simState
*/
- private void updateCarrierStateWithSimStatus(State simState) {
+ private void updateCarrierStateWithSimStatus(IccCardConstants.State simState) {
if (DEBUG) Log.d(TAG, "updateCarrierTextWithSimStatus(), simState = " + simState);
CharSequence carrierText = null;
@@ -663,7 +663,7 @@
private SimStateCallback mSimStateCallback = new SimStateCallback() {
- public void onSimStateChanged(State simState) {
+ public void onSimStateChanged(IccCardConstants.State simState) {
updateCarrierStateWithSimStatus(simState);
}
};
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index dfe9134..5cd0349 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -34,14 +34,8 @@
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
-import android.provider.Telephony;
-import static android.provider.Telephony.Intents.EXTRA_PLMN;
-import static android.provider.Telephony.Intents.EXTRA_SHOW_PLMN;
-import static android.provider.Telephony.Intents.EXTRA_SHOW_SPN;
-import static android.provider.Telephony.Intents.EXTRA_SPN;
-import static android.provider.Telephony.Intents.SPN_STRINGS_UPDATED_ACTION;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
import android.telephony.TelephonyManager;
@@ -70,7 +64,7 @@
private final Context mContext;
- private IccCard.State mSimState = IccCard.State.READY;
+ private IccCardConstants.State mSimState = IccCardConstants.State.READY;
private boolean mDeviceProvisioned;
@@ -115,44 +109,44 @@
* the intent and provide a {@link SimCard.State} result.
*/
private static class SimArgs {
- public final IccCard.State simState;
+ public final IccCardConstants.State simState;
- SimArgs(IccCard.State state) {
+ SimArgs(IccCardConstants.State state) {
simState = state;
}
static SimArgs fromIntent(Intent intent) {
- IccCard.State state;
+ IccCardConstants.State state;
if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
}
- String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
- if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+ String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+ if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
final String absentReason = intent
- .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
+ .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
- if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
+ if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
absentReason)) {
- state = IccCard.State.PERM_DISABLED;
+ state = IccCardConstants.State.PERM_DISABLED;
} else {
- state = IccCard.State.ABSENT;
+ state = IccCardConstants.State.ABSENT;
}
- } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
- state = IccCard.State.READY;
- } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+ } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+ state = IccCardConstants.State.READY;
+ } else if (IccCardConstants.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)) {
- state = IccCard.State.PIN_REQUIRED;
- } else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
- state = IccCard.State.PUK_REQUIRED;
+ .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+ if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+ state = IccCardConstants.State.PIN_REQUIRED;
+ } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+ state = IccCardConstants.State.PUK_REQUIRED;
} else {
- state = IccCard.State.UNKNOWN;
+ state = IccCardConstants.State.UNKNOWN;
}
- } else if (IccCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
- state = IccCard.State.NETWORK_LOCKED;
+ } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
+ state = IccCardConstants.State.NETWORK_LOCKED;
} else {
- state = IccCard.State.UNKNOWN;
+ state = IccCardConstants.State.UNKNOWN;
}
return new SimArgs(state);
}
@@ -253,7 +247,7 @@
}
// take a guess to start
- mSimState = IccCard.State.READY;
+ mSimState = IccCardConstants.State.READY;
mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
mTelephonyPlmn = getDefaultPlmn();
@@ -266,7 +260,7 @@
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
- filter.addAction(SPN_STRINGS_UPDATED_ACTION);
+ filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
filter.addAction(Intent.ACTION_USER_SWITCHED);
@@ -281,7 +275,7 @@
|| Intent.ACTION_TIME_CHANGED.equals(action)
|| Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_TIME_UPDATE));
- } else if (SPN_STRINGS_UPDATED_ACTION.equals(action)) {
+ } else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
mTelephonyPlmn = getTelephonyPlmnFrom(intent);
mTelephonySpn = getTelephonySpnFrom(intent);
mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE));
@@ -296,7 +290,7 @@
} else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
if (DEBUG_SIM_STATES) {
Log.v(TAG, "action " + action + " state" +
- intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE));
+ intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE));
}
mHandler.sendMessage(mHandler.obtainMessage(
MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
@@ -405,15 +399,14 @@
* Handle {@link #MSG_SIM_STATE_CHANGE}
*/
private void handleSimStateChange(SimArgs simArgs) {
- final IccCard.State state = simArgs.simState;
+ final IccCardConstants.State state = simArgs.simState;
if (DEBUG) {
Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " "
+ "state resolved to " + state.toString());
}
- if (state != IccCard.State.UNKNOWN && state != mSimState) {
- if (DEBUG_SIM_STATES) Log.v(TAG, "dispatching state: " + state);
+ if (state != IccCardConstants.State.UNKNOWN && state != mSimState) {
mSimState = state;
for (int i = 0; i < mSimStateCallbacks.size(); i++) {
mSimStateCallbacks.get(i).onSimStateChanged(state);
@@ -466,12 +459,12 @@
}
/**
- * @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION}
+ * @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION}
* @return The string to use for the plmn, or null if it should not be shown.
*/
private CharSequence getTelephonyPlmnFrom(Intent intent) {
- if (intent.getBooleanExtra(EXTRA_SHOW_PLMN, false)) {
- final String plmn = intent.getStringExtra(EXTRA_PLMN);
+ if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
+ final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN);
if (plmn != null) {
return plmn;
} else {
@@ -494,8 +487,8 @@
* @return The string to use for the plmn, or null if it should not be shown.
*/
private CharSequence getTelephonySpnFrom(Intent intent) {
- if (intent.getBooleanExtra(EXTRA_SHOW_SPN, false)) {
- final String spn = intent.getStringExtra(EXTRA_SPN);
+ if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
+ final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN);
if (spn != null) {
return spn;
}
@@ -601,7 +594,7 @@
* Callback to notify of sim state change.
*/
interface SimStateCallback {
- void onSimStateChanged(IccCard.State simState);
+ void onSimStateChanged(IccCardConstants.State simState);
}
/**
@@ -646,7 +639,7 @@
mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
}
- public IccCard.State getSimState() {
+ public IccCardConstants.State getSimState() {
return mSimState;
}
@@ -659,7 +652,7 @@
* through mHandler, this *must* be called from the UI thread.
*/
public void reportSimUnlocked() {
- handleSimStateChange(new SimArgs(IccCard.State.READY));
+ handleSimStateChange(new SimArgs(IccCardConstants.State.READY));
}
public boolean isDevicePluggedIn() {
@@ -725,8 +718,8 @@
}
public boolean isSimLocked() {
- return mSimState == IccCard.State.PIN_REQUIRED
- || mSimState == IccCard.State.PUK_REQUIRED
- || mSimState == IccCard.State.PERM_DISABLED;
+ return mSimState == IccCardConstants.State.PIN_REQUIRED
+ || mSimState == IccCardConstants.State.PUK_REQUIRED
+ || mSimState == IccCardConstants.State.PERM_DISABLED;
}
}
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index e84e912..5fa6dbf 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -19,7 +19,7 @@
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.LockPatternUtils;
import android.app.ActivityManagerNative;
@@ -230,7 +230,7 @@
private KeyguardUpdateMonitor mUpdateMonitor;
- private boolean mScreenOn = false;
+ private boolean mScreenOn;
// last known state of the cellular connection
private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
@@ -318,6 +318,8 @@
final ContentResolver cr = mContext.getContentResolver();
mShowLockIcon = (Settings.System.getInt(cr, "show_status_bar_lock", 0) == 1);
+ mScreenOn = mPM.isScreenOn();
+
mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
String soundPath = Settings.System.getString(cr, Settings.System.LOCK_SOUND);
if (soundPath != null) {
@@ -621,10 +623,10 @@
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
false);
final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
- final IccCard.State state = mUpdateMonitor.getSimState();
+ final IccCardConstants.State state = mUpdateMonitor.getSimState();
final boolean lockedOrMissing = state.isPinLocked()
- || ((state == IccCard.State.ABSENT
- || state == IccCard.State.PERM_DISABLED)
+ || ((state == IccCardConstants.State.ABSENT
+ || state == IccCardConstants.State.PERM_DISABLED)
&& requireSim);
if (!lockedOrMissing && !provisioned) {
@@ -727,7 +729,7 @@
}
/** {@inheritDoc} */
- public void onSimStateChanged(IccCard.State simState) {
+ public void onSimStateChanged(IccCardConstants.State simState) {
if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState);
switch (simState) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 35e7820..041211c 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -20,7 +20,7 @@
import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallback;
import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
import com.android.internal.policy.impl.LockPatternKeyguardView.UnlockMode;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockScreenWidgetCallback;
import com.android.internal.widget.LockScreenWidgetInterface;
@@ -267,8 +267,8 @@
private boolean stuckOnLockScreenBecauseSimMissing() {
return mRequiresSim
&& (!mUpdateMonitor.isDeviceProvisioned())
- && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT ||
- mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED);
+ && (mUpdateMonitor.getSimState() == IccCardConstants.State.ABSENT ||
+ mUpdateMonitor.getSimState() == IccCardConstants.State.PERM_DISABLED);
}
/**
@@ -289,9 +289,9 @@
}
public void goToUnlockScreen() {
- final IccCard.State simState = mUpdateMonitor.getSimState();
+ final IccCardConstants.State simState = mUpdateMonitor.getSimState();
if (stuckOnLockScreenBecauseSimMissing()
- || (simState == IccCard.State.PUK_REQUIRED
+ || (simState == IccCardConstants.State.PUK_REQUIRED
&& !mLockPatternUtils.isPukUnlockScreenEnable())){
// stuck on lock screen when sim missing or
// puk'd but puk unlock screen is disabled
@@ -757,7 +757,7 @@
public void wakeWhenReadyTq(int keyCode) {
if (DEBUG) Log.d(TAG, "onWakeKey");
if (keyCode == KeyEvent.KEYCODE_MENU && isSecure() && (mMode == Mode.LockScreen)
- && (mUpdateMonitor.getSimState() != IccCard.State.PUK_REQUIRED)) {
+ && (mUpdateMonitor.getSimState() != IccCardConstants.State.PUK_REQUIRED)) {
if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
updateScreen(Mode.UnlockScreen, false);
getCallback().pokeWakelock();
@@ -811,10 +811,10 @@
secure = mLockPatternUtils.isLockPatternEnabled();
break;
case SimPin:
- secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED;
+ secure = mUpdateMonitor.getSimState() == IccCardConstants.State.PIN_REQUIRED;
break;
case SimPuk:
- secure = mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED;
+ secure = mUpdateMonitor.getSimState() == IccCardConstants.State.PUK_REQUIRED;
break;
case Account:
secure = true;
@@ -1044,9 +1044,9 @@
* the lock screen (lock or unlock).
*/
private Mode getInitialMode() {
- final IccCard.State simState = mUpdateMonitor.getSimState();
+ final IccCardConstants.State simState = mUpdateMonitor.getSimState();
if (stuckOnLockScreenBecauseSimMissing() ||
- (simState == IccCard.State.PUK_REQUIRED &&
+ (simState == IccCardConstants.State.PUK_REQUIRED &&
!mLockPatternUtils.isPukUnlockScreenEnable())) {
return Mode.LockScreen;
} else {
@@ -1062,11 +1062,11 @@
* Given the current state of things, what should the unlock screen be?
*/
private UnlockMode getUnlockMode() {
- final IccCard.State simState = mUpdateMonitor.getSimState();
+ final IccCardConstants.State simState = mUpdateMonitor.getSimState();
UnlockMode currentMode;
- if (simState == IccCard.State.PIN_REQUIRED) {
+ if (simState == IccCardConstants.State.PIN_REQUIRED) {
currentMode = UnlockMode.SimPin;
- } else if (simState == IccCard.State.PUK_REQUIRED) {
+ } else if (simState == IccCardConstants.State.PUK_REQUIRED) {
currentMode = UnlockMode.SimPuk;
} else {
final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality();
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
index 58d14ed..6d3c20a6 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
@@ -19,7 +19,7 @@
import com.android.internal.widget.LockPatternUtils;
import android.content.Context;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
/**
* Knows how to create a lock pattern keyguard view, and answer questions about
@@ -55,10 +55,11 @@
}
private boolean isSimPinSecure() {
- final IccCard.State simState = mUpdateMonitor.getSimState();
- return (simState == IccCard.State.PIN_REQUIRED
- || simState == IccCard.State.PUK_REQUIRED
- || simState == IccCard.State.PERM_DISABLED);
+ final IccCardConstants.State simState = mUpdateMonitor.getSimState();
+ return (simState == IccCardConstants.State.PIN_REQUIRED
+ || simState == IccCardConstants.State.PUK_REQUIRED
+ || simState == IccCardConstants.State.ABSENT
+ || simState == IccCardConstants.State.PERM_DISABLED);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index ec954fe..26078ec 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -19,7 +19,7 @@
import com.android.internal.R;
import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
import com.android.internal.policy.impl.KeyguardUpdateMonitor.SimStateCallback;
-import com.android.internal.telephony.IccCard.State;
+import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.SlidingTab;
import com.android.internal.widget.WaveView;
@@ -105,7 +105,7 @@
};
SimStateCallback mSimStateCallback = new SimStateCallback() {
- public void onSimStateChanged(State simState) {
+ public void onSimStateChanged(IccCardConstants.State simState) {
updateTargets();
}
};
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 47703c6..0aa3018 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1666,7 +1666,9 @@
*/
private void restorePanelState(SparseArray<Parcelable> icicles) {
PanelFeatureState st;
- for (int curFeatureId = icicles.size() - 1; curFeatureId >= 0; curFeatureId--) {
+ int curFeatureId;
+ for (int i = icicles.size() - 1; i >= 0; i--) {
+ curFeatureId = icicles.keyAt(i);
st = getPanelState(curFeatureId, false /* required */);
if (st == null) {
// The panel must not have been required, and is currently not around, skip it
diff --git a/policy/src/com/android/internal/policy/impl/Policy.java b/policy/src/com/android/internal/policy/impl/Policy.java
index a490729..153ef0f 100644
--- a/policy/src/com/android/internal/policy/impl/Policy.java
+++ b/policy/src/com/android/internal/policy/impl/Policy.java
@@ -41,7 +41,7 @@
"com.android.internal.policy.impl.PhoneLayoutInflater",
"com.android.internal.policy.impl.PhoneWindow",
"com.android.internal.policy.impl.PhoneWindow$1",
- "com.android.internal.policy.impl.PhoneWindow$ContextMenuCallback",
+ "com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback",
"com.android.internal.policy.impl.PhoneWindow$DecorView",
"com.android.internal.policy.impl.PhoneWindow$PanelFeatureState",
"com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState",
diff --git a/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java b/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
index db71e2b..862e683 100644
--- a/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
+++ b/policy/tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
@@ -18,7 +18,7 @@
import android.content.Context;
import com.android.internal.policy.impl.KeyguardViewCallback;
-import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
import android.content.res.Configuration;
import android.test.AndroidTestCase;
import android.view.View;
@@ -40,14 +40,14 @@
private static class MockUpdateMonitor extends KeyguardUpdateMonitor {
- public IccCard.State simState = IccCard.State.READY;
+ public IccCardConstants.State simState = IccCardConstants.State.READY;
private MockUpdateMonitor(Context context) {
super(context);
}
@Override
- public IccCard.State getSimState() {
+ public IccCardConstants.State getSimState() {
return simState;
}
}
@@ -318,7 +318,7 @@
public void testMenuDoesntGoToUnlockScreenOnWakeWhenPukLocked() {
// PUK locked
- mUpdateMonitor.simState = IccCard.State.PUK_REQUIRED;
+ mUpdateMonitor.simState = IccCardConstants.State.PUK_REQUIRED;
// wake by menu
mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU);
diff --git a/preloaded-classes b/preloaded-classes
index c29ba15..feddbd6 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -38,10 +38,6 @@
android.animation.TypeEvaluator
android.animation.ValueAnimator
android.animation.ValueAnimator$1
-android.animation.ValueAnimator$2
-android.animation.ValueAnimator$3
-android.animation.ValueAnimator$4
-android.animation.ValueAnimator$5
android.animation.ValueAnimator$AnimationHandler
android.app.ActionBar
android.app.ActionBar$LayoutParams
@@ -279,7 +275,6 @@
android.content.res.ObbInfo$1
android.content.res.ObbScanner
android.content.res.Resources
-android.content.res.Resources$1
android.content.res.Resources$Theme
android.content.res.StringBlock
android.content.res.StringBlock$StyleIDs
@@ -318,13 +313,11 @@
android.database.Observable
android.database.sqlite.DatabaseObjectNotClosedException
android.database.sqlite.SQLiteClosable
-android.database.sqlite.SQLiteCompiledSql
android.database.sqlite.SQLiteCursor
android.database.sqlite.SQLiteCursorDriver
android.database.sqlite.SQLiteDatabase
android.database.sqlite.SQLiteDatabase$1
android.database.sqlite.SQLiteDatabase$CustomFunction
-android.database.sqlite.SQLiteDatabase$DatabaseReentrantLock
android.database.sqlite.SQLiteDebug
android.database.sqlite.SQLiteDebug$PagerStats
android.database.sqlite.SQLiteDirectCursorDriver
@@ -482,7 +475,6 @@
android.media.AudioFormat
android.media.AudioManager
android.media.AudioManager$1
-android.media.AudioManager$2
android.media.AudioManager$FocusEventHandlerDelegate
android.media.AudioManager$FocusEventHandlerDelegate$1
android.media.AudioRecord
@@ -495,8 +487,6 @@
android.media.IAudioService
android.media.IAudioService$Stub
android.media.IAudioService$Stub$Proxy
-android.media.IRemoteControlClientDispatcher
-android.media.IRemoteControlClientDispatcher$Stub
android.media.JetPlayer
android.media.MediaFile
android.media.MediaPlayer
@@ -605,7 +595,6 @@
android.os.Parcelable$Creator
android.os.PatternMatcher
android.os.PatternMatcher$1
-android.os.Power
android.os.PowerManager
android.os.PowerManager$WakeLock
android.os.PowerManager$WakeLock$1
@@ -698,7 +687,6 @@
android.text.TextDirectionHeuristics
android.text.TextDirectionHeuristics$1
android.text.TextDirectionHeuristics$AnyStrong
-android.text.TextDirectionHeuristics$CharCount
android.text.TextDirectionHeuristics$FirstStrong
android.text.TextDirectionHeuristics$TextDirectionAlgorithm
android.text.TextDirectionHeuristics$TextDirectionHeuristicImpl
@@ -729,7 +717,6 @@
android.text.method.TransformationMethod
android.text.method.TransformationMethod2
android.text.method.WordIterator
-android.text.method.WordIterator$1
android.text.style.AlignmentSpan
android.text.style.CharacterStyle
android.text.style.LeadingMarginSpan
@@ -824,10 +811,9 @@
android.view.InputEvent$1
android.view.InputEventConsistencyVerifier
android.view.InputEventConsistencyVerifier$KeyState
-android.view.InputHandler
+android.view.InputEventReceiver
android.view.InputQueue
android.view.InputQueue$Callback
-android.view.InputQueue$FinishedCallback
android.view.KeyCharacterMap
android.view.KeyCharacterMap$FallbackAction
android.view.KeyEvent
@@ -903,7 +889,6 @@
android.view.ViewParent
android.view.ViewRootImpl
android.view.ViewRootImpl$2
-android.view.ViewRootImpl$3
android.view.ViewRootImpl$AccessibilityInteractionConnectionManager
android.view.ViewRootImpl$InputMethodCallback
android.view.ViewRootImpl$ResizedInfo
@@ -1005,8 +990,11 @@
android.widget.CursorAdapter
android.widget.CursorFilter$CursorFilterClient
android.widget.EdgeEffect
-android.widget.EdgeGlow
android.widget.EditText
+android.widget.Editor$Blink
+android.widget.Editor$EasyEditSpanController
+android.widget.Editor$InputContentType
+android.widget.Editor$InputMethodState
android.widget.ExpandableListView
android.widget.FastScroller
android.widget.FastScroller$1
@@ -1080,17 +1068,12 @@
android.widget.TextView
android.widget.TextView$2
android.widget.TextView$3
-android.widget.TextView$Blink
android.widget.TextView$BufferType
android.widget.TextView$ChangeWatcher
android.widget.TextView$CharWrapper
android.widget.TextView$Drawables
-android.widget.TextView$EasyEditSpanController
-android.widget.TextView$InputContentType
-android.widget.TextView$InputMethodState
android.widget.TextView$OnEditorActionListener
android.widget.TextView$SavedState
-android.widget.TextView$TextAlign
android.widget.VideoView
android.widget.ViewAnimator
com.android.i18n.phonenumbers.AsYouTypeFormatter
@@ -1144,7 +1127,7 @@
com.android.internal.telephony.ITelephonyRegistry
com.android.internal.telephony.ITelephonyRegistry$Stub
com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
-com.android.internal.telephony.Phone$State
+com.android.internal.telephony.PhoneConstants$State
com.android.internal.util.ArrayUtils
com.android.internal.util.FastXmlSerializer
com.android.internal.util.Preconditions
diff --git a/services/common_time/common_clock_service.h b/services/common_time/common_clock_service.h
index a65e398..bd663f0 100644
--- a/services/common_time/common_clock_service.h
+++ b/services/common_time/common_clock_service.h
@@ -14,11 +14,12 @@
* limitations under the License.
*/
-#include <common_time/ICommonClock.h>
-
#ifndef ANDROID_COMMON_CLOCK_SERVICE_H
#define ANDROID_COMMON_CLOCK_SERVICE_H
+#include <sys/socket.h>
+#include <common_time/ICommonClock.h>
+
namespace android {
class CommonTimeServer;
diff --git a/services/common_time/common_time_config_service.h b/services/common_time/common_time_config_service.h
index 8283c24..89806dd 100644
--- a/services/common_time/common_time_config_service.h
+++ b/services/common_time/common_time_config_service.h
@@ -13,11 +13,12 @@
* limitations under the License.
*/
-#include <common_time/ICommonTimeConfig.h>
-
#ifndef ANDROID_COMMON_TIME_CONFIG_SERVICE_H
#define ANDROID_COMMON_TIME_CONFIG_SERVICE_H
+#include <sys/socket.h>
+#include <common_time/ICommonTimeConfig.h>
+
namespace android {
class String16;
diff --git a/services/common_time/common_time_server.h b/services/common_time/common_time_server.h
index a0f549f..89bca64 100644
--- a/services/common_time/common_time_server.h
+++ b/services/common_time/common_time_server.h
@@ -19,7 +19,7 @@
#include <arpa/inet.h>
#include <stdint.h>
-#include <linux/socket.h>
+#include <sys/socket.h>
#include <common_time/ICommonClock.h>
#include <common_time/local_clock.h>
diff --git a/services/java/Android.mk b/services/java/Android.mk
index c756d29..e70a6c9 100644
--- a/services/java/Android.mk
+++ b/services/java/Android.mk
@@ -11,7 +11,7 @@
LOCAL_MODULE:= services
-LOCAL_JAVA_LIBRARIES := android.policy
+LOCAL_JAVA_LIBRARIES := android.policy telephony-common
LOCAL_NO_EMMA_INSTRUMENT := true
LOCAL_NO_EMMA_COMPILE := true
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 7bbc8b5..86ada40 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -77,6 +77,7 @@
import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
@@ -1008,7 +1009,7 @@
try {
if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
mNetConfigs[networkType] == null) {
- return Phone.APN_REQUEST_FAILED;
+ return PhoneConstants.APN_REQUEST_FAILED;
}
FeatureUser f = new FeatureUser(networkType, feature, binder);
@@ -1027,7 +1028,7 @@
uidRules = mUidRules.get(Binder.getCallingUid(), RULE_ALLOW_ALL);
}
if (networkMetered && (uidRules & RULE_REJECT_METERED) != 0) {
- return Phone.APN_REQUEST_FAILED;
+ return PhoneConstants.APN_REQUEST_FAILED;
}
NetworkStateTracker network = mNetTrackers[usedNetworkType];
@@ -1039,7 +1040,7 @@
if (ni.isAvailable() == false) {
if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
if (DBG) log("special network not available ni=" + ni.getTypeName());
- return Phone.APN_TYPE_NOT_AVAILABLE;
+ return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
} else {
// else make the attempt anyway - probably giving REQUEST_STARTED below
if (DBG) {
@@ -1088,10 +1089,10 @@
} finally {
Binder.restoreCallingIdentity(token);
}
- return Phone.APN_ALREADY_ACTIVE;
+ return PhoneConstants.APN_ALREADY_ACTIVE;
}
if (VDBG) log("special network already connecting");
- return Phone.APN_REQUEST_STARTED;
+ return PhoneConstants.APN_REQUEST_STARTED;
}
// check if the radio in play can make another contact
@@ -1102,7 +1103,7 @@
feature);
}
network.reconnect();
- return Phone.APN_REQUEST_STARTED;
+ return PhoneConstants.APN_REQUEST_STARTED;
} else {
// need to remember this unsupported request so we respond appropriately on stop
synchronized(this) {
@@ -1115,7 +1116,7 @@
return -1;
}
}
- return Phone.APN_TYPE_NOT_AVAILABLE;
+ return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
} finally {
if (DBG) {
final long execTime = SystemClock.elapsedRealtime() - startTime;
@@ -2037,7 +2038,7 @@
// @see bug/4455071
/** Notify TetheringService if interface name has been changed. */
if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
- Phone.REASON_LINK_PROPERTIES_CHANGED)) {
+ PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
if (isTetheringSupported()) {
mTethering.handleTetherIfaceChange();
}
@@ -2489,6 +2490,11 @@
// @see bug/4455071
handleConnectivityChange(info.getType(), false);
break;
+ case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED:
+ info = (NetworkInfo) msg.obj;
+ type = info.getType();
+ updateNetworkSettings(mNetTrackers[type]);
+ break;
case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
String causedBy = null;
synchronized (ConnectivityService.this) {
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 7609613..ea19d6e 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -1691,6 +1691,7 @@
// Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
+ intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
mWakeLock.acquire(10000);
mContext.startService(intent);
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 1482d22..04267a3 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1221,6 +1221,7 @@
for(MountServiceBinderListener bl : mListeners) {
if (bl.mListener == listener) {
mListeners.remove(mListeners.indexOf(bl));
+ listener.asBinder().unlinkToDeath(bl, 0);
return;
}
}
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index 6ad8bd0..87843d9 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -110,8 +110,8 @@
private final EnabledState mEnabledState = new EnabledState();
@Override
- protected String getMessageInfo(Message msg) {
- return cmdToString(msg.what);
+ protected String getWhatToString(int what) {
+ return cmdToString(what);
}
/**
@@ -144,7 +144,7 @@
} else {
setInitialState(mDisabledState);
}
- setProcessedMessagesSize(25);
+ setLogRecSize(25);
registerForNsdSetting();
}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 24c59a5..888ec69 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1165,6 +1165,8 @@
? "SCREEN_BRIGHT_BIT " : "")
+ (((state & SCREEN_ON_BIT) != 0)
? "SCREEN_ON_BIT " : "")
+ + (((state & BUTTON_BRIGHT_BIT) != 0)
+ ? "BUTTON_BRIGHT_BIT " : "")
+ (((state & BATTERY_LOW_BIT) != 0)
? "BATTERY_LOW_BIT " : "");
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6d0b26f..2676537 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -83,7 +83,7 @@
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
SystemClock.uptimeMillis());
- Looper.prepare();
+ Looper.prepareMainLooper();
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
@@ -693,6 +693,12 @@
reportWtf("making Vibrator Service ready", e);
}
+ try {
+ lockSettings.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Lock Settings Service ready", e);
+ }
+
if (devicePolicy != null) {
try {
devicePolicy.systemReady();
@@ -734,11 +740,6 @@
} catch (Throwable e) {
reportWtf("making Package Manager Service ready", e);
}
- try {
- lockSettings.systemReady();
- } catch (Throwable e) {
- reportWtf("making Lock Settings Service ready", e);
- }
// These are needed to propagate to the runnable below.
final Context contextF = context;
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 1b1638a..c23a1d9 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -44,6 +44,7 @@
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.DefaultPhoneNotifier;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyIntents;
import com.android.server.am.BatteryStatsService;
@@ -622,7 +623,8 @@
}
Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
- intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
+ intent.putExtra(PhoneConstants.STATE_KEY,
+ DefaultPhoneNotifier.convertCallState(state).toString());
if (!TextUtils.isEmpty(incomingNumber)) {
intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
}
@@ -637,34 +639,35 @@
// status bar takes care of that after taking into account all of the
// required info.
Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
- intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
+ intent.putExtra(PhoneConstants.STATE_KEY,
+ DefaultPhoneNotifier.convertDataState(state).toString());
if (!isDataConnectivityPossible) {
- intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
+ intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
}
if (reason != null) {
- intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
+ intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
}
if (linkProperties != null) {
- intent.putExtra(Phone.DATA_LINK_PROPERTIES_KEY, linkProperties);
+ intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
String iface = linkProperties.getInterfaceName();
if (iface != null) {
- intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface);
+ intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
}
}
if (linkCapabilities != null) {
- intent.putExtra(Phone.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
+ intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
}
- if (roaming) intent.putExtra(Phone.DATA_NETWORK_ROAMING_KEY, true);
+ if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
- intent.putExtra(Phone.DATA_APN_KEY, apn);
- intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
+ intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
+ intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
mContext.sendStickyBroadcast(intent);
}
private void broadcastDataConnectionFailed(String reason, String apnType) {
Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
- intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
- intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
+ intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
+ intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
mContext.sendStickyBroadcast(intent);
}
diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java
index b609867..72fde11 100755
--- a/services/java/com/android/server/VibratorService.java
+++ b/services/java/com/android/server/VibratorService.java
@@ -441,7 +441,7 @@
private void delay(long duration) {
if (duration > 0) {
- long bedtime = SystemClock.uptimeMillis();
+ long bedtime = duration + SystemClock.uptimeMillis();
do {
try {
this.wait(duration);
@@ -451,8 +451,7 @@
if (mDone) {
break;
}
- duration = duration
- - SystemClock.uptimeMillis() - bedtime;
+ duration = bedtime - SystemClock.uptimeMillis();
} while (duration > 0);
}
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index d97d335..8a08277 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -45,6 +45,7 @@
import android.os.FileObserver;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
+import android.os.SELinux;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserId;
@@ -639,8 +640,12 @@
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
-1, -1);
}
- ParcelFileDescriptor fd = ParcelFileDescriptor.open(new File(dir, WALLPAPER),
+ File file = new File(dir, WALLPAPER);
+ ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
MODE_CREATE|MODE_READ_WRITE);
+ if (!SELinux.restorecon(file)) {
+ return null;
+ }
wallpaper.name = name;
return fd;
} catch (FileNotFoundException e) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 95d3c41..5d74cf3 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -106,6 +106,7 @@
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.os.SELinux;
import android.os.ServiceManager;
import android.os.StrictMode;
import android.os.SystemClock;
@@ -1820,7 +1821,7 @@
if (cr.binding != null && cr.binding.service != null
&& cr.binding.service.app != null
&& cr.binding.service.app.lruSeq != mLruSeq) {
- updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
+ updateLruProcessInternalLocked(cr.binding.service.app, false,
updateActivityTime, i+1);
}
}
@@ -1828,7 +1829,7 @@
for (int j=app.conProviders.size()-1; j>=0; j--) {
ContentProviderRecord cpr = app.conProviders.get(j).provider;
if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
- updateLruProcessInternalLocked(cpr.proc, oomAdj,
+ updateLruProcessInternalLocked(cpr.proc, false,
updateActivityTime, i+1);
}
}
@@ -2053,7 +2054,7 @@
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags,
- app.info.targetSdkVersion, null);
+ app.info.targetSdkVersion, null, null);
BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
synchronized (bs) {
@@ -3032,7 +3033,12 @@
File tracesFile = new File(tracesPath);
try {
File tracesDir = tracesFile.getParentFile();
- if (!tracesDir.exists()) tracesFile.mkdirs();
+ if (!tracesDir.exists()) {
+ tracesFile.mkdirs();
+ if (!SELinux.restorecon(tracesDir)) {
+ return null;
+ }
+ }
FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
if (clearTraces && tracesFile.exists()) tracesFile.delete();
@@ -3136,7 +3142,12 @@
final File tracesDir = tracesFile.getParentFile();
final File tracesTmp = new File(tracesDir, "__tmp__");
try {
- if (!tracesDir.exists()) tracesFile.mkdirs();
+ if (!tracesDir.exists()) {
+ tracesFile.mkdirs();
+ if (!SELinux.restorecon(tracesDir.getPath())) {
+ return;
+ }
+ }
FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
if (tracesFile.exists()) {
@@ -10950,7 +10961,9 @@
restart = true;
} else {
removeDyingProviderLocked(app, cpr, true);
+ // cpr should have been removed from mLaunchingProviders
NL = mLaunchingProviders.size();
+ i--;
}
}
}
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 9171e47..b9e63b7 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2762,7 +2762,8 @@
// If the top activity in the task is the root
// activity, deliver this new intent to it if it
// desires.
- if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
+ if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
+ || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
&& taskTop.realActivity.equals(r.realActivity)) {
logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task);
if (taskTop.frontOfTask) {
diff --git a/services/java/com/android/server/am/DeviceMonitor.java b/services/java/com/android/server/am/DeviceMonitor.java
index 5f3b0ce..21e7252 100644
--- a/services/java/com/android/server/am/DeviceMonitor.java
+++ b/services/java/com/android/server/am/DeviceMonitor.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import android.os.SELinux;
import android.util.Slog;
import java.io.*;
@@ -80,6 +81,9 @@
if (!BASE.isDirectory() && !BASE.mkdirs()) {
throw new AssertionError("Couldn't create " + BASE + ".");
}
+ if (!SELinux.restorecon(BASE)) {
+ throw new AssertionError("Couldn't restorecon " + BASE + ".");
+ }
}
private static final File[] PATHS = {
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index d148ec3..e4608a2 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -127,7 +127,12 @@
Slog.i(TAG,
"Removing from providersByName name=" + name + " user="
+ (optionalUserId == -1 ? Binder.getOrigCallingUser() : optionalUserId));
- getProvidersByName(optionalUserId).remove(name);
+ HashMap<String, ContentProviderRecord> map = getProvidersByName(optionalUserId);
+ // map returned by getProvidersByName wouldn't be null
+ map.remove(name);
+ if (map.size() == 0) {
+ mProvidersByNamePerUser.remove(optionalUserId);
+ }
}
}
@@ -141,7 +146,12 @@
Slog.i(TAG,
"Removing from providersByClass name=" + name + " user="
+ (optionalUserId == -1 ? Binder.getOrigCallingUser() : optionalUserId));
- getProvidersByClass(optionalUserId).remove(name);
+ HashMap<ComponentName, ContentProviderRecord> map = getProvidersByClass(optionalUserId);
+ // map returned by getProvidersByClass wouldn't be null
+ map.remove(name);
+ if (map.size() == 0) {
+ mProvidersByClassPerUser.remove(optionalUserId);
+ }
}
}
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 88a0ccb..682ecf8 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -47,6 +47,7 @@
import android.util.Log;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
@@ -1190,7 +1191,7 @@
boolean retValue = true;
if (apnType == ConnectivityManager.TYPE_NONE) return false;
if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection();
- int result = Phone.APN_REQUEST_FAILED;
+ int result = PhoneConstants.APN_REQUEST_FAILED;
String enableString = enableString(apnType);
if (enableString == null) return false;
try {
@@ -1199,14 +1200,14 @@
} catch (Exception e) {
}
switch (result) {
- case Phone.APN_ALREADY_ACTIVE:
- case Phone.APN_REQUEST_STARTED:
+ case PhoneConstants.APN_ALREADY_ACTIVE:
+ case PhoneConstants.APN_REQUEST_STARTED:
mMobileApnReserved = apnType;
Message m = obtainMessage(CMD_CELL_CONNECTION_RENEW);
m.arg1 = ++mCurrentConnectionSequence;
sendMessageDelayed(m, CELL_CONNECTION_RENEW_MS);
break;
- case Phone.APN_REQUEST_FAILED:
+ case PhoneConstants.APN_REQUEST_FAILED:
default:
retValue = false;
break;
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index ce53499..4ad6140 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -60,6 +60,7 @@
import com.android.internal.location.GpsNetInitiatedHandler;
import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
import java.io.File;
import java.io.FileInputStream;
@@ -1285,8 +1286,8 @@
int result = mConnMgr.startUsingNetworkFeature(
ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL);
mAGpsDataConnectionIpAddr = ipaddr;
- if (result == Phone.APN_ALREADY_ACTIVE) {
- if (DEBUG) Log.d(TAG, "Phone.APN_ALREADY_ACTIVE");
+ if (result == PhoneConstants.APN_ALREADY_ACTIVE) {
+ if (DEBUG) Log.d(TAG, "PhoneConstants.APN_ALREADY_ACTIVE");
if (mAGpsApn != null) {
Log.d(TAG, "mAGpsDataConnectionIpAddr " + mAGpsDataConnectionIpAddr);
if (mAGpsDataConnectionIpAddr != 0xffffffff) {
@@ -1300,12 +1301,12 @@
native_agps_data_conn_open(mAGpsApn);
mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
} else {
- Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE");
+ Log.e(TAG, "mAGpsApn not set when receiving PhoneConstants.APN_ALREADY_ACTIVE");
mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
native_agps_data_conn_failed();
}
- } else if (result == Phone.APN_REQUEST_STARTED) {
- if (DEBUG) Log.d(TAG, "Phone.APN_REQUEST_STARTED");
+ } else if (result == PhoneConstants.APN_REQUEST_STARTED) {
+ if (DEBUG) Log.d(TAG, "PhoneConstants.APN_REQUEST_STARTED");
// Nothing to do here
} else {
if (DEBUG) Log.d(TAG, "startUsingNetworkFeature failed");
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index eb81791..cd7599d 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -96,6 +96,7 @@
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
+import android.os.SELinux;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -143,6 +144,7 @@
import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;
+import libcore.io.StructStat;
/**
* Keep track of all those .apks everywhere.
@@ -293,8 +295,6 @@
File mScanningPath;
int mLastScanError;
- final int[] mOutPermissions = new int[3];
-
// ----------------------------------------------------------------
// Keys are String (package name), values are Package. This also serves
@@ -3761,14 +3761,18 @@
boolean uidError = false;
if (dataPath.exists()) {
- // XXX should really do this check for each user.
- mOutPermissions[1] = 0;
- FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
+ int currentUid = 0;
+ try {
+ StructStat stat = Libcore.os.stat(dataPath.getPath());
+ currentUid = stat.st_uid;
+ } catch (ErrnoException e) {
+ Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
+ }
// If we have mismatched owners for the data path, we have a problem.
- if (mOutPermissions[1] != pkg.applicationInfo.uid) {
+ if (currentUid != pkg.applicationInfo.uid) {
boolean recovered = false;
- if (mOutPermissions[1] == 0) {
+ if (currentUid == 0) {
// The directory somehow became owned by root. Wow.
// This is probably because the system was stopped while
// installd was in the middle of messing with its libs
@@ -3797,7 +3801,7 @@
? "System package " : "Third party package ";
String msg = prefix + pkg.packageName
+ " has changed from uid: "
- + mOutPermissions[1] + " to "
+ + currentUid + " to "
+ pkg.applicationInfo.uid + "; old data erased";
reportSettingsProblem(Log.WARN, msg);
recovered = true;
@@ -3829,11 +3833,11 @@
if (!recovered) {
pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
+ pkg.applicationInfo.uid + "/fs_"
- + mOutPermissions[1];
+ + currentUid;
pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
String msg = "Package " + pkg.packageName
+ " has mismatched uid: "
- + mOutPermissions[1] + " on disk, "
+ + currentUid + " on disk, "
+ pkg.applicationInfo.uid + " in settings";
// writer
synchronized (mPackages) {
@@ -6430,6 +6434,10 @@
return false;
}
+ if (!SELinux.restorecon(newCodeFile)) {
+ return false;
+ }
+
return true;
}
}
@@ -7411,6 +7419,9 @@
FileUtils.setPermissions(
tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
-1, -1);
+ if (!SELinux.restorecon(tmpPackageFile)) {
+ return null;
+ }
} catch (IOException e) {
Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
return null;
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index d031686..120b650 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1241,7 +1241,7 @@
// Avoid any application that has a space in its path
// or that is handled by the system.
- if (dataPath.indexOf(" ") >= 0 || ai.uid <= Process.FIRST_APPLICATION_UID)
+ if (dataPath.indexOf(" ") >= 0 || ai.uid < Process.FIRST_APPLICATION_UID)
continue;
// we store on each line the following information for now:
diff --git a/services/java/com/android/server/pm/ShutdownThread.java b/services/java/com/android/server/pm/ShutdownThread.java
index 69406c8..3675d41 100644
--- a/services/java/com/android/server/pm/ShutdownThread.java
+++ b/services/java/com/android/server/pm/ShutdownThread.java
@@ -84,6 +84,8 @@
private PowerManager.WakeLock mCpuWakeLock;
private PowerManager.WakeLock mScreenWakeLock;
private Handler mHandler;
+
+ private static AlertDialog sConfirmDialog;
private ShutdownThread() {
}
@@ -124,7 +126,10 @@
if (confirm) {
final CloseDialogReceiver closer = new CloseDialogReceiver(context);
- final AlertDialog dialog = new AlertDialog.Builder(context)
+ if (sConfirmDialog != null) {
+ sConfirmDialog.dismiss();
+ }
+ sConfirmDialog = new AlertDialog.Builder(context)
.setTitle(mRebootSafeMode
? com.android.internal.R.string.reboot_safemode_title
: com.android.internal.R.string.power_off)
@@ -136,10 +141,10 @@
})
.setNegativeButton(com.android.internal.R.string.no, null)
.create();
- closer.dialog = dialog;
- dialog.setOnDismissListener(closer);
- dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
- dialog.show();
+ closer.dialog = sConfirmDialog;
+ sConfirmDialog.setOnDismissListener(closer);
+ sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ sConfirmDialog.show();
} else {
beginShutdownSequence(context);
}
diff --git a/services/java/com/android/server/usb/UsbSettingsManager.java b/services/java/com/android/server/usb/UsbSettingsManager.java
index 7dde340..9b3459b 100644
--- a/services/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/java/com/android/server/usb/UsbSettingsManager.java
@@ -545,6 +545,10 @@
defaultPackage = mDevicePreferenceMap.get(new DeviceFilter(device));
}
+ // Send broadcast to running activity with registered intent
+ mContext.sendBroadcast(intent);
+
+ // Start activity with registered intent
resolveActivity(intent, matches, defaultPackage, device, null);
}
diff --git a/telephony/java/android/telephony/CellBroadcastMessage.java b/telephony/java/android/telephony/CellBroadcastMessage.java
deleted file mode 100644
index 36c238d..0000000
--- a/telephony/java/android/telephony/CellBroadcastMessage.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2011 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.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Typeface;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.provider.Telephony;
-import android.telephony.SmsCbCmasInfo;
-import android.telephony.SmsCbEtwsInfo;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.format.DateUtils;
-import android.text.style.StyleSpan;
-
-/**
- * Application wrapper for {@link SmsCbMessage}. This is Parcelable so that
- * decoded broadcast message objects can be passed between running Services.
- * New broadcasts are received by the CellBroadcastReceiver app, which exports
- * the database of previously received broadcasts at "content://cellbroadcasts/".
- * The "android.permission.READ_CELL_BROADCASTS" permission is required to read
- * from the ContentProvider, and writes to the database are not allowed.<p>
- *
- * Use {@link #createFromCursor} to create CellBroadcastMessage objects from rows
- * in the database cursor returned by the ContentProvider.
- *
- * {@hide}
- */
-public class CellBroadcastMessage implements Parcelable {
-
- /** Identifier for getExtra() when adding this object to an Intent. */
- public static final String SMS_CB_MESSAGE_EXTRA =
- "com.android.cellbroadcastreceiver.SMS_CB_MESSAGE";
-
- /** SmsCbMessage. */
- private final SmsCbMessage mSmsCbMessage;
-
- private final long mDeliveryTime;
- private boolean mIsRead;
-
- public CellBroadcastMessage(SmsCbMessage message) {
- mSmsCbMessage = message;
- mDeliveryTime = System.currentTimeMillis();
- mIsRead = false;
- }
-
- private CellBroadcastMessage(SmsCbMessage message, long deliveryTime, boolean isRead) {
- mSmsCbMessage = message;
- mDeliveryTime = deliveryTime;
- mIsRead = isRead;
- }
-
- private CellBroadcastMessage(Parcel in) {
- mSmsCbMessage = new SmsCbMessage(in);
- mDeliveryTime = in.readLong();
- mIsRead = (in.readInt() != 0);
- }
-
- /** Parcelable: no special flags. */
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- mSmsCbMessage.writeToParcel(out, flags);
- out.writeLong(mDeliveryTime);
- out.writeInt(mIsRead ? 1 : 0);
- }
-
- public static final Parcelable.Creator<CellBroadcastMessage> CREATOR
- = new Parcelable.Creator<CellBroadcastMessage>() {
- public CellBroadcastMessage createFromParcel(Parcel in) {
- return new CellBroadcastMessage(in);
- }
-
- public CellBroadcastMessage[] newArray(int size) {
- return new CellBroadcastMessage[size];
- }
- };
-
- /**
- * Create a CellBroadcastMessage from a row in the database.
- * @param cursor an open SQLite cursor pointing to the row to read
- * @return the new CellBroadcastMessage
- * @throws IllegalArgumentException if one of the required columns is missing
- */
- public static CellBroadcastMessage createFromCursor(Cursor cursor) {
- int geoScope = cursor.getInt(
- cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE));
- int serialNum = cursor.getInt(
- cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERIAL_NUMBER));
- int category = cursor.getInt(
- cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERVICE_CATEGORY));
- String language = cursor.getString(
- cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.LANGUAGE_CODE));
- String body = cursor.getString(
- cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_BODY));
- int format = cursor.getInt(
- cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_FORMAT));
- int priority = cursor.getInt(
- cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_PRIORITY));
-
- String plmn;
- int plmnColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.PLMN);
- if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) {
- plmn = cursor.getString(plmnColumn);
- } else {
- plmn = null;
- }
-
- int lac;
- int lacColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.LAC);
- if (lacColumn != -1 && !cursor.isNull(lacColumn)) {
- lac = cursor.getInt(lacColumn);
- } else {
- lac = -1;
- }
-
- int cid;
- int cidColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.CID);
- if (cidColumn != -1 && !cursor.isNull(cidColumn)) {
- cid = cursor.getInt(cidColumn);
- } else {
- cid = -1;
- }
-
- SmsCbLocation location = new SmsCbLocation(plmn, lac, cid);
-
- SmsCbEtwsInfo etwsInfo;
- int etwsWarningTypeColumn = cursor.getColumnIndex(
- Telephony.CellBroadcasts.ETWS_WARNING_TYPE);
- if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) {
- int warningType = cursor.getInt(etwsWarningTypeColumn);
- etwsInfo = new SmsCbEtwsInfo(warningType, false, false, null);
- } else {
- etwsInfo = null;
- }
-
- SmsCbCmasInfo cmasInfo;
- int cmasMessageClassColumn = cursor.getColumnIndex(
- Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS);
- if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) {
- int messageClass = cursor.getInt(cmasMessageClassColumn);
-
- int cmasCategory;
- int cmasCategoryColumn = cursor.getColumnIndex(
- Telephony.CellBroadcasts.CMAS_CATEGORY);
- if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) {
- cmasCategory = cursor.getInt(cmasCategoryColumn);
- } else {
- cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN;
- }
-
- int responseType;
- int cmasResponseTypeColumn = cursor.getColumnIndex(
- Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE);
- if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) {
- responseType = cursor.getInt(cmasResponseTypeColumn);
- } else {
- responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN;
- }
-
- int severity;
- int cmasSeverityColumn = cursor.getColumnIndex(
- Telephony.CellBroadcasts.CMAS_SEVERITY);
- if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) {
- severity = cursor.getInt(cmasSeverityColumn);
- } else {
- severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
- }
-
- int urgency;
- int cmasUrgencyColumn = cursor.getColumnIndex(
- Telephony.CellBroadcasts.CMAS_URGENCY);
- if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) {
- urgency = cursor.getInt(cmasUrgencyColumn);
- } else {
- urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
- }
-
- int certainty;
- int cmasCertaintyColumn = cursor.getColumnIndex(
- Telephony.CellBroadcasts.CMAS_CERTAINTY);
- if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) {
- certainty = cursor.getInt(cmasCertaintyColumn);
- } else {
- certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
- }
-
- cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity,
- urgency, certainty);
- } else {
- cmasInfo = null;
- }
-
- SmsCbMessage msg = new SmsCbMessage(format, geoScope, serialNum, location, category,
- language, body, priority, etwsInfo, cmasInfo);
-
- long deliveryTime = cursor.getLong(cursor.getColumnIndexOrThrow(
- Telephony.CellBroadcasts.DELIVERY_TIME));
- boolean isRead = (cursor.getInt(cursor.getColumnIndexOrThrow(
- Telephony.CellBroadcasts.MESSAGE_READ)) != 0);
-
- return new CellBroadcastMessage(msg, deliveryTime, isRead);
- }
-
- /**
- * Return a ContentValues object for insertion into the database.
- * @return a new ContentValues object containing this object's data
- */
- public ContentValues getContentValues() {
- ContentValues cv = new ContentValues(16);
- SmsCbMessage msg = mSmsCbMessage;
- cv.put(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE, msg.getGeographicalScope());
- SmsCbLocation location = msg.getLocation();
- if (location.getPlmn() != null) {
- cv.put(Telephony.CellBroadcasts.PLMN, location.getPlmn());
- }
- if (location.getLac() != -1) {
- cv.put(Telephony.CellBroadcasts.LAC, location.getLac());
- }
- if (location.getCid() != -1) {
- cv.put(Telephony.CellBroadcasts.CID, location.getCid());
- }
- cv.put(Telephony.CellBroadcasts.SERIAL_NUMBER, msg.getSerialNumber());
- cv.put(Telephony.CellBroadcasts.SERVICE_CATEGORY, msg.getServiceCategory());
- cv.put(Telephony.CellBroadcasts.LANGUAGE_CODE, msg.getLanguageCode());
- cv.put(Telephony.CellBroadcasts.MESSAGE_BODY, msg.getMessageBody());
- cv.put(Telephony.CellBroadcasts.DELIVERY_TIME, mDeliveryTime);
- cv.put(Telephony.CellBroadcasts.MESSAGE_READ, mIsRead);
- cv.put(Telephony.CellBroadcasts.MESSAGE_FORMAT, msg.getMessageFormat());
- cv.put(Telephony.CellBroadcasts.MESSAGE_PRIORITY, msg.getMessagePriority());
-
- SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
- if (etwsInfo != null) {
- cv.put(Telephony.CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType());
- }
-
- SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo();
- if (cmasInfo != null) {
- cv.put(Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass());
- cv.put(Telephony.CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory());
- cv.put(Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType());
- cv.put(Telephony.CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity());
- cv.put(Telephony.CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency());
- cv.put(Telephony.CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty());
- }
-
- return cv;
- }
-
- /**
- * Set or clear the "read message" flag.
- * @param isRead true if the message has been read; false if not
- */
- public void setIsRead(boolean isRead) {
- mIsRead = isRead;
- }
-
- public String getLanguageCode() {
- return mSmsCbMessage.getLanguageCode();
- }
-
- public int getServiceCategory() {
- return mSmsCbMessage.getServiceCategory();
- }
-
- public long getDeliveryTime() {
- return mDeliveryTime;
- }
-
- public String getMessageBody() {
- return mSmsCbMessage.getMessageBody();
- }
-
- public boolean isRead() {
- return mIsRead;
- }
-
- public int getSerialNumber() {
- return mSmsCbMessage.getSerialNumber();
- }
-
- public SmsCbCmasInfo getCmasWarningInfo() {
- return mSmsCbMessage.getCmasWarningInfo();
- }
-
- public SmsCbEtwsInfo getEtwsWarningInfo() {
- return mSmsCbMessage.getEtwsWarningInfo();
- }
-
- /**
- * Return whether the broadcast is an emergency (PWS) message type.
- * This includes lower priority test messages and Amber alerts.
- *
- * All public alerts show the flashing warning icon in the dialog,
- * but only emergency alerts play the alert sound and speak the message.
- *
- * @return true if the message is PWS type; false otherwise
- */
- public boolean isPublicAlertMessage() {
- return mSmsCbMessage.isEmergencyMessage();
- }
-
- /**
- * Returns whether the broadcast is an emergency (PWS) message type,
- * including test messages, but excluding lower priority Amber alert broadcasts.
- *
- * @return true if the message is PWS type, excluding Amber alerts
- */
- public boolean isEmergencyAlertMessage() {
- if (!mSmsCbMessage.isEmergencyMessage()) {
- return false;
- }
- SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo();
- if (cmasInfo != null &&
- cmasInfo.getMessageClass() == SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY) {
- return false;
- }
- return true;
- }
-
- /**
- * Return whether the broadcast is an ETWS emergency message type.
- * @return true if the message is ETWS emergency type; false otherwise
- */
- public boolean isEtwsMessage() {
- return mSmsCbMessage.isEtwsMessage();
- }
-
- /**
- * Return whether the broadcast is a CMAS emergency message type.
- * @return true if the message is CMAS emergency type; false otherwise
- */
- public boolean isCmasMessage() {
- return mSmsCbMessage.isCmasMessage();
- }
-
- /**
- * Return the CMAS message class.
- * @return the CMAS message class, e.g. {@link SmsCbCmasInfo#CMAS_CLASS_SEVERE_THREAT}, or
- * {@link SmsCbCmasInfo#CMAS_CLASS_UNKNOWN} if this is not a CMAS alert
- */
- public int getCmasMessageClass() {
- if (mSmsCbMessage.isCmasMessage()) {
- return mSmsCbMessage.getCmasWarningInfo().getMessageClass();
- } else {
- return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
- }
- }
-
- /**
- * Return whether the broadcast is an ETWS popup alert.
- * This method checks the message ID and the message code.
- * @return true if the message indicates an ETWS popup alert
- */
- public boolean isEtwsPopupAlert() {
- SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
- return etwsInfo != null && etwsInfo.isPopupAlert();
- }
-
- /**
- * Return whether the broadcast is an ETWS emergency user alert.
- * This method checks the message ID and the message code.
- * @return true if the message indicates an ETWS emergency user alert
- */
- public boolean isEtwsEmergencyUserAlert() {
- SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
- return etwsInfo != null && etwsInfo.isEmergencyUserAlert();
- }
-
- /**
- * Return whether the broadcast is an ETWS test message.
- * @return true if the message is an ETWS test message; false otherwise
- */
- public boolean isEtwsTestMessage() {
- SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
- return etwsInfo != null &&
- etwsInfo.getWarningType() == SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE;
- }
-
- /**
- * Return the abbreviated date string for the message delivery time.
- * @param context the context object
- * @return a String to use in the broadcast list UI
- */
- public String getDateString(Context context) {
- int flags = DateUtils.FORMAT_NO_NOON_MIDNIGHT | DateUtils.FORMAT_SHOW_TIME |
- DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE |
- DateUtils.FORMAT_CAP_AMPM;
- return DateUtils.formatDateTime(context, mDeliveryTime, flags);
- }
-
- /**
- * Return the date string for the message delivery time, suitable for text-to-speech.
- * @param context the context object
- * @return a String for populating the list item AccessibilityEvent for TTS
- */
- public String getSpokenDateString(Context context) {
- int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE;
- return DateUtils.formatDateTime(context, mDeliveryTime, flags);
- }
-}
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index 5eaa5a0..42c2aff 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -26,7 +26,7 @@
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
/**
* Abstract class that represents the location of the device. {@more}
@@ -64,9 +64,9 @@
// TelephonyManager.getDefault().getCurrentPhoneType() handles the case when
// ITelephony interface is not up yet.
switch(TelephonyManager.getDefault().getCurrentPhoneType()) {
- case Phone.PHONE_TYPE_CDMA:
+ case PhoneConstants.PHONE_TYPE_CDMA:
return new CdmaCellLocation(bundle);
- case Phone.PHONE_TYPE_GSM:
+ case PhoneConstants.PHONE_TYPE_GSM:
return new GsmCellLocation(bundle);
default:
return null;
@@ -92,9 +92,9 @@
// TelephonyManager.getDefault().getCurrentPhoneType() handles the case when
// ITelephony interface is not up yet.
switch(TelephonyManager.getDefault().getCurrentPhoneType()) {
- case Phone.PHONE_TYPE_CDMA:
+ case PhoneConstants.PHONE_TYPE_CDMA:
return new CdmaCellLocation();
- case Phone.PHONE_TYPE_GSM:
+ case PhoneConstants.PHONE_TYPE_GSM:
return new GsmCellLocation();
default:
return null;
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 698206c..def6939 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -26,7 +26,6 @@
import android.util.Log;
import com.android.internal.telephony.IPhoneStateListener;
-import com.android.internal.telephony.Phone;
/**
* A listener class for monitoring changes in specific telephony states
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
old mode 100644
new mode 100755
index 1049669..92b889b
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -48,7 +48,8 @@
};
/** @hide */
- public static final int INVALID_SNR = 0x7FFFFFFF;
+ //Use int max, as -1 is a valid value in signal strength
+ public static final int INVALID = 0x7FFFFFFF;
private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
@@ -64,7 +65,6 @@
private int mLteCqi;
private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
-
/**
* Create a new SignalStrength from a intent notifier Bundle
*
@@ -96,15 +96,39 @@
mEvdoDbm = -1;
mEvdoEcio = -1;
mEvdoSnr = -1;
- mLteSignalStrength = -1;
- mLteRsrp = -1;
- mLteRsrq = -1;
- mLteRssnr = INVALID_SNR;
- mLteCqi = -1;
+ mLteSignalStrength = 99;
+ mLteRsrp = INVALID;
+ mLteRsrq = INVALID;
+ mLteRssnr = INVALID;
+ mLteCqi = INVALID;
isGsm = true;
}
/**
+ * This constructor is used to create SignalStrength with default
+ * values and set the isGsmFlag with the value passed in the input
+ *
+ * @param gsmFlag true if Gsm Phone,false if Cdma phone
+ * @return newly created SignalStrength
+ * @hide
+ */
+ public SignalStrength(boolean gsmFlag) {
+ mGsmSignalStrength = 99;
+ mGsmBitErrorRate = -1;
+ mCdmaDbm = -1;
+ mCdmaEcio = -1;
+ mEvdoDbm = -1;
+ mEvdoEcio = -1;
+ mEvdoSnr = -1;
+ mLteSignalStrength = 99;
+ mLteRsrp = INVALID;
+ mLteRsrq = INVALID;
+ mLteRssnr = INVALID;
+ mLteCqi = INVALID;
+ isGsm = gsmFlag;
+ }
+
+ /**
* Constructor
*
* @hide
@@ -138,9 +162,8 @@
int cdmaDbm, int cdmaEcio,
int evdoDbm, int evdoEcio, int evdoSnr,
boolean gsm) {
- this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
- evdoDbm, evdoEcio, evdoSnr, -1, -1,
- -1, INVALID_SNR, -1, gsm);
+ this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, evdoDbm, evdoEcio, evdoSnr, 99,
+ INVALID, INVALID, INVALID, INVALID, gsm);
}
/**
@@ -236,7 +259,54 @@
};
/**
- * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS 27.007 8.5
+ * Validate the individual signal strength fields as per the range
+ * specified in ril.h
+ * Set to invalid any field that is not in the valid range
+ * Cdma, evdo, lte rsrp & rsrq values are sign converted
+ * when received from ril interface
+ *
+ * @return
+ * Valid values for all signalstrength fields
+ * @hide
+ */
+ public void validateInput() {
+ if (DBG) log("Signal before validate=" + this);
+ // TS 27.007 8.5
+ mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
+ // BER no change;
+
+ mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
+ mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160;
+
+ mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
+ mEvdoEcio = (mEvdoEcio > 0) ? -mEvdoEcio : -1;
+ mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
+
+ // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
+ mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
+ mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID;
+ mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
+ mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
+ : SignalStrength.INVALID;
+ // Cqi no change
+ if (DBG) log("Signal after validate=" + this);
+ }
+
+ /**
+ * @param true - Gsm, Lte phones
+ * false - Cdma phones
+ *
+ * Used by voice phone to set the isGsm
+ * flag
+ * @hide
+ */
+ public void setGsm(boolean gsmFlag) {
+ isGsm = gsmFlag;
+ }
+
+ /**
+ * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
+ * 27.007 8.5
*/
public int getGsmSignalStrength() {
return this.mGsmSignalStrength;
@@ -293,25 +363,19 @@
int level;
if (isGsm) {
- // TODO Need solve the discrepancy of invalid values between
- // RIL_LTE_SignalStrength and here.
- if ((mLteSignalStrength == -1)
- && (mLteRsrp == -1)
- && (mLteRsrq == -1)
- && (mLteCqi == -1)) {
+ level = getLteLevel();
+ if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
level = getGsmLevel();
- } else {
- level = getLteLevel();
}
} else {
int cdmaLevel = getCdmaLevel();
int evdoLevel = getEvdoLevel();
if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know evdo, use cdma */
- level = getCdmaLevel();
+ level = cdmaLevel;
} else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know cdma, use evdo */
- level = getEvdoLevel();
+ level = evdoLevel;
} else {
/* We know both, use the lowest level */
level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
@@ -329,10 +393,7 @@
public int getAsuLevel() {
int asuLevel;
if (isGsm) {
- if ((mLteSignalStrength == -1)
- && (mLteRsrp == -1)
- && (mLteRsrq == -1)
- && (mLteCqi == -1)) {
+ if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
asuLevel = getGsmAsuLevel();
} else {
asuLevel = getLteAsuLevel();
@@ -364,16 +425,17 @@
int dBm;
if(isGsm()) {
- if ((mLteSignalStrength == -1)
- && (mLteRsrp == -1)
- && (mLteRsrq == -1)
- && (mLteCqi == -1)) {
+ if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
dBm = getGsmDbm();
} else {
dBm = getLteDbm();
}
} else {
- dBm = getCdmaDbm();
+ int cdmaDbm = getCdmaDbm();
+ int evdoDbm = getEvdoDbm();
+
+ return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm
+ : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm));
}
if (DBG) log("getDbm=" + dBm);
return dBm;
@@ -568,34 +630,63 @@
* @hide
*/
public int getLteLevel() {
- int levelLteRsrp = 0;
- int levelLteRssnr = 0;
+ /*
+ * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
+ * signal + noise RSRP = reference signal dBm RSRQ = quality of signal
+ * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
+ * = -10log P1/P2 dB
+ */
+ int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
- if (mLteRsrp == -1) levelLteRsrp = 0;
- else if (mLteRsrp >= -95) levelLteRsrp = SIGNAL_STRENGTH_GREAT;
- else if (mLteRsrp >= -105) levelLteRsrp = SIGNAL_STRENGTH_GOOD;
- else if (mLteRsrp >= -115) levelLteRsrp = SIGNAL_STRENGTH_MODERATE;
- else levelLteRsrp = SIGNAL_STRENGTH_POOR;
+ if (mLteRsrp > -44) rsrpIconLevel = -1;
+ else if (mLteRsrp >= -85) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
+ else if (mLteRsrp >= -95) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
+ else if (mLteRsrp >= -105) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
+ else if (mLteRsrp >= -115) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
+ else if (mLteRsrp >= -140) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- if (mLteRssnr == INVALID_SNR) levelLteRssnr = 0;
- else if (mLteRssnr >= 45) levelLteRssnr = SIGNAL_STRENGTH_GREAT;
- else if (mLteRssnr >= 10) levelLteRssnr = SIGNAL_STRENGTH_GOOD;
- else if (mLteRssnr >= -30) levelLteRssnr = SIGNAL_STRENGTH_MODERATE;
- else levelLteRssnr = SIGNAL_STRENGTH_POOR;
+ /*
+ * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
+ * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
+ * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
+ * Icon Only
+ */
+ if (mLteRssnr > 300) snrIconLevel = -1;
+ else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
+ else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
+ else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
+ else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
+ else if (mLteRssnr >= -200)
+ snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- int level;
- if (mLteRsrp == -1)
- level = levelLteRssnr;
- else if (mLteRssnr == INVALID_SNR)
- level = levelLteRsrp;
- else
- level = (levelLteRssnr < levelLteRsrp) ? levelLteRssnr : levelLteRsrp;
+ if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
+ + rsrpIconLevel + " snrIconLevel:" + snrIconLevel);
- if (DBG) log("Lte rsrp level: "+levelLteRsrp
- + " snr level: " + levelLteRssnr + " level: " + level);
- return level;
+ /* Choose a measurement type to use for notification */
+ if (snrIconLevel != -1 && rsrpIconLevel != -1) {
+ /*
+ * The number of bars displayed shall be the smaller of the bars
+ * associated with LTE RSRP and the bars associated with the LTE
+ * RS_SNR
+ */
+ return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
+ }
+
+ if (snrIconLevel != -1) return snrIconLevel;
+
+ if (rsrpIconLevel != -1) return rsrpIconLevel;
+
+ /* Valid values are (0-63, 99) as defined in TS 36.331 */
+ if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
+ else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
+ else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
+ else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
+ if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
+ + rssiIconLevel);
+ return rssiIconLevel;
+
}
-
/**
* Get the LTE signal level as an asu value between 0..97, 99 is unknown
* Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
@@ -605,8 +696,20 @@
public int getLteAsuLevel() {
int lteAsuLevel = 99;
int lteDbm = getLteDbm();
- if (lteDbm <= -140) lteAsuLevel = 0;
- else if (lteDbm >= -43) lteAsuLevel = 97;
+ /*
+ * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+ * 0 -140 dBm or less
+ * 1 -139 dBm
+ * 2...96 -138... -44 dBm
+ * 97 -43 dBm or greater
+ * 255 not known or not detectable
+ */
+ /*
+ * validateInput will always give a valid range between -140 t0 -44 as
+ * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255
+ * and not 97 or 0
+ */
+ if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255;
else lteAsuLevel = lteDbm + 140;
if (DBG) log("Lte Asu level: "+lteAsuLevel);
return lteAsuLevel;
diff --git a/telephony/java/android/telephony/SmsCbCmasInfo.java b/telephony/java/android/telephony/SmsCbCmasInfo.java
deleted file mode 100644
index 7a89d94..0000000
--- a/telephony/java/android/telephony/SmsCbCmasInfo.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Contains CMAS warning notification Type 1 elements for a {@link SmsCbMessage}.
- * Supported values for each element are defined in TIA-1149-0-1 (CMAS over CDMA) and
- * 3GPP TS 23.041 (for GSM/UMTS).
- *
- * {@hide}
- */
-public class SmsCbCmasInfo implements Parcelable {
-
- // CMAS message class (in GSM/UMTS message identifier or CDMA service category).
-
- /** Presidential-level alert (Korean Public Alert System Class 0 message). */
- public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0x00;
-
- /** Extreme threat to life and property (Korean Public Alert System Class 1 message). */
- public static final int CMAS_CLASS_EXTREME_THREAT = 0x01;
-
- /** Severe threat to life and property (Korean Public Alert System Class 1 message). */
- public static final int CMAS_CLASS_SEVERE_THREAT = 0x02;
-
- /** Child abduction emergency (AMBER Alert). */
- public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 0x03;
-
- /** CMAS test message. */
- public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 0x04;
-
- /** CMAS exercise. */
- public static final int CMAS_CLASS_CMAS_EXERCISE = 0x05;
-
- /** CMAS category for operator defined use. */
- public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 0x06;
-
- /** CMAS category for warning types that are reserved for future extension. */
- public static final int CMAS_CLASS_UNKNOWN = -1;
-
- // CMAS alert category (in CDMA type 1 elements record).
-
- /** CMAS alert category: Geophysical including landslide. */
- public static final int CMAS_CATEGORY_GEO = 0x00;
-
- /** CMAS alert category: Meteorological including flood. */
- public static final int CMAS_CATEGORY_MET = 0x01;
-
- /** CMAS alert category: General emergency and public safety. */
- public static final int CMAS_CATEGORY_SAFETY = 0x02;
-
- /** CMAS alert category: Law enforcement, military, homeland/local/private security. */
- public static final int CMAS_CATEGORY_SECURITY = 0x03;
-
- /** CMAS alert category: Rescue and recovery. */
- public static final int CMAS_CATEGORY_RESCUE = 0x04;
-
- /** CMAS alert category: Fire suppression and rescue. */
- public static final int CMAS_CATEGORY_FIRE = 0x05;
-
- /** CMAS alert category: Medical and public health. */
- public static final int CMAS_CATEGORY_HEALTH = 0x06;
-
- /** CMAS alert category: Pollution and other environmental. */
- public static final int CMAS_CATEGORY_ENV = 0x07;
-
- /** CMAS alert category: Public and private transportation. */
- public static final int CMAS_CATEGORY_TRANSPORT = 0x08;
-
- /** CMAS alert category: Utility, telecom, other non-transport infrastructure. */
- public static final int CMAS_CATEGORY_INFRA = 0x09;
-
- /** CMAS alert category: Chem, bio, radiological, nuclear, high explosive threat or attack. */
- public static final int CMAS_CATEGORY_CBRNE = 0x0a;
-
- /** CMAS alert category: Other events. */
- public static final int CMAS_CATEGORY_OTHER = 0x0b;
-
- /**
- * CMAS alert category is unknown. The category is only available for CDMA broadcasts
- * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown.
- */
- public static final int CMAS_CATEGORY_UNKNOWN = -1;
-
- // CMAS response type (in CDMA type 1 elements record).
-
- /** CMAS response type: Take shelter in place. */
- public static final int CMAS_RESPONSE_TYPE_SHELTER = 0x00;
-
- /** CMAS response type: Evacuate (Relocate). */
- public static final int CMAS_RESPONSE_TYPE_EVACUATE = 0x01;
-
- /** CMAS response type: Make preparations. */
- public static final int CMAS_RESPONSE_TYPE_PREPARE = 0x02;
-
- /** CMAS response type: Execute a pre-planned activity. */
- public static final int CMAS_RESPONSE_TYPE_EXECUTE = 0x03;
-
- /** CMAS response type: Attend to information sources. */
- public static final int CMAS_RESPONSE_TYPE_MONITOR = 0x04;
-
- /** CMAS response type: Avoid hazard. */
- public static final int CMAS_RESPONSE_TYPE_AVOID = 0x05;
-
- /** CMAS response type: Evaluate the information in this message (not for public warnings). */
- public static final int CMAS_RESPONSE_TYPE_ASSESS = 0x06;
-
- /** CMAS response type: No action recommended. */
- public static final int CMAS_RESPONSE_TYPE_NONE = 0x07;
-
- /**
- * CMAS response type is unknown. The response type is only available for CDMA broadcasts
- * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown.
- */
- public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1;
-
- // 4-bit CMAS severity (in GSM/UMTS message identifier or CDMA type 1 elements record).
-
- /** CMAS severity type: Extraordinary threat to life or property. */
- public static final int CMAS_SEVERITY_EXTREME = 0x0;
-
- /** CMAS severity type: Significant threat to life or property. */
- public static final int CMAS_SEVERITY_SEVERE = 0x1;
-
- /**
- * CMAS alert severity is unknown. The severity is available for CDMA warning alerts
- * containing a type 1 elements record and for all GSM and UMTS alerts except for the
- * Presidential-level alert class (Korean Public Alert System Class 0).
- */
- public static final int CMAS_SEVERITY_UNKNOWN = -1;
-
- // CMAS urgency (in GSM/UMTS message identifier or CDMA type 1 elements record).
-
- /** CMAS urgency type: Responsive action should be taken immediately. */
- public static final int CMAS_URGENCY_IMMEDIATE = 0x0;
-
- /** CMAS urgency type: Responsive action should be taken within the next hour. */
- public static final int CMAS_URGENCY_EXPECTED = 0x1;
-
- /**
- * CMAS alert urgency is unknown. The urgency is available for CDMA warning alerts
- * containing a type 1 elements record and for all GSM and UMTS alerts except for the
- * Presidential-level alert class (Korean Public Alert System Class 0).
- */
- public static final int CMAS_URGENCY_UNKNOWN = -1;
-
- // CMAS certainty (in GSM/UMTS message identifier or CDMA type 1 elements record).
-
- /** CMAS certainty type: Determined to have occurred or to be ongoing. */
- public static final int CMAS_CERTAINTY_OBSERVED = 0x0;
-
- /** CMAS certainty type: Likely (probability > ~50%). */
- public static final int CMAS_CERTAINTY_LIKELY = 0x1;
-
- /**
- * CMAS alert certainty is unknown. The certainty is available for CDMA warning alerts
- * containing a type 1 elements record and for all GSM and UMTS alerts except for the
- * Presidential-level alert class (Korean Public Alert System Class 0).
- */
- public static final int CMAS_CERTAINTY_UNKNOWN = -1;
-
- /** CMAS message class. */
- private final int mMessageClass;
-
- /** CMAS category. */
- private final int mCategory;
-
- /** CMAS response type. */
- private final int mResponseType;
-
- /** CMAS severity. */
- private final int mSeverity;
-
- /** CMAS urgency. */
- private final int mUrgency;
-
- /** CMAS certainty. */
- private final int mCertainty;
-
- /** Create a new SmsCbCmasInfo object with the specified values. */
- public SmsCbCmasInfo(int messageClass, int category, int responseType, int severity,
- int urgency, int certainty) {
- mMessageClass = messageClass;
- mCategory = category;
- mResponseType = responseType;
- mSeverity = severity;
- mUrgency = urgency;
- mCertainty = certainty;
- }
-
- /** Create a new SmsCbCmasInfo object from a Parcel. */
- SmsCbCmasInfo(Parcel in) {
- mMessageClass = in.readInt();
- mCategory = in.readInt();
- mResponseType = in.readInt();
- mSeverity = in.readInt();
- mUrgency = in.readInt();
- mCertainty = in.readInt();
- }
-
- /**
- * Flatten this object into a Parcel.
- *
- * @param dest The Parcel in which the object should be written.
- * @param flags Additional flags about how the object should be written (ignored).
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mMessageClass);
- dest.writeInt(mCategory);
- dest.writeInt(mResponseType);
- dest.writeInt(mSeverity);
- dest.writeInt(mUrgency);
- dest.writeInt(mCertainty);
- }
-
- /**
- * Returns the CMAS message class, e.g. {@link #CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT}.
- * @return one of the {@code CMAS_CLASS} values
- */
- public int getMessageClass() {
- return mMessageClass;
- }
-
- /**
- * Returns the CMAS category, e.g. {@link #CMAS_CATEGORY_GEO}.
- * @return one of the {@code CMAS_CATEGORY} values
- */
- public int getCategory() {
- return mCategory;
- }
-
- /**
- * Returns the CMAS response type, e.g. {@link #CMAS_RESPONSE_TYPE_SHELTER}.
- * @return one of the {@code CMAS_RESPONSE_TYPE} values
- */
- public int getResponseType() {
- return mResponseType;
- }
-
- /**
- * Returns the CMAS severity, e.g. {@link #CMAS_SEVERITY_EXTREME}.
- * @return one of the {@code CMAS_SEVERITY} values
- */
- public int getSeverity() {
- return mSeverity;
- }
-
- /**
- * Returns the CMAS urgency, e.g. {@link #CMAS_URGENCY_IMMEDIATE}.
- * @return one of the {@code CMAS_URGENCY} values
- */
- public int getUrgency() {
- return mUrgency;
- }
-
- /**
- * Returns the CMAS certainty, e.g. {@link #CMAS_CERTAINTY_OBSERVED}.
- * @return one of the {@code CMAS_CERTAINTY} values
- */
- public int getCertainty() {
- return mCertainty;
- }
-
- @Override
- public String toString() {
- return "SmsCbCmasInfo{messageClass=" + mMessageClass + ", category=" + mCategory
- + ", responseType=" + mResponseType + ", severity=" + mSeverity
- + ", urgency=" + mUrgency + ", certainty=" + mCertainty + '}';
- }
-
- /**
- * Describe the kinds of special objects contained in the marshalled representation.
- * @return a bitmask indicating this Parcelable contains no special objects
- */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Creator for unparcelling objects. */
- public static final Parcelable.Creator<SmsCbCmasInfo>
- CREATOR = new Parcelable.Creator<SmsCbCmasInfo>() {
- public SmsCbCmasInfo createFromParcel(Parcel in) {
- return new SmsCbCmasInfo(in);
- }
-
- public SmsCbCmasInfo[] newArray(int size) {
- return new SmsCbCmasInfo[size];
- }
- };
-}
diff --git a/telephony/java/android/telephony/SmsCbEtwsInfo.java b/telephony/java/android/telephony/SmsCbEtwsInfo.java
deleted file mode 100644
index 0890d52..0000000
--- a/telephony/java/android/telephony/SmsCbEtwsInfo.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.format.Time;
-
-import com.android.internal.telephony.IccUtils;
-
-import java.util.Arrays;
-
-/**
- * Contains information elements for a GSM or UMTS ETWS warning notification.
- * Supported values for each element are defined in 3GPP TS 23.041.
- *
- * {@hide}
- */
-public class SmsCbEtwsInfo implements Parcelable {
-
- /** ETWS warning type for earthquake. */
- public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00;
-
- /** ETWS warning type for tsunami. */
- public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01;
-
- /** ETWS warning type for earthquake and tsunami. */
- public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02;
-
- /** ETWS warning type for test messages. */
- public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 0x03;
-
- /** ETWS warning type for other emergency types. */
- public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 0x04;
-
- /** Unknown ETWS warning type. */
- public static final int ETWS_WARNING_TYPE_UNKNOWN = -1;
-
- /** One of the ETWS warning type constants defined in this class. */
- private final int mWarningType;
-
- /** Whether or not to activate the emergency user alert tone and vibration. */
- private final boolean mEmergencyUserAlert;
-
- /** Whether or not to activate a popup alert. */
- private final boolean mActivatePopup;
-
- /**
- * 50-byte security information (ETWS primary notification for GSM only). As of Release 10,
- * 3GPP TS 23.041 states that the UE shall ignore the ETWS primary notification timestamp
- * and digital signature if received. Therefore it is treated as a raw byte array and
- * parceled with the broadcast intent if present, but the timestamp is only computed if an
- * application asks for the individual components.
- */
- private final byte[] mWarningSecurityInformation;
-
- /** Create a new SmsCbEtwsInfo object with the specified values. */
- public SmsCbEtwsInfo(int warningType, boolean emergencyUserAlert, boolean activatePopup,
- byte[] warningSecurityInformation) {
- mWarningType = warningType;
- mEmergencyUserAlert = emergencyUserAlert;
- mActivatePopup = activatePopup;
- mWarningSecurityInformation = warningSecurityInformation;
- }
-
- /** Create a new SmsCbEtwsInfo object from a Parcel. */
- SmsCbEtwsInfo(Parcel in) {
- mWarningType = in.readInt();
- mEmergencyUserAlert = (in.readInt() != 0);
- mActivatePopup = (in.readInt() != 0);
- mWarningSecurityInformation = in.createByteArray();
- }
-
- /**
- * Flatten this object into a Parcel.
- *
- * @param dest The Parcel in which the object should be written.
- * @param flags Additional flags about how the object should be written (ignored).
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mWarningType);
- dest.writeInt(mEmergencyUserAlert ? 1 : 0);
- dest.writeInt(mActivatePopup ? 1 : 0);
- dest.writeByteArray(mWarningSecurityInformation);
- }
-
- /**
- * Returns the ETWS warning type.
- * @return a warning type such as {@link #ETWS_WARNING_TYPE_EARTHQUAKE}
- */
- public int getWarningType() {
- return mWarningType;
- }
-
- /**
- * Returns the ETWS emergency user alert flag.
- * @return true to notify terminal to activate emergency user alert; false otherwise
- */
- public boolean isEmergencyUserAlert() {
- return mEmergencyUserAlert;
- }
-
- /**
- * Returns the ETWS activate popup flag.
- * @return true to notify terminal to activate display popup; false otherwise
- */
- public boolean isPopupAlert() {
- return mActivatePopup;
- }
-
- /**
- * Returns the Warning-Security-Information timestamp (GSM primary notifications only).
- * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received.
- * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present
- */
- public long getPrimaryNotificationTimestamp() {
- if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) {
- return 0;
- }
-
- int year = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[0]);
- int month = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[1]);
- int day = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[2]);
- int hour = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[3]);
- int minute = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[4]);
- int second = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[5]);
-
- // For the timezone, the most significant bit of the
- // least significant nibble is the sign byte
- // (meaning the max range of this field is 79 quarter-hours,
- // which is more than enough)
-
- byte tzByte = mWarningSecurityInformation[6];
-
- // Mask out sign bit.
- int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
-
- timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
-
- Time time = new Time(Time.TIMEZONE_UTC);
-
- // We only need to support years above 2000.
- time.year = year + 2000;
- time.month = month - 1;
- time.monthDay = day;
- time.hour = hour;
- time.minute = minute;
- time.second = second;
-
- // Timezone offset is in quarter hours.
- return time.toMillis(true) - (long) (timezoneOffset * 15 * 60 * 1000);
- }
-
- /**
- * Returns the digital signature (GSM primary notifications only). As of Release 10,
- * 3GPP TS 23.041 states that the UE shall ignore this value if received.
- * @return a byte array containing a copy of the primary notification digital signature
- */
- public byte[] getPrimaryNotificationSignature() {
- if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 50) {
- return null;
- }
- return Arrays.copyOfRange(mWarningSecurityInformation, 7, 50);
- }
-
- @Override
- public String toString() {
- return "SmsCbEtwsInfo{warningType=" + mWarningType + ", emergencyUserAlert="
- + mEmergencyUserAlert + ", activatePopup=" + mActivatePopup + '}';
- }
-
- /**
- * Describe the kinds of special objects contained in the marshalled representation.
- * @return a bitmask indicating this Parcelable contains no special objects
- */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Creator for unparcelling objects. */
- public static final Creator<SmsCbEtwsInfo> CREATOR = new Creator<SmsCbEtwsInfo>() {
- public SmsCbEtwsInfo createFromParcel(Parcel in) {
- return new SmsCbEtwsInfo(in);
- }
-
- public SmsCbEtwsInfo[] newArray(int size) {
- return new SmsCbEtwsInfo[size];
- }
- };
-}
diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java
deleted file mode 100644
index 7b5bd0d..0000000
--- a/telephony/java/android/telephony/SmsCbLocation.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.telephony.gsm.GsmCellLocation;
-
-/**
- * Represents the location and geographical scope of a cell broadcast message.
- * For GSM/UMTS, the Location Area and Cell ID are set when the broadcast
- * geographical scope is cell wide or Location Area wide. For CDMA, the
- * broadcast geographical scope is always PLMN wide.
- *
- * @hide
- */
-public class SmsCbLocation implements Parcelable {
-
- /** The PLMN. Note that this field may be an empty string, but isn't allowed to be null. */
- private final String mPlmn;
-
- private final int mLac;
- private final int mCid;
-
- /**
- * Construct an empty location object. This is used for some test cases, and for
- * cell broadcasts saved in older versions of the database without location info.
- */
- public SmsCbLocation() {
- mPlmn = "";
- mLac = -1;
- mCid = -1;
- }
-
- /**
- * Construct a location object for the PLMN. This class is immutable, so
- * the same object can be reused for multiple broadcasts.
- */
- public SmsCbLocation(String plmn) {
- mPlmn = plmn;
- mLac = -1;
- mCid = -1;
- }
-
- /**
- * Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so
- * the same object can be reused for multiple broadcasts.
- */
- public SmsCbLocation(String plmn, int lac, int cid) {
- mPlmn = plmn;
- mLac = lac;
- mCid = cid;
- }
-
- /**
- * Initialize the object from a Parcel.
- */
- public SmsCbLocation(Parcel in) {
- mPlmn = in.readString();
- mLac = in.readInt();
- mCid = in.readInt();
- }
-
- /**
- * Returns the MCC/MNC of the network as a String.
- * @return the PLMN identifier (MCC+MNC) as a String
- */
- public String getPlmn() {
- return mPlmn;
- }
-
- /**
- * Returns the GSM location area code, or UMTS service area code.
- * @return location area code, -1 if unknown, 0xffff max legal value
- */
- public int getLac() {
- return mLac;
- }
-
- /**
- * Returns the GSM or UMTS cell ID.
- * @return gsm cell id, -1 if unknown, 0xffff max legal value
- */
- public int getCid() {
- return mCid;
- }
-
- @Override
- public int hashCode() {
- int hash = mPlmn.hashCode();
- hash = hash * 31 + mLac;
- hash = hash * 31 + mCid;
- return hash;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (o == null || !(o instanceof SmsCbLocation)) {
- return false;
- }
- SmsCbLocation other = (SmsCbLocation) o;
- return mPlmn.equals(other.mPlmn) && mLac == other.mLac && mCid == other.mCid;
- }
-
- @Override
- public String toString() {
- return '[' + mPlmn + ',' + mLac + ',' + mCid + ']';
- }
-
- /**
- * Test whether this location is within the location area of the specified object.
- *
- * @param area the location area to compare with this location
- * @return true if this location is contained within the specified location area
- */
- public boolean isInLocationArea(SmsCbLocation area) {
- if (mCid != -1 && mCid != area.mCid) {
- return false;
- }
- if (mLac != -1 && mLac != area.mLac) {
- return false;
- }
- return mPlmn.equals(area.mPlmn);
- }
-
- /**
- * Test whether this location is within the location area of the CellLocation.
- *
- * @param plmn the PLMN to use for comparison
- * @param lac the Location Area (GSM) or Service Area (UMTS) to compare with
- * @param cid the Cell ID to compare with
- * @return true if this location is contained within the specified PLMN, LAC, and Cell ID
- */
- public boolean isInLocationArea(String plmn, int lac, int cid) {
- if (!mPlmn.equals(plmn)) {
- return false;
- }
-
- if (mLac != -1 && mLac != lac) {
- return false;
- }
-
- if (mCid != -1 && mCid != cid) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Flatten this object into a Parcel.
- *
- * @param dest The Parcel in which the object should be written.
- * @param flags Additional flags about how the object should be written (ignored).
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mPlmn);
- dest.writeInt(mLac);
- dest.writeInt(mCid);
- }
-
- public static final Parcelable.Creator<SmsCbLocation> CREATOR
- = new Parcelable.Creator<SmsCbLocation>() {
- @Override
- public SmsCbLocation createFromParcel(Parcel in) {
- return new SmsCbLocation(in);
- }
-
- @Override
- public SmsCbLocation[] newArray(int size) {
- return new SmsCbLocation[size];
- }
- };
-
- /**
- * Describe the kinds of special objects contained in the marshalled representation.
- * @return a bitmask indicating this Parcelable contains no special objects
- */
- @Override
- public int describeContents() {
- return 0;
- }
-}
diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java
deleted file mode 100644
index 046bf8c..0000000
--- a/telephony/java/android/telephony/SmsCbMessage.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.os.Parcelable;
-
-/**
- * Parcelable object containing a received cell broadcast message. There are four different types
- * of Cell Broadcast messages:
- *
- * <ul>
- * <li>opt-in informational broadcasts, e.g. news, weather, stock quotes, sports scores</li>
- * <li>cell information messages, broadcast on channel 50, indicating the current cell name for
- * roaming purposes (required to display on the idle screen in Brazil)</li>
- * <li>emergency broadcasts for the Japanese Earthquake and Tsunami Warning System (ETWS)</li>
- * <li>emergency broadcasts for the American Commercial Mobile Alert Service (CMAS)</li>
- * </ul>
- *
- * <p>There are also four different CB message formats: GSM, ETWS Primary Notification (GSM only),
- * UMTS, and CDMA. Some fields are only applicable for some message formats. Other fields were
- * unified under a common name, avoiding some names, such as "Message Identifier", that refer to
- * two completely different concepts in 3GPP and CDMA.
- *
- * <p>The GSM/UMTS Message Identifier field is available via {@link #getServiceCategory}, the name
- * of the equivalent field in CDMA. In both cases the service category is a 16-bit value, but 3GPP
- * and 3GPP2 have completely different meanings for the respective values. For ETWS and CMAS, the
- * application should
- *
- * <p>The CDMA Message Identifier field is available via {@link #getSerialNumber}, which is used
- * to detect the receipt of a duplicate message to be discarded. In CDMA, the message ID is
- * unique to the current PLMN. In GSM/UMTS, there is a 16-bit serial number containing a 2-bit
- * Geographical Scope field which indicates whether the 10-bit message code and 4-bit update number
- * are considered unique to the PLMN, to the current cell, or to the current Location Area (or
- * Service Area in UMTS). The relevant values are concatenated into a single String which will be
- * unique if the messages are not duplicates.
- *
- * <p>The SMS dispatcher does not detect duplicate messages. However, it does concatenate the
- * pages of a GSM multi-page cell broadcast into a single SmsCbMessage object.
- *
- * <p>Interested applications with {@code RECEIVE_SMS_PERMISSION} can register to receive
- * {@code SMS_CB_RECEIVED_ACTION} broadcast intents for incoming non-emergency broadcasts.
- * Only system applications such as the CellBroadcastReceiver may receive notifications for
- * emergency broadcasts (ETWS and CMAS). This is intended to prevent any potential for delays or
- * interference with the immediate display of the alert message and playing of the alert sound and
- * vibration pattern, which could be caused by poorly written or malicious non-system code.
- *
- * @hide
- */
-public class SmsCbMessage implements Parcelable {
-
- protected static final String LOG_TAG = "SMSCB";
-
- /** Cell wide geographical scope with immediate display (GSM/UMTS only). */
- public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0;
-
- /** PLMN wide geographical scope (GSM/UMTS and all CDMA broadcasts). */
- public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1;
-
- /** Location / service area wide geographical scope (GSM/UMTS only). */
- public static final int GEOGRAPHICAL_SCOPE_LA_WIDE = 2;
-
- /** Cell wide geographical scope (GSM/UMTS only). */
- public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3;
-
- /** GSM or UMTS format cell broadcast. */
- public static final int MESSAGE_FORMAT_3GPP = 1;
-
- /** CDMA format cell broadcast. */
- public static final int MESSAGE_FORMAT_3GPP2 = 2;
-
- /** Normal message priority. */
- public static final int MESSAGE_PRIORITY_NORMAL = 0;
-
- /** Interactive message priority. */
- public static final int MESSAGE_PRIORITY_INTERACTIVE = 1;
-
- /** Urgent message priority. */
- public static final int MESSAGE_PRIORITY_URGENT = 2;
-
- /** Emergency message priority. */
- public static final int MESSAGE_PRIORITY_EMERGENCY = 3;
-
- /** Format of this message (for interpretation of service category values). */
- private final int mMessageFormat;
-
- /** Geographical scope of broadcast. */
- private final int mGeographicalScope;
-
- /**
- * Serial number of broadcast (message identifier for CDMA, geographical scope + message code +
- * update number for GSM/UMTS). The serial number plus the location code uniquely identify
- * a cell broadcast for duplicate detection.
- */
- private final int mSerialNumber;
-
- /**
- * Location identifier for this message. It consists of the current operator MCC/MNC as a
- * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
- * message is not binary 01, the Location Area is included for comparison. If the GS is
- * 00 or 11, the Cell ID is also included. LAC and Cell ID are -1 if not specified.
- */
- private final SmsCbLocation mLocation;
-
- /**
- * 16-bit CDMA service category or GSM/UMTS message identifier. For ETWS and CMAS warnings,
- * the information provided by the category is also available via {@link #getEtwsWarningInfo()}
- * or {@link #getCmasWarningInfo()}.
- */
- private final int mServiceCategory;
-
- /** Message language, as a two-character string, e.g. "en". */
- private final String mLanguage;
-
- /** Message body, as a String. */
- private final String mBody;
-
- /** Message priority (including emergency priority). */
- private final int mPriority;
-
- /** ETWS warning notification information (ETWS warnings only). */
- private final SmsCbEtwsInfo mEtwsWarningInfo;
-
- /** CMAS warning notification information (CMAS warnings only). */
- private final SmsCbCmasInfo mCmasWarningInfo;
-
- /**
- * Create a new SmsCbMessage with the specified data.
- */
- public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
- SmsCbLocation location, int serviceCategory, String language, String body,
- int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) {
- mMessageFormat = messageFormat;
- mGeographicalScope = geographicalScope;
- mSerialNumber = serialNumber;
- mLocation = location;
- mServiceCategory = serviceCategory;
- mLanguage = language;
- mBody = body;
- mPriority = priority;
- mEtwsWarningInfo = etwsWarningInfo;
- mCmasWarningInfo = cmasWarningInfo;
- }
-
- /** Create a new SmsCbMessage object from a Parcel. */
- public SmsCbMessage(Parcel in) {
- mMessageFormat = in.readInt();
- mGeographicalScope = in.readInt();
- mSerialNumber = in.readInt();
- mLocation = new SmsCbLocation(in);
- mServiceCategory = in.readInt();
- mLanguage = in.readString();
- mBody = in.readString();
- mPriority = in.readInt();
- int type = in.readInt();
- switch (type) {
- case 'E':
- // unparcel ETWS warning information
- mEtwsWarningInfo = new SmsCbEtwsInfo(in);
- mCmasWarningInfo = null;
- break;
-
- case 'C':
- // unparcel CMAS warning information
- mEtwsWarningInfo = null;
- mCmasWarningInfo = new SmsCbCmasInfo(in);
- break;
-
- default:
- mEtwsWarningInfo = null;
- mCmasWarningInfo = null;
- }
- }
-
- /**
- * Flatten this object into a Parcel.
- *
- * @param dest The Parcel in which the object should be written.
- * @param flags Additional flags about how the object should be written (ignored).
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mMessageFormat);
- dest.writeInt(mGeographicalScope);
- dest.writeInt(mSerialNumber);
- mLocation.writeToParcel(dest, flags);
- dest.writeInt(mServiceCategory);
- dest.writeString(mLanguage);
- dest.writeString(mBody);
- dest.writeInt(mPriority);
- if (mEtwsWarningInfo != null) {
- // parcel ETWS warning information
- dest.writeInt('E');
- mEtwsWarningInfo.writeToParcel(dest, flags);
- } else if (mCmasWarningInfo != null) {
- // parcel CMAS warning information
- dest.writeInt('C');
- mCmasWarningInfo.writeToParcel(dest, flags);
- } else {
- // no ETWS or CMAS warning information
- dest.writeInt('0');
- }
- }
-
- public static final Parcelable.Creator<SmsCbMessage> CREATOR
- = new Parcelable.Creator<SmsCbMessage>() {
- @Override
- public SmsCbMessage createFromParcel(Parcel in) {
- return new SmsCbMessage(in);
- }
-
- @Override
- public SmsCbMessage[] newArray(int size) {
- return new SmsCbMessage[size];
- }
- };
-
- /**
- * Return the geographical scope of this message (GSM/UMTS only).
- *
- * @return Geographical scope
- */
- public int getGeographicalScope() {
- return mGeographicalScope;
- }
-
- /**
- * Return the broadcast serial number of broadcast (message identifier for CDMA, or
- * geographical scope + message code + update number for GSM/UMTS). The serial number plus
- * the location code uniquely identify a cell broadcast for duplicate detection.
- *
- * @return the 16-bit CDMA message identifier or GSM/UMTS serial number
- */
- public int getSerialNumber() {
- return mSerialNumber;
- }
-
- /**
- * Return the location identifier for this message, consisting of the MCC/MNC as a
- * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
- * message is not binary 01, the Location Area is included. If the GS is 00 or 11, the
- * cell ID is also included. The {@link SmsCbLocation} object includes a method to test
- * if the location is included within another location area or within a PLMN and CellLocation.
- *
- * @return the geographical location code for duplicate message detection
- */
- public SmsCbLocation getLocation() {
- return mLocation;
- }
-
- /**
- * Return the 16-bit CDMA service category or GSM/UMTS message identifier. The interpretation
- * of the category is radio technology specific. For ETWS and CMAS warnings, the information
- * provided by the category is available via {@link #getEtwsWarningInfo()} or
- * {@link #getCmasWarningInfo()} in a radio technology independent format.
- *
- * @return the radio technology specific service category
- */
- public int getServiceCategory() {
- return mServiceCategory;
- }
-
- /**
- * Get the ISO-639-1 language code for this message, or null if unspecified
- *
- * @return Language code
- */
- public String getLanguageCode() {
- return mLanguage;
- }
-
- /**
- * Get the body of this message, or null if no body available
- *
- * @return Body, or null
- */
- public String getMessageBody() {
- return mBody;
- }
-
- /**
- * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}).
- * @return an integer representing 3GPP or 3GPP2 message format
- */
- public int getMessageFormat() {
- return mMessageFormat;
- }
-
- /**
- * Get the message priority. Normal broadcasts return {@link #MESSAGE_PRIORITY_NORMAL}
- * and emergency broadcasts return {@link #MESSAGE_PRIORITY_EMERGENCY}. CDMA also may return
- * {@link #MESSAGE_PRIORITY_INTERACTIVE} or {@link #MESSAGE_PRIORITY_URGENT}.
- * @return an integer representing the message priority
- */
- public int getMessagePriority() {
- return mPriority;
- }
-
- /**
- * If this is an ETWS warning notification then this method will return an object containing
- * the ETWS warning type, the emergency user alert flag, and the popup flag. If this is an
- * ETWS primary notification (GSM only), there will also be a 7-byte timestamp and 43-byte
- * digital signature. As of Release 10, 3GPP TS 23.041 states that the UE shall ignore the
- * ETWS primary notification timestamp and digital signature if received.
- *
- * @return an SmsCbEtwsInfo object, or null if this is not an ETWS warning notification
- */
- public SmsCbEtwsInfo getEtwsWarningInfo() {
- return mEtwsWarningInfo;
- }
-
- /**
- * If this is a CMAS warning notification then this method will return an object containing
- * the CMAS message class, category, response type, severity, urgency and certainty.
- * The message class is always present. Severity, urgency and certainty are present for CDMA
- * warning notifications containing a type 1 elements record and for GSM and UMTS warnings
- * except for the Presidential-level alert category. Category and response type are only
- * available for CDMA notifications containing a type 1 elements record.
- *
- * @return an SmsCbCmasInfo object, or null if this is not a CMAS warning notification
- */
- public SmsCbCmasInfo getCmasWarningInfo() {
- return mCmasWarningInfo;
- }
-
- /**
- * Return whether this message is an emergency (PWS) message type.
- * @return true if the message is a public warning notification; false otherwise
- */
- public boolean isEmergencyMessage() {
- return mPriority == MESSAGE_PRIORITY_EMERGENCY;
- }
-
- /**
- * Return whether this message is an ETWS warning alert.
- * @return true if the message is an ETWS warning notification; false otherwise
- */
- public boolean isEtwsMessage() {
- return mEtwsWarningInfo != null;
- }
-
- /**
- * Return whether this message is a CMAS warning alert.
- * @return true if the message is a CMAS warning notification; false otherwise
- */
- public boolean isCmasMessage() {
- return mCmasWarningInfo != null;
- }
-
- @Override
- public String toString() {
- return "SmsCbMessage{geographicalScope=" + mGeographicalScope + ", serialNumber="
- + mSerialNumber + ", location=" + mLocation + ", serviceCategory="
- + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody
- + ", priority=" + mPriority
- + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
- + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}';
- }
-
- /**
- * Describe the kinds of special objects contained in the marshalled representation.
- * @return a bitmask indicating this Parcelable contains no special objects
- */
- @Override
- public int describeContents() {
- return 0;
- }
-}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
deleted file mode 100644
index 44bdaeb..0000000
--- a/telephony/java/android/telephony/SmsManager.java
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.app.PendingIntent;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.ISms;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.SmsRawData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/*
- * TODO(code review): Curious question... Why are a lot of these
- * methods not declared as static, since they do not seem to require
- * any local object state? Presumably this cannot be changed without
- * interfering with the API...
- */
-
-/**
- * Manages SMS operations such as sending data, text, and pdu SMS messages.
- * Get this object by calling the static method SmsManager.getDefault().
- */
-public final class SmsManager {
- /** Singleton object constructed during class initialization. */
- private static final SmsManager sInstance = new SmsManager();
-
- /**
- * 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 successfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK</code> for success,
- * or one of these errors:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- *
- * @throws IllegalArgumentException if 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");
- }
-
- try {
- ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (iccISms != null) {
- iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
- }
-
- /**
- * Divide a message text into several fragments, 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) {
- return SmsMessage.fragmentText(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
- * <code>PendingIntent</code>s (one for each message part) that is
- * broadcast when the corresponding message part has been sent.
- * The result code will be <code>Activity.RESULT_OK</code> for success,
- * or one of these errors:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntents if not null, an <code>ArrayList</code> of
- * <code>PendingIntent</code>s (one for each message part) that is
- * broadcast when the corresponding message part has been delivered
- * to the recipient. The raw pdu of the status report is in the
- * extended data ("pdu").
- *
- * @throws IllegalArgumentException if 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 successfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK</code> for success,
- * or one of these errors:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- *
- * @throws IllegalArgumentException if 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");
- }
-
- try {
- ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (iccISms != null) {
- iccISms.sendData(destinationAddress, scAddress, destinationPort & 0xFFFF,
- data, 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() {
- return sInstance;
- }
-
- private SmsManager() {
- //nothing
- }
-
- /**
- * Copy a raw SMS PDU to the ICC.
- * ICC (Integrated Circuit Card) is the card of the device.
- * For example, this can be the SIM or USIM for GSM.
- *
- * @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.
- * ICC (Integrated Circuit Card) is the card of the device.
- * For example, this can be the SIM or USIM for GSM.
- *
- * @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.
- * ICC (Integrated Circuit Card) is the card of the device.
- * For example, this can be the SIM or USIM for GSM.
- *
- * @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.
- * ICC (Integrated Circuit Card) is the card of the device.
- * For example, this can be the SIM or USIM for GSM.
- *
- * @return <code>ArrayList</code> of <code>SmsMessage</code> objects
- *
- * {@hide}
- */
- public static 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);
- }
-
- /**
- * Enable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages. All received messages will be broadcast in an
- * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED".
- * Note: This call is blocking, callers may want to avoid calling it from
- * the main thread of an application.
- *
- * @param messageIdentifier Message identifier as specified in TS 23.041
- * @return true if successful, false otherwise
- * @see #disableCellBroadcast(int)
- *
- * {@hide}
- */
- public boolean enableCellBroadcast(int messageIdentifier) {
- boolean success = false;
-
- try {
- ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (iccISms != null) {
- success = iccISms.enableCellBroadcast(messageIdentifier);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
- }
-
- /**
- * Disable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages.
- * Note: This call is blocking, callers may want to avoid calling it from
- * the main thread of an application.
- *
- * @param messageIdentifier Message identifier as specified in TS 23.041
- * @return true if successful, false otherwise
- *
- * @see #enableCellBroadcast(int)
- *
- * {@hide}
- */
- public boolean disableCellBroadcast(int messageIdentifier) {
- boolean success = false;
-
- try {
- ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (iccISms != null) {
- success = iccISms.disableCellBroadcast(messageIdentifier);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
- }
-
- /**
- * Enable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier range. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages. All received messages will be broadcast in an
- * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED".
- * Note: This call is blocking, callers may want to avoid calling it from
- * the main thread of an application.
- *
- * @param startMessageId first message identifier as specified in TS 23.041
- * @param endMessageId last message identifier as specified in TS 23.041
- * @return true if successful, false otherwise
- * @see #disableCellBroadcastRange(int, int)
- *
- * {@hide}
- */
- public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
- boolean success = false;
-
- try {
- ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (iccISms != null) {
- success = iccISms.enableCellBroadcastRange(startMessageId, endMessageId);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
- }
-
- /**
- * Disable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier range. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages.
- * Note: This call is blocking, callers may want to avoid calling it from
- * the main thread of an application.
- *
- * @param startMessageId first message identifier as specified in TS 23.041
- * @param endMessageId last message identifier as specified in TS 23.041
- * @return true if successful, false otherwise
- *
- * @see #enableCellBroadcastRange(int, int)
- *
- * {@hide}
- */
- public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
- boolean success = false;
-
- try {
- ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (iccISms != null) {
- success = iccISms.disableCellBroadcastRange(startMessageId, endMessageId);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
- }
-
- /**
- * 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 static ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
- ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
- if (records != null) {
- int count = records.size();
- for (int i = 0; i < count; i++) {
- SmsRawData data = records.get(i);
- // List contains all records, including "free" records (null)
- if (data != null) {
- SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes());
- if (sms != null) {
- 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;
- /** Failed because we reached the sending queue limit. {@hide} */
- static public final int RESULT_ERROR_LIMIT_EXCEEDED = 5;
- /** Failed because FDN is enabled. {@hide} */
- static public final int RESULT_ERROR_FDN_CHECK_FAILURE = 6;
-}
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
deleted file mode 100644
index 1410747..0000000
--- a/telephony/java/android/telephony/SmsMessage.java
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony;
-
-import android.os.Parcel;
-import android.util.Log;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-
-import java.lang.Math;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
-
-
-/**
- * A Short Message Service message.
- */
-public class SmsMessage {
- 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;
- }
-
- /** User data text encoding code unit size */
- public static final int ENCODING_UNKNOWN = 0;
- public static final int ENCODING_7BIT = 1;
- public static final int ENCODING_8BIT = 2;
- public static final int ENCODING_16BIT = 3;
- /**
- * @hide This value is not defined in global standard. Only in Korea, this is used.
- */
- public static final int ENCODING_KSC5601 = 4;
-
- /** 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.
- */
- 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;
-
- /**
- * Indicates a 3GPP format SMS message.
- * @hide pending API council approval
- */
- public static final String FORMAT_3GPP = "3gpp";
-
- /**
- * Indicates a 3GPP2 format SMS message.
- * @hide pending API council approval
- */
- public static final String FORMAT_3GPP2 = "3gpp2";
-
- /** Contains actual SmsMessage. Only public for debugging and for framework layer.
- *
- * @hide
- */
- public SmsMessageBase mWrappedSmsMessage;
-
- public static class SubmitPdu {
-
- public byte[] encodedScAddress; // Null if not applicable.
- public byte[] encodedMessage;
-
- public String toString() {
- return "SubmitPdu: encodedScAddress = "
- + Arrays.toString(encodedScAddress)
- + ", encodedMessage = "
- + Arrays.toString(encodedMessage);
- }
-
- /**
- * @hide
- */
- protected SubmitPdu(SubmitPduBase spb) {
- this.encodedMessage = spb.encodedMessage;
- this.encodedScAddress = spb.encodedScAddress;
- }
-
- }
-
- private SmsMessage(SmsMessageBase smb) {
- mWrappedSmsMessage = smb;
- }
-
- /**
- * Create an SmsMessage from a raw PDU.
- *
- * <p><b>This method will soon be deprecated</b> and all applications which handle
- * incoming SMS messages by processing the {@code SMS_RECEIVED_ACTION} broadcast
- * intent <b>must</b> now pass the new {@code format} String extra from the intent
- * into the new method {@code createFromPdu(byte[], String)} which takes an
- * extra format parameter. This is required in order to correctly decode the PDU on
- * devices that require support for both 3GPP and 3GPP2 formats at the same time,
- * such as dual-mode GSM/CDMA and CDMA/LTE phones.
- */
- public static SmsMessage createFromPdu(byte[] pdu) {
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
- String format = (PHONE_TYPE_CDMA == activePhone) ? FORMAT_3GPP2 : FORMAT_3GPP;
- return createFromPdu(pdu, format);
- }
-
- /**
- * Create an SmsMessage from a raw PDU with the specified message format. The
- * message format is passed in the {@code SMS_RECEIVED_ACTION} as the {@code format}
- * String extra, and will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format
- * or "3gpp2" for CDMA/LTE messages in 3GPP2 format.
- *
- * @param pdu the message PDU from the SMS_RECEIVED_ACTION intent
- * @param format the format extra from the SMS_RECEIVED_ACTION intent
- * @hide pending API council approval
- */
- public static SmsMessage createFromPdu(byte[] pdu, String format) {
- SmsMessageBase wrappedMessage;
-
- if (FORMAT_3GPP2.equals(format)) {
- wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
- } else if (FORMAT_3GPP.equals(format)) {
- wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
- } else {
- Log.e(LOG_TAG, "createFromPdu(): unsupported message format " + format);
- return null;
- }
-
- 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: [<alpha>],<length><CR><LF><pdu>
- *
- * Only public for debugging and for RIL
- *
- * {@hide}
- */
- public static SmsMessage newFromCMT(String[] lines) {
- // received SMS in 3GPP format
- SmsMessageBase wrappedMessage =
- com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);
-
- return new SmsMessage(wrappedMessage);
- }
-
- /** @hide */
- public static SmsMessage newFromParcel(Parcel p) {
- // received SMS in 3GPP2 format
- SmsMessageBase wrappedMessage =
- com.android.internal.telephony.cdma.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().getCurrentPhoneType();
-
- 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 wrappedMessage != null ? new SmsMessage(wrappedMessage) : null;
- }
-
- /**
- * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
- * length in bytes (not hex chars) less the SMSC header
- *
- * FIXME: This method is only used by a CTS test case that isn't run on CDMA devices.
- * We should probably deprecate it and remove the obsolete test case.
- */
- public static int getTPLayerLengthForPDU(String pdu) {
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
- if (PHONE_TYPE_CDMA == activePhone) {
- return com.android.internal.telephony.cdma.SmsMessage.getTPLayerLengthForPDU(pdu);
- } else {
- return com.android.internal.telephony.gsm.SmsMessage.getTPLayerLengthForPDU(pdu);
- }
- }
-
- /*
- * TODO(cleanup): It would make some sense if the result of
- * preprocessing a message to determine the proper encoding (i.e.
- * the resulting data structure from calculateLength) could be
- * passed as an argument to the actual final encoding function.
- * This would better ensure that the logic behind size calculation
- * actually matched the encoding.
- */
-
- /**
- * Calculates the number of SMS's required to encode the message body and
- * the number of characters remaining until the next message.
- *
- * @param msgBody the message to encode
- * @param use7bitOnly if true, characters that are not part of the
- * radio-specific 7-bit encoding are counted as single
- * space chars. If false, and if the messageBody contains
- * non-7-bit encodable characters, length is calculated
- * using a 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 an indicator of the encoding
- * code unit size (see the ENCODING_* definitions in this
- * class).
- */
- public static int[] calculateLength(CharSequence msgBody, boolean use7bitOnly) {
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
- TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ?
- com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly) :
- com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly);
- int ret[] = new int[4];
- ret[0] = ted.msgCount;
- ret[1] = ted.codeUnitCount;
- ret[2] = ted.codeUnitsRemaining;
- ret[3] = ted.codeUnitSize;
- return ret;
- }
-
- /**
- * Divide a message text into several fragments, none bigger than
- * the maximum SMS message text size.
- *
- * @param text text, must not be null.
- * @return an <code>ArrayList</code> of strings that, in order,
- * comprise the original msg text
- *
- * @hide
- */
- public static ArrayList<String> fragmentText(String text) {
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
- TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ?
- com.android.internal.telephony.cdma.SmsMessage.calculateLength(text, false) :
- com.android.internal.telephony.gsm.SmsMessage.calculateLength(text, false);
-
- // TODO(cleanup): The code here could be rolled into the logic
- // below cleanly if these MAX_* constants were defined more
- // flexibly...
-
- int limit;
- if (ted.codeUnitSize == ENCODING_7BIT) {
- int udhLength;
- if (ted.languageTable != 0 && ted.languageShiftTable != 0) {
- udhLength = GsmAlphabet.UDH_SEPTET_COST_TWO_SHIFT_TABLES;
- } else if (ted.languageTable != 0 || ted.languageShiftTable != 0) {
- udhLength = GsmAlphabet.UDH_SEPTET_COST_ONE_SHIFT_TABLE;
- } else {
- udhLength = 0;
- }
-
- if (ted.msgCount > 1) {
- udhLength += GsmAlphabet.UDH_SEPTET_COST_CONCATENATED_MESSAGE;
- }
-
- if (udhLength != 0) {
- udhLength += GsmAlphabet.UDH_SEPTET_COST_LENGTH;
- }
-
- limit = MAX_USER_DATA_SEPTETS - udhLength;
- } else {
- if (ted.msgCount > 1) {
- limit = MAX_USER_DATA_BYTES_WITH_HEADER;
- } else {
- limit = MAX_USER_DATA_BYTES;
- }
- }
-
- int pos = 0; // Index in code units.
- int textLen = text.length();
- ArrayList<String> result = new ArrayList<String>(ted.msgCount);
- while (pos < textLen) {
- int nextPos = 0; // Counts code units.
- if (ted.codeUnitSize == ENCODING_7BIT) {
- if (activePhone == PHONE_TYPE_CDMA && ted.msgCount == 1) {
- // For a singleton CDMA message, the encoding must be ASCII...
- nextPos = pos + Math.min(limit, textLen - pos);
- } else {
- // For multi-segment messages, CDMA 7bit equals GSM 7bit encoding (EMS mode).
- nextPos = GsmAlphabet.findGsmSeptetLimitIndex(text, pos, limit,
- ted.languageTable, ted.languageShiftTable);
- }
- } else { // Assume unicode.
- nextPos = pos + Math.min(limit / 2, textLen - pos);
- }
- if ((nextPos <= pos) || (nextPos > textLen)) {
- Log.e(LOG_TAG, "fragmentText failed (" + pos + " >= " + nextPos + " or " +
- nextPos + " >= " + textLen + ")");
- break;
- }
- result.add(text.substring(pos, nextPos));
- pos = nextPos;
- }
- return result;
- }
-
- /**
- * 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 radio
- * specific (GSM / CDMA) alphabet encoding are converted to as a
- * single space characters. If false, a messageBody containing
- * non-GSM or non-CDMA alphabet characters are encoded using
- * 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);
- }
-
- /*
- * TODO(cleanup): It looks like there is now no useful reason why
- * apps should generate pdus themselves using these routines,
- * instead of handing the raw data to SMSDispatcher (and thereby
- * have the phone process do the encoding). Moreover, CDMA now
- * has shared state (in the form of the msgId system property)
- * which can only be modified by the phone process, and hence
- * makes the output of these routines incorrect. Since they now
- * serve no purpose, they should probably just return null
- * directly, and be deprecated. Going further in that direction,
- * the above parsers of serialized pdu data should probably also
- * be gotten rid of, hiding all but the necessarily visible
- * structured data from client apps. A possible concern with
- * doing this is that apps may be using these routines to generate
- * pdus that are then sent elsewhere, some network server, for
- * example, and that always returning null would thereby break
- * otherwise useful apps.
- */
-
- /**
- * Get an SMS-SUBMIT PDU for a destination address and a message.
- * This method will not attempt to use any GSM national language 7 bit encodings.
- *
- * @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().getCurrentPhoneType();
-
- if (PHONE_TYPE_CDMA == activePhone) {
- spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
- destinationAddress, message, statusReportRequested, null);
- } 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 & port.
- * This method will not attempt to use any GSM national language 7 bit encodings.
- *
- * @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 data 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().getCurrentPhoneType();
-
- 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();
- }
-
- /**
- * 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();
- }
-}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index bc50906..fa4b7cd 100755
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -23,15 +23,20 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.util.Log;
import com.android.internal.telephony.IPhoneSubInfo;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.ITelephonyRegistry;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.TelephonyProperties;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Provides access to information about the telephony services on
@@ -131,25 +136,25 @@
* Retrieve with
* {@link android.content.Intent#getStringExtra(String)}.
*/
- public static final String EXTRA_STATE = Phone.STATE_KEY;
+ public static final String EXTRA_STATE = PhoneConstants.STATE_KEY;
/**
* Value used with {@link #EXTRA_STATE} corresponding to
* {@link #CALL_STATE_IDLE}.
*/
- public static final String EXTRA_STATE_IDLE = Phone.State.IDLE.toString();
+ public static final String EXTRA_STATE_IDLE = PhoneConstants.State.IDLE.toString();
/**
* Value used with {@link #EXTRA_STATE} corresponding to
* {@link #CALL_STATE_RINGING}.
*/
- public static final String EXTRA_STATE_RINGING = Phone.State.RINGING.toString();
+ public static final String EXTRA_STATE_RINGING = PhoneConstants.State.RINGING.toString();
/**
* Value used with {@link #EXTRA_STATE} corresponding to
* {@link #CALL_STATE_OFFHOOK}.
*/
- public static final String EXTRA_STATE_OFFHOOK = Phone.State.OFFHOOK.toString();
+ public static final String EXTRA_STATE_OFFHOOK = PhoneConstants.State.OFFHOOK.toString();
/**
* The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
@@ -279,13 +284,13 @@
}
/** No phone radio. */
- public static final int PHONE_TYPE_NONE = Phone.PHONE_TYPE_NONE;
+ public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE;
/** Phone radio is GSM. */
- public static final int PHONE_TYPE_GSM = Phone.PHONE_TYPE_GSM;
+ public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM;
/** Phone radio is CDMA. */
- public static final int PHONE_TYPE_CDMA = Phone.PHONE_TYPE_CDMA;
+ public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
/** Phone is via SIP. */
- public static final int PHONE_TYPE_SIP = Phone.PHONE_TYPE_SIP;
+ public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
/**
* Returns the current phone type.
@@ -348,8 +353,125 @@
int mode = SystemProperties.getInt("ro.telephony.default_network", -1);
if (mode == -1)
return PHONE_TYPE_NONE;
- return PhoneFactory.getPhoneType(mode);
+ return getPhoneType(mode);
}
+
+ /**
+ * This function returns the type of the phone, depending
+ * on the network mode.
+ *
+ * @param network mode
+ * @return Phone Type
+ *
+ * @hide
+ */
+ public static int getPhoneType(int networkMode) {
+ switch(networkMode) {
+ case RILConstants.NETWORK_MODE_CDMA:
+ case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
+ case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
+ return PhoneConstants.PHONE_TYPE_CDMA;
+
+ case RILConstants.NETWORK_MODE_WCDMA_PREF:
+ case RILConstants.NETWORK_MODE_GSM_ONLY:
+ case RILConstants.NETWORK_MODE_WCDMA_ONLY:
+ case RILConstants.NETWORK_MODE_GSM_UMTS:
+ return PhoneConstants.PHONE_TYPE_GSM;
+
+ // Use CDMA Phone for the global mode including CDMA
+ case RILConstants.NETWORK_MODE_GLOBAL:
+ case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
+ case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+ return PhoneConstants.PHONE_TYPE_CDMA;
+
+ case RILConstants.NETWORK_MODE_LTE_ONLY:
+ if (getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
+ return PhoneConstants.PHONE_TYPE_CDMA;
+ } else {
+ return PhoneConstants.PHONE_TYPE_GSM;
+ }
+ default:
+ return PhoneConstants.PHONE_TYPE_GSM;
+ }
+ }
+
+ /**
+ * The contents of the /proc/cmdline file
+ */
+ private static String getProcCmdLine()
+ {
+ String cmdline = "";
+ FileInputStream is = null;
+ try {
+ is = new FileInputStream("/proc/cmdline");
+ byte [] buffer = new byte[2048];
+ int count = is.read(buffer);
+ if (count > 0) {
+ cmdline = new String(buffer, 0, count);
+ }
+ } catch (IOException e) {
+ Log.d(TAG, "No /proc/cmdline exception=" + e);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ Log.d(TAG, "/proc/cmdline=" + cmdline);
+ return cmdline;
+ }
+
+ /** Kernel command line */
+ private static final String sKernelCmdLine = getProcCmdLine();
+
+ /** Pattern for selecting the product type from the kernel command line */
+ private static final Pattern sProductTypePattern =
+ Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
+
+ /** The ProductType used for LTE on CDMA devices */
+ private static final String sLteOnCdmaProductType =
+ SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
+
+ /**
+ * Return if the current radio is LTE on CDMA. This
+ * is a tri-state return value as for a period of time
+ * the mode may be unknown.
+ *
+ * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
+ * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
+ *
+ * @hide
+ */
+ public static int getLteOnCdmaModeStatic() {
+ int retVal;
+ int curVal;
+ String productType = "";
+
+ curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
+ PhoneConstants.LTE_ON_CDMA_UNKNOWN);
+ retVal = curVal;
+ if (retVal == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
+ Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
+ if (matcher.find()) {
+ productType = matcher.group(1);
+ if (sLteOnCdmaProductType.equals(productType)) {
+ retVal = PhoneConstants.LTE_ON_CDMA_TRUE;
+ } else {
+ retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
+ }
+ } else {
+ retVal = PhoneConstants.LTE_ON_CDMA_FALSE;
+ }
+ }
+
+ Log.d(TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
+ " product_type='" + productType +
+ "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
+ return retVal;
+ }
+
//
//
// Current Network
@@ -695,10 +817,10 @@
return getITelephony().getLteOnCdmaMode();
} catch (RemoteException ex) {
// Assume no ICC card if remote exception which shouldn't happen
- return Phone.LTE_ON_CDMA_UNKNOWN;
+ return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
} catch (NullPointerException ex) {
// This could happen before phone restarts due to crashing
- return Phone.LTE_ON_CDMA_UNKNOWN;
+ return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
}
}
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 84db830..6cfae6a 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -81,14 +81,26 @@
}
/**
- * @return cdma base station latitude, Integer.MAX_VALUE if unknown
+ * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+ * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
+ * It is represented in units of 0.25 seconds and ranges from -1296000
+ * to 1296000, both values inclusive (corresponding to a range of -90
+ * to +90 degrees). Integer.MAX_VALUE is considered invalid value.
+ *
+ * @return cdma base station latitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
*/
public int getBaseStationLatitude() {
return this.mBaseStationLatitude;
}
/**
- * @return cdma base station longitude, Integer.MAX_VALUE if unknown
+ * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+ * (http://www.3gpp2.org/public_html/specs/C.S0005-A_v6.0.pdf)
+ * It is represented in units of 0.25 seconds and ranges from -2592000
+ * to 2592000, both values inclusive (corresponding to a range of -180
+ * to +180 degrees). Integer.MAX_VALUE is considered invalid value.
+ *
+ * @return cdma base station longitude in units of 0.25 seconds, Integer.MAX_VALUE if unknown
*/
public int getBaseStationLongitude() {
return this.mBaseStationLongitude;
@@ -215,6 +227,22 @@
this.mNetworkId == -1);
}
+ /**
+ * Converts latitude or longitude from 0.25 seconds (as defined in the
+ * 3GPP2 C.S0005-A v6.0 standard) to decimal degrees
+ *
+ * @param quartSec latitude or longitude in 0.25 seconds units
+ * @return latitude or longitude in decimal degrees units
+ * @throws IllegalArgumentException if value is less than -2592000,
+ * greater than 2592000, or is not a number.
+ */
+ public static double convertQuartSecToDecDegrees(int quartSec) {
+ if(Double.isNaN(quartSec) || quartSec < -2592000 || quartSec > 2592000){
+ // Invalid value
+ throw new IllegalArgumentException("Invalid coordiante value:" + quartSec);
+ }
+ return ((double)quartSec) / (3600 * 4);
+ }
}
diff --git a/telephony/java/android/telephony/gsm/SmsManager.java b/telephony/java/android/telephony/gsm/SmsManager.java
deleted file mode 100644
index 3b75298..0000000
--- a/telephony/java/android/telephony/gsm/SmsManager.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.gsm;
-
-import android.app.PendingIntent;
-
-import java.util.ArrayList;
-
-
-/**
- * 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.
- */
-@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;
- }
-
- @Deprecated
- private SmsManager() {
- mSmsMgrProxy = android.telephony.SmsManager.getDefault();
- }
-
- /**
- * 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 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").
- *
- * @throws IllegalArgumentException if destinationAddress or text are empty
- * @deprecated Use android.telephony.SmsManager.
- */
- @Deprecated
- public final void sendTextMessage(
- String destinationAddress, String scAddress, String text,
- PendingIntent sentIntent, PendingIntent deliveryIntent) {
- mSmsMgrProxy.sendTextMessage(destinationAddress, scAddress, text,
- 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
- * @deprecated Use android.telephony.SmsManager.
- */
- @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
- * <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
- * @deprecated Use android.telephony.SmsManager.
- */
- @Deprecated
- public final void sendMultipartTextMessage(
- String destinationAddress, String scAddress, ArrayList<String> parts,
- ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
- mSmsMgrProxy.sendMultipartTextMessage(destinationAddress, scAddress, parts,
- sentIntents, deliveryIntents);
- }
-
- /**
- * 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
- * @deprecated Use android.telephony.SmsManager.
- */
- @Deprecated
- public final void sendDataMessage(
- String destinationAddress, String scAddress, short destinationPort,
- byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- mSmsMgrProxy.sendDataMessage(destinationAddress, scAddress, destinationPort,
- data, sentIntent, deliveryIntent);
- }
-
- /**
- * Copy a raw SMS PDU to the SIM.
- *
- * @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_SIM_READ, STATUS_ON_SIM_UNREAD,
- * STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT)
- * @return true for success
- * @deprecated Use android.telephony.SmsManager.
- * {@hide}
- */
- @Deprecated
- public final boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) {
- return mSmsMgrProxy.copyMessageToIcc(smsc, pdu, status);
- }
-
- /**
- * Delete the specified message from the SIM.
- *
- * @param messageIndex is the record index of the message on SIM
- * @return true for success
- * @deprecated Use android.telephony.SmsManager.
- * {@hide}
- */
- @Deprecated
- public final boolean deleteMessageFromSim(int messageIndex) {
- return mSmsMgrProxy.deleteMessageFromIcc(messageIndex);
- }
-
- /**
- * Update the specified message on the SIM.
- *
- * @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 pdu the raw PDU to store
- * @return true for success
- * @deprecated Use android.telephony.SmsManager.
- * {@hide}
- */
- @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}
- */
- @Deprecated
- public final ArrayList<android.telephony.SmsMessage> getAllMessagesFromSim() {
- return mSmsMgrProxy.getAllMessagesFromIcc();
- }
-
- /** 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).
- * @deprecated Use android.telephony.SmsManager. */
- @Deprecated static public final int STATUS_ON_SIM_READ = 1;
-
- /** 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).
- * @deprecated Use android.telephony.SmsManager. */
- @Deprecated static public final int STATUS_ON_SIM_SENT = 5;
-
- /** 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;
-
- /** 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;
-
-}
diff --git a/telephony/java/android/telephony/gsm/SmsMessage.java b/telephony/java/android/telephony/gsm/SmsMessage.java
deleted file mode 100644
index 8d86ec2..0000000
--- a/telephony/java/android/telephony/gsm/SmsMessage.java
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.gsm;
-
-import android.os.Parcel;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
-
-import java.util.Arrays;
-
-import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
-
-
-/**
- * A Short Message Service message.
- * @deprecated Replaced by android.telephony.SmsMessage that supports both GSM and CDMA.
- */
-@Deprecated
-public class SmsMessage {
- private static final boolean LOCAL_DEBUG = true;
- private static final String LOG_TAG = "SMS";
-
- /**
- * SMS Class enumeration.
- * See TS 23.038.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public enum MessageClass{
- UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
- }
-
- /** Unknown encoding scheme (see TS 23.038)
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated public static final int ENCODING_UNKNOWN = 0;
-
- /** 7-bit encoding scheme (see TS 23.038)
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated public static final int ENCODING_7BIT = 1;
-
- /** 8-bit encoding scheme (see TS 23.038)
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated public static final int ENCODING_8BIT = 2;
-
- /** 16-bit encoding scheme (see TS 23.038)
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated public static final int ENCODING_16BIT = 3;
-
- /** The maximum number of payload bytes per message
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated 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.
- *
- * @deprecated Use android.telephony.SmsMessage.
- * @hide pending API Council approval to extend the public API
- */
- @Deprecated public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
-
- /** The maximum number of payload septets per message
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
-
- /** Contains actual SmsMessage. Only public for debugging and for framework layer.
- * @deprecated Use android.telephony.SmsMessage.
- * {@hide}
- */
- @Deprecated public SmsMessageBase mWrappedSmsMessage;
-
- /** @deprecated Use android.telephony.SmsMessage. */
- @Deprecated
- public static class SubmitPdu {
- /** @deprecated Use android.telephony.SmsMessage. */
- @Deprecated public byte[] encodedScAddress; // Null if not applicable.
- /** @deprecated Use android.telephony.SmsMessage. */
- @Deprecated public byte[] encodedMessage;
-
- //Constructor
- /** @deprecated Use android.telephony.SmsMessage. */
- @Deprecated
- public SubmitPdu() {
- }
-
- /** @deprecated Use android.telephony.SmsMessage.
- * {@hide}
- */
- @Deprecated
- protected SubmitPdu(SubmitPduBase spb) {
- this.encodedMessage = spb.encodedMessage;
- this.encodedScAddress = spb.encodedScAddress;
- }
-
- /** @deprecated Use android.telephony.SmsMessage. */
- @Deprecated
- public String toString() {
- return "SubmitPdu: encodedScAddress = "
- + Arrays.toString(encodedScAddress)
- + ", encodedMessage = "
- + Arrays.toString(encodedMessage);
- }
- }
-
- // Constructor
- /** @deprecated Use android.telephony.SmsMessage. */
- @Deprecated
- public SmsMessage() {
- this(getSmsFacility());
- }
-
- private SmsMessage(SmsMessageBase smb) {
- mWrappedSmsMessage = smb;
- }
-
- /**
- * Create an SmsMessage from a raw PDU.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public static SmsMessage createFromPdu(byte[] pdu) {
- SmsMessageBase wrappedMessage;
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
- 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);
- }
-
- /**
- * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
- * length in bytes (not hex chars) less the SMSC header
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public static int getTPLayerLengthForPDU(String pdu) {
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public static int[] calculateLength(CharSequence messageBody, boolean use7bitOnly) {
- SmsMessageBase.TextEncodingDetails ted =
- com.android.internal.telephony.gsm.SmsMessage
- .calculateLength(messageBody, use7bitOnly);
- int ret[] = new int[4];
- ret[0] = ted.msgCount;
- ret[1] = ted.codeUnitCount;
- ret[2] = ted.codeUnitsRemaining;
- ret[3] = ted.codeUnitSize;
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- * @hide
- */
- @Deprecated
- public static SubmitPdu getSubmitPdu(String scAddress,
- String destinationAddress, String message,
- boolean statusReportRequested, byte[] header) {
- SubmitPduBase spb;
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
- if (PHONE_TYPE_CDMA == activePhone) {
- spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
- destinationAddress, message, statusReportRequested,
- SmsHeader.fromByteArray(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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public static SubmitPdu getSubmitPdu(String scAddress,
- String destinationAddress, String message, boolean statusReportRequested) {
- SubmitPduBase spb;
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
- if (PHONE_TYPE_CDMA == activePhone) {
- spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
- destinationAddress, message, statusReportRequested, null);
- } 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 & 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public static SubmitPdu getSubmitPdu(String scAddress,
- String destinationAddress, short destinationPort, byte[] data,
- boolean statusReportRequested) {
- SubmitPduBase spb;
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public String getServiceCenterAddress() {
- return mWrappedSmsMessage.getServiceCenterAddress();
- }
-
- /**
- * Returns the originating address (sender) of this SMS message in String
- * form or null if unavailable
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public String getMessageBody() {
- return mWrappedSmsMessage.getMessageBody();
- }
-
- /**
- * Returns the class of this message.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public MessageClass getMessageClass() {
- int index = mWrappedSmsMessage.getMessageClass().ordinal();
-
- return MessageClass.values()[index];
- }
-
- /**
- * Returns the message body, or email message body if this message was from
- * an email gateway. Returns null if message body unavailable.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public String getDisplayMessageBody() {
- return mWrappedSmsMessage.getDisplayMessageBody();
- }
-
- /**
- * Unofficial convention of a subject line enclosed in parens empty string
- * if not present
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public String getPseudoSubject() {
- return mWrappedSmsMessage.getPseudoSubject();
- }
-
- /**
- * Returns the service centre timestamp in currentTimeMillis() format
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public boolean isEmail() {
- return mWrappedSmsMessage.isEmail();
- }
-
- /**
- * @return if isEmail() is true, body of the email sent through the gateway.
- * null otherwise
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public String getEmailBody() {
- return mWrappedSmsMessage.getEmailBody();
- }
-
- /**
- * @return if isEmail() is true, email from address of email sent through
- * the gateway. null otherwise
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public String getEmailFrom() {
- return mWrappedSmsMessage.getEmailFrom();
- }
-
- /**
- * Get protocol identifier.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public int getProtocolIdentifier() {
- return mWrappedSmsMessage.getProtocolIdentifier();
- }
-
- /**
- * See TS 23.040 9.2.3.9 returns true if this is a "replace short message" SMS
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public boolean isCphsMwiMessage() {
- return mWrappedSmsMessage.isCphsMwiMessage();
- }
-
- /**
- * returns true if this message is a CPHS voicemail / message waiting
- * indicator (MWI) clear message
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public boolean isMWIClearMessage() {
- return mWrappedSmsMessage.isMWIClearMessage();
- }
-
- /**
- * returns true if this message is a CPHS voicemail / message waiting
- * indicator (MWI) set message
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public boolean isMwiDontStore() {
- return mWrappedSmsMessage.isMwiDontStore();
- }
-
- /**
- * returns the user data section minus the user data header if one was present.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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 android.telephony.SmsMessage and 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
- * @deprecated Use android.telephony.SmsMessage.
- * @hide
- */
- @Deprecated
- 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 android.telephony.SmsMessage and 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.
- * @deprecated Use android.telephony.SmsMessage.
- * @hide
- */
- @Deprecated
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public int getStatus() {
- return mWrappedSmsMessage.getStatus();
- }
-
- /**
- * Return true iff the message is a SMS-STATUS-REPORT message.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- public boolean isStatusReportMessage() {
- return mWrappedSmsMessage.isStatusReportMessage();
- }
-
- /**
- * Returns true iff the <code>TP-Reply-Path</code> bit is set in
- * this message.
- * @deprecated Use android.telephony.SmsMessage.
- */
- @Deprecated
- 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.
- * @deprecated Use android.telephony.SmsMessage.
- */
- private static final SmsMessageBase getSmsFacility(){
- int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
- if (PHONE_TYPE_CDMA == activePhone) {
- return new com.android.internal.telephony.cdma.SmsMessage();
- } else {
- return new com.android.internal.telephony.gsm.SmsMessage();
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/ATParseEx.java b/telephony/java/com/android/internal/telephony/ATParseEx.java
deleted file mode 100644
index c93b875..0000000
--- a/telephony/java/com/android/internal/telephony/ATParseEx.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public class ATParseEx extends RuntimeException
-{
- public
- ATParseEx()
- {
- super();
- }
-
- public
- ATParseEx(String s)
- {
- super(s);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/ATResponseParser.java b/telephony/java/com/android/internal/telephony/ATResponseParser.java
deleted file mode 100644
index fdb0526..0000000
--- a/telephony/java/com/android/internal/telephony/ATResponseParser.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public class ATResponseParser
-{
- /*************************** Instance Variables **************************/
-
- private String line;
- private int next = 0;
- private int tokStart, tokEnd;
-
- /***************************** Class Methods *****************************/
-
- public
- ATResponseParser (String line)
- {
- this.line = line;
- }
-
- public boolean
- nextBoolean()
- {
- // "\s*(\d)(,|$)"
- // \d is '0' or '1'
-
- nextTok();
-
- if (tokEnd - tokStart > 1) {
- throw new ATParseEx();
- }
- char c = line.charAt(tokStart);
-
- if (c == '0') return false;
- if (c == '1') return true;
- throw new ATParseEx();
- }
-
-
- /** positive int only */
- public int
- nextInt()
- {
- // "\s*(\d+)(,|$)"
- int ret = 0;
-
- nextTok();
-
- for (int i = tokStart ; i < tokEnd ; i++) {
- char c = line.charAt(i);
-
- // Yes, ASCII decimal digits only
- if (c < '0' || c > '9') {
- throw new ATParseEx();
- }
-
- ret *= 10;
- ret += c - '0';
- }
-
- return ret;
- }
-
- public String
- nextString()
- {
- nextTok();
-
- return line.substring(tokStart, tokEnd);
- }
-
- public boolean
- hasMore()
- {
- return next < line.length();
- }
-
- private void
- nextTok()
- {
- int len = line.length();
-
- if (next == 0) {
- skipPrefix();
- }
-
- if (next >= len) {
- throw new ATParseEx();
- }
-
- try {
- // \s*("([^"]*)"|(.*)\s*)(,|$)
-
- char c = line.charAt(next++);
- boolean hasQuote = false;
-
- c = skipWhiteSpace(c);
-
- if (c == '"') {
- if (next >= len) {
- throw new ATParseEx();
- }
- c = line.charAt(next++);
- tokStart = next - 1;
- while (c != '"' && next < len) {
- c = line.charAt(next++);
- }
- if (c != '"') {
- throw new ATParseEx();
- }
- tokEnd = next - 1;
- if (next < len && line.charAt(next++) != ',') {
- throw new ATParseEx();
- }
- } else {
- tokStart = next - 1;
- tokEnd = tokStart;
- while (c != ',') {
- if (!Character.isWhitespace(c)) {
- tokEnd = next;
- }
- if (next == len) {
- break;
- }
- c = line.charAt(next++);
- }
- }
- } catch (StringIndexOutOfBoundsException ex) {
- throw new ATParseEx();
- }
- }
-
-
- /** Throws ATParseEx if whitespace extends to the end of string */
- private char
- skipWhiteSpace (char c)
- {
- int len;
- len = line.length();
- while (next < len && Character.isWhitespace(c)) {
- c = line.charAt(next++);
- }
-
- if (Character.isWhitespace(c)) {
- throw new ATParseEx();
- }
- return c;
- }
-
-
- private void
- skipPrefix()
- {
- // consume "^[^:]:"
-
- next = 0;
- int s = line.length();
- while (next < s){
- char c = line.charAt(next++);
-
- if (c == ':') {
- return;
- }
- }
-
- throw new ATParseEx("missing prefix");
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.aidl b/telephony/java/com/android/internal/telephony/AdnRecord.aidl
deleted file mode 100644
index b4a1a29..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecord.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-** 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
-**
-** 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;
-
-parcelable AdnRecord;
-
diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.java b/telephony/java/com/android/internal/telephony/AdnRecord.java
deleted file mode 100644
index 1bf2d3c..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecord.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * 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.text.TextUtils;
-import android.util.Log;
-
-import java.util.Arrays;
-
-
-/**
- *
- * 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 = null;
- String number = null;
- String[] emails;
- 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_DIALING_NUMBER_START = 2;
- static final int ADN_DIALING_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;
- String[] emails;
-
- efid = source.readInt();
- recordNumber = source.readInt();
- alphaTag = source.readString();
- number = source.readString();
- emails = source.readStringArray();
-
- return new AdnRecord(efid, recordNumber, alphaTag, number, emails);
- }
-
- 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 (String alphaTag, String number, String[] emails) {
- this(0, 0, alphaTag, number, emails);
- }
-
- public AdnRecord (int efid, int recordNumber, String alphaTag, String number, String[] emails) {
- this.efid = efid;
- this.recordNumber = recordNumber;
- this.alphaTag = alphaTag;
- this.number = number;
- this.emails = emails;
- }
-
- public AdnRecord(int efid, int recordNumber, String alphaTag, String number) {
- this.efid = efid;
- this.recordNumber = recordNumber;
- this.alphaTag = alphaTag;
- this.number = number;
- this.emails = null;
- }
-
- //***** Instance Methods
-
- public String getAlphaTag() {
- return alphaTag;
- }
-
- public String getNumber() {
- return number;
- }
-
- public String[] getEmails() {
- return emails;
- }
-
- public void setEmails(String[] emails) {
- this.emails = emails;
- }
-
- public String toString() {
- return "ADN Record '" + alphaTag + "' '" + number + " " + emails + "'";
- }
-
- public boolean isEmpty() {
- return TextUtils.isEmpty(alphaTag) && TextUtils.isEmpty(number) && emails == null;
- }
-
- public boolean hasExtendedRecord() {
- return extRecord != 0 && extRecord != 0xff;
- }
-
- /** Helper function for {@link #isEqual}. */
- private static boolean stringCompareNullEqualsEmpty(String s1, String s2) {
- if (s1 == s2) {
- return true;
- }
- if (s1 == null) {
- s1 = "";
- }
- if (s2 == null) {
- s2 = "";
- }
- return (s1.equals(s2));
- }
-
- public boolean isEqual(AdnRecord adn) {
- return ( stringCompareNullEqualsEmpty(alphaTag, adn.alphaTag) &&
- stringCompareNullEqualsEmpty(number, adn.number) &&
- Arrays.equals(emails, adn.emails));
- }
- //***** 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);
- dest.writeStringArray(emails);
- }
-
- /**
- * 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 null for wrong format of dialing number or tag
- */
- public byte[] buildAdnString(int recordSize) {
- byte[] bcdNumber;
- byte[] byteTag;
- byte[] adnString;
- int footerOffset = recordSize - FOOTER_SIZE_BYTES;
-
- // create an empty record
- adnString = new byte[recordSize];
- for (int i = 0; i < recordSize; i++) {
- adnString[i] = (byte) 0xFF;
- }
-
- if (TextUtils.isEmpty(number)) {
- Log.w(LOG_TAG, "[buildAdnString] Empty dialing number");
- return adnString; // return the empty record (for delete)
- } else if (number.length()
- > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) {
- Log.w(LOG_TAG,
- "[buildAdnString] Max length of dialing number is 20");
- return null;
- } else if (alphaTag != null && alphaTag.length() > footerOffset) {
- Log.w(LOG_TAG,
- "[buildAdnString] Max length of tag is " + footerOffset);
- return null;
- } else {
- 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; // Capability Id
- adnString[footerOffset + ADN_EXTENSION_ID]
- = (byte) 0xFF; // Extension Record Id
-
- if (!TextUtils.isEmpty(alphaTag)) {
- 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];
-
- emails = null;
-
- } catch (RuntimeException ex) {
- Log.w(LOG_TAG, "Error parsing AdnRecord", ex);
- number = "";
- alphaTag = "";
- emails = null;
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
deleted file mode 100644
index db5f4da..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecordCache.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * 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 android.util.SparseArray;
-
-import com.android.internal.telephony.gsm.UsimPhoneBookManager;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * {@hide}
- */
-public final class AdnRecordCache extends Handler implements IccConstants {
- //***** Instance Variables
-
- private IccFileHandler mFh;
- private UsimPhoneBookManager mUsimPhoneBookManager;
-
- // Indexed by EF ID
- SparseArray<ArrayList<AdnRecord>> adnLikeFiles
- = new SparseArray<ArrayList<AdnRecord>>();
-
- // People waiting for ADN-like files to be loaded
- SparseArray<ArrayList<Message>> adnLikeWaiters
- = new SparseArray<ArrayList<Message>>();
-
- // People waiting for adn record to be updated
- SparseArray<Message> userWriteResponse = new SparseArray<Message>();
-
- //***** Event Constants
-
- static final int EVENT_LOAD_ALL_ADN_LIKE_DONE = 1;
- static final int EVENT_UPDATE_ADN_DONE = 2;
-
- //***** Constructor
-
-
-
- public AdnRecordCache(IccFileHandler fh) {
- mFh = fh;
- mUsimPhoneBookManager = new UsimPhoneBookManager(mFh, this);
- }
-
- //***** Called from SIMRecords
-
- /**
- * Called from SIMRecords.onRadioNotAvailable and SIMRecords.handleSimRefresh.
- */
- public void reset() {
- adnLikeFiles.clear();
- mUsimPhoneBookManager.reset();
-
- clearWaiters();
- clearUserWriters();
-
- }
-
- private void clearWaiters() {
- int size = adnLikeWaiters.size();
- for (int i = 0; i < size; i++) {
- ArrayList<Message> waiters = adnLikeWaiters.valueAt(i);
- AsyncResult ar = new AsyncResult(null, null, new RuntimeException("AdnCache reset"));
- notifyWaiters(waiters, ar);
- }
- adnLikeWaiters.clear();
- }
-
- private void clearUserWriters() {
- int size = userWriteResponse.size();
- for (int i = 0; i < size; i++) {
- sendErrorResponse(userWriteResponse.valueAt(i), "AdnCace reset");
- }
- userWriteResponse.clear();
- }
-
- /**
- * @return List of AdnRecords for efid if we've already loaded them this
- * radio session, or null if we haven't
- */
- public ArrayList<AdnRecord>
- getRecordsIfLoaded(int efid) {
- return adnLikeFiles.get(efid);
- }
-
- /**
- * Returns extension ef associated with ADN-like EF or -1 if
- * we don't know.
- *
- * See 3GPP TS 51.011 for this mapping
- */
- int 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_PBR: return 0; // The EF PBR doesn't have an extension record
- default: return -1;
- }
- }
-
- private void sendErrorResponse(Message response, String errString) {
- if (response != null) {
- Exception e = new RuntimeException(errString);
- AsyncResult.forMessage(response).exception = e;
- response.sendToTarget();
- }
- }
-
- /**
- * Update an ADN-like record in EF by record index
- *
- * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN
- * @param adn is the new adn to be stored
- * @param recordIndex is the 1-based adn record index
- * @param pin2 is required to update EF_FDN, otherwise must be null
- * @param response message to be posted when done
- * response.exception hold the exception in error
- */
- public void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2,
- Message response) {
-
- int extensionEF = extensionEfForEf(efid);
- if (extensionEF < 0) {
- sendErrorResponse(response, "EF is not known ADN-like EF:" + efid);
- return;
- }
-
- Message pendingResponse = userWriteResponse.get(efid);
- if (pendingResponse != null) {
- sendErrorResponse(response, "Have pending update for EF:" + efid);
- return;
- }
-
- userWriteResponse.put(efid, response);
-
- new AdnRecordLoader(mFh).updateEF(adn, efid, extensionEF,
- recordIndex, pin2,
- obtainMessage(EVENT_UPDATE_ADN_DONE, efid, recordIndex, adn));
- }
-
- /**
- * Replace oldAdn with newAdn in ADN-like record in EF
- *
- * The ADN-like records must be read through requestLoadAllAdnLike() before
- *
- * @param efid must be one of EF_ADN, EF_FDN, and EF_SDN
- * @param oldAdn is the adn to be replaced
- * If oldAdn.isEmpty() is ture, it insert the newAdn
- * @param newAdn is the adn to be stored
- * If newAdn.isEmpty() is true, it delete the oldAdn
- * @param pin2 is required to update EF_FDN, otherwise must be null
- * @param response message to be posted when done
- * response.exception hold the exception in error
- */
- public void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn,
- String pin2, Message response) {
-
- int extensionEF;
- extensionEF = extensionEfForEf(efid);
-
- if (extensionEF < 0) {
- sendErrorResponse(response, "EF is not known ADN-like EF:" + efid);
- return;
- }
-
- ArrayList<AdnRecord> oldAdnList;
-
- if (efid == EF_PBR) {
- oldAdnList = mUsimPhoneBookManager.loadEfFilesFromUsim();
- } else {
- oldAdnList = getRecordsIfLoaded(efid);
- }
-
- if (oldAdnList == null) {
- sendErrorResponse(response, "Adn list not exist for EF:" + efid);
- return;
- }
-
- int index = -1;
- int count = 1;
- for (Iterator<AdnRecord> it = oldAdnList.iterator(); it.hasNext(); ) {
- if (oldAdn.isEqual(it.next())) {
- index = count;
- break;
- }
- count++;
- }
-
- if (index == -1) {
- sendErrorResponse(response, "Adn record don't exist for " + oldAdn);
- return;
- }
-
- if (efid == EF_PBR) {
- AdnRecord foundAdn = oldAdnList.get(index-1);
- efid = foundAdn.efid;
- extensionEF = foundAdn.extRecord;
- index = foundAdn.recordNumber;
-
- newAdn.efid = efid;
- newAdn.extRecord = extensionEF;
- newAdn.recordNumber = index;
- }
-
- Message pendingResponse = userWriteResponse.get(efid);
-
- if (pendingResponse != null) {
- sendErrorResponse(response, "Have pending update for EF:" + efid);
- return;
- }
-
- userWriteResponse.put(efid, response);
-
- new AdnRecordLoader(mFh).updateEF(newAdn, efid, extensionEF,
- index, pin2,
- obtainMessage(EVENT_UPDATE_ADN_DONE, efid, index, newAdn));
- }
-
-
- /**
- * Responds with exception (in response) if efid is not a known ADN-like
- * record
- */
- public void
- requestLoadAllAdnLike (int efid, int extensionEf, Message response) {
- ArrayList<Message> waiters;
- ArrayList<AdnRecord> result;
-
- if (efid == EF_PBR) {
- result = mUsimPhoneBookManager.loadEfFilesFromUsim();
- } else {
- result = getRecordsIfLoaded(efid);
- }
-
- // Have we already loaded this efid?
- if (result != null) {
- if (response != null) {
- AsyncResult.forMessage(response).result = result;
- response.sendToTarget();
- }
-
- return;
- }
-
- // Have we already *started* loading this efid?
-
- waiters = adnLikeWaiters.get(efid);
-
- if (waiters != null) {
- // There's a pending request for this EF already
- // just add ourselves to it
-
- waiters.add(response);
- return;
- }
-
- // Start loading efid
-
- waiters = new ArrayList<Message>();
- waiters.add(response);
-
- adnLikeWaiters.put(efid, waiters);
-
-
- if (extensionEf < 0) {
- // respond with error if not known ADN-like record
-
- if (response != null) {
- AsyncResult.forMessage(response).exception
- = new RuntimeException("EF is not known ADN-like EF:" + efid);
- response.sendToTarget();
- }
-
- return;
- }
-
- new AdnRecordLoader(mFh).loadAllFromEF(efid, extensionEf,
- obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE, efid, 0));
- }
-
- //***** Private methods
-
- private void
- notifyWaiters(ArrayList<Message> waiters, AsyncResult ar) {
-
- if (waiters == null) {
- return;
- }
-
- for (int i = 0, s = waiters.size() ; i < s ; i++) {
- Message waiter = waiters.get(i);
-
- AsyncResult.forMessage(waiter, ar.result, ar.exception);
- waiter.sendToTarget();
- }
- }
-
- //***** Overridden from Handler
-
- public void
- handleMessage(Message msg) {
- AsyncResult ar;
- int efid;
-
- switch(msg.what) {
- case EVENT_LOAD_ALL_ADN_LIKE_DONE:
- /* arg1 is efid, obj.result is ArrayList<AdnRecord>*/
- ar = (AsyncResult) msg.obj;
- efid = msg.arg1;
- ArrayList<Message> waiters;
-
- waiters = adnLikeWaiters.get(efid);
- adnLikeWaiters.delete(efid);
-
- if (ar.exception == null) {
- adnLikeFiles.put(efid, (ArrayList<AdnRecord>) ar.result);
- }
- notifyWaiters(waiters, ar);
- break;
- case EVENT_UPDATE_ADN_DONE:
- ar = (AsyncResult)msg.obj;
- efid = msg.arg1;
- int index = msg.arg2;
- AdnRecord adn = (AdnRecord) (ar.userObj);
-
- if (ar.exception == null) {
- adnLikeFiles.get(efid).set(index - 1, adn);
- mUsimPhoneBookManager.invalidateCache();
- }
-
- Message response = userWriteResponse.get(efid);
- userWriteResponse.delete(efid);
-
- AsyncResult.forMessage(response, null, ar.exception);
- response.sendToTarget();
- break;
- }
-
- }
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java b/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
deleted file mode 100644
index 084fae6..0000000
--- a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * 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.Looper;
-import android.os.Message;
-import android.util.Log;
-
-
-public class AdnRecordLoader extends Handler {
- final static String LOG_TAG = "RIL_AdnRecordLoader";
-
- //***** Instance Variables
-
- private IccFileHandler mFh;
- 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(IccFileHandler fh) {
- // The telephony unit-test cases may create AdnRecords
- // in secondary threads
- super(Looper.getMainLooper());
- mFh = fh;
- }
-
- /**
- * 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;
-
- mFh.loadEFLinearFixed(
- ef, recordNumber,
- obtainMessage(EVENT_ADN_LOAD_DONE));
-
- }
-
-
- /**
- * Resulting ArrayList<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;
-
- mFh.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 phone number
- * @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;
-
- mFh.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("wrong ADN format",
- ar.exception);
- }
-
- mFh.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;
-
- mFh.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 extension 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++;
-
- mFh.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;
- }
- }
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java
deleted file mode 100644
index 9746398..0000000
--- a/telephony/java/com/android/internal/telephony/ApnContext.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * 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.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Maintain the Apn context
- */
-public class ApnContext {
-
- public final String LOG_TAG;
-
- protected static final boolean DBG = true;
-
- private final String mApnType;
-
- private DataConnectionTracker.State mState;
-
- private ArrayList<ApnSetting> mWaitingApns = null;
-
- /** A zero indicates that all waiting APNs had a permanent error */
- private AtomicInteger mWaitingApnsPermanentFailureCountDown;
-
- private ApnSetting mApnSetting;
-
- DataConnection mDataConnection;
-
- DataConnectionAc mDataConnectionAc;
-
- String mReason;
-
- int mRetryCount;
-
- /**
- * user/app requested connection on this APN
- */
- AtomicBoolean mDataEnabled;
-
- /**
- * carrier requirements met
- */
- AtomicBoolean mDependencyMet;
-
- public ApnContext(String apnType, String logTag) {
- mApnType = apnType;
- mState = DataConnectionTracker.State.IDLE;
- setReason(Phone.REASON_DATA_ENABLED);
- setRetryCount(0);
- mDataEnabled = new AtomicBoolean(false);
- mDependencyMet = new AtomicBoolean(true);
- mWaitingApnsPermanentFailureCountDown = new AtomicInteger(0);
- LOG_TAG = logTag;
- }
-
- public String getApnType() {
- return mApnType;
- }
-
- public synchronized DataConnection getDataConnection() {
- return mDataConnection;
- }
-
- public synchronized void setDataConnection(DataConnection dc) {
- if (DBG) {
- log("setDataConnection: old dc=" + mDataConnection + " new dc=" + dc + " this=" + this);
- }
- mDataConnection = dc;
- }
-
-
- public synchronized DataConnectionAc getDataConnectionAc() {
- return mDataConnectionAc;
- }
-
- public synchronized void setDataConnectionAc(DataConnectionAc dcac) {
- if (DBG) {
- log("setDataConnectionAc: old dcac=" + mDataConnectionAc + " new dcac=" + dcac);
- }
- if (dcac != null) {
- dcac.addApnContextSync(this);
- } else {
- if (mDataConnectionAc != null) {
- mDataConnectionAc.removeApnContextSync(this);
- }
- }
- mDataConnectionAc = dcac;
- }
-
- public synchronized ApnSetting getApnSetting() {
- return mApnSetting;
- }
-
- public synchronized void setApnSetting(ApnSetting apnSetting) {
- mApnSetting = apnSetting;
- }
-
- public synchronized void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
- mWaitingApns = waitingApns;
- mWaitingApnsPermanentFailureCountDown.set(mWaitingApns.size());
- }
-
- public int getWaitingApnsPermFailCount() {
- return mWaitingApnsPermanentFailureCountDown.get();
- }
-
- public void decWaitingApnsPermFailCount() {
- mWaitingApnsPermanentFailureCountDown.decrementAndGet();
- }
-
- public synchronized ApnSetting getNextWaitingApn() {
- ArrayList<ApnSetting> list = mWaitingApns;
- ApnSetting apn = null;
-
- if (list != null) {
- if (!list.isEmpty()) {
- apn = list.get(0);
- }
- }
- return apn;
- }
-
- public synchronized void removeWaitingApn(ApnSetting apn) {
- if (mWaitingApns != null) {
- mWaitingApns.remove(apn);
- }
- }
-
- public synchronized ArrayList<ApnSetting> getWaitingApns() {
- return mWaitingApns;
- }
-
- public synchronized void setState(DataConnectionTracker.State s) {
- if (DBG) {
- log("setState: " + s + ", previous state:" + mState);
- }
-
- mState = s;
-
- if (mState == DataConnectionTracker.State.FAILED) {
- if (mWaitingApns != null) {
- mWaitingApns.clear(); // when teardown the connection and set to IDLE
- }
- }
- }
-
- public synchronized DataConnectionTracker.State getState() {
- return mState;
- }
-
- public boolean isDisconnected() {
- DataConnectionTracker.State currentState = getState();
- return ((currentState == DataConnectionTracker.State.IDLE) ||
- currentState == DataConnectionTracker.State.FAILED);
- }
-
- public synchronized void setReason(String reason) {
- if (DBG) {
- log("set reason as " + reason + ",current state " + mState);
- }
- mReason = reason;
- }
-
- public synchronized String getReason() {
- return mReason;
- }
-
- public synchronized void setRetryCount(int retryCount) {
- if (DBG) {
- log("setRetryCount: " + retryCount);
- }
- mRetryCount = retryCount;
- DataConnection dc = mDataConnection;
- if (dc != null) {
- dc.setRetryCount(retryCount);
- }
- }
-
- public synchronized int getRetryCount() {
- return mRetryCount;
- }
-
- public boolean isReady() {
- return mDataEnabled.get() && mDependencyMet.get();
- }
-
- public void setEnabled(boolean enabled) {
- if (DBG) {
- log("set enabled as " + enabled + ", current state is " + mDataEnabled.get());
- }
- mDataEnabled.set(enabled);
- }
-
- public boolean isEnabled() {
- return mDataEnabled.get();
- }
-
- public void setDependencyMet(boolean met) {
- if (DBG) {
- log("set mDependencyMet as " + met + " current state is " + mDependencyMet.get());
- }
- mDependencyMet.set(met);
- }
-
- public boolean getDependencyMet() {
- return mDependencyMet.get();
- }
-
- @Override
- public String toString() {
- // We don't print mDataConnection because its recursive.
- return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns=" + mWaitingApns +
- " mWaitingApnsPermanentFailureCountDown=" + mWaitingApnsPermanentFailureCountDown +
- " mApnSetting=" + mApnSetting + " mDataConnectionAc=" + mDataConnectionAc +
- " mReason=" + mReason + " mRetryCount=" + mRetryCount +
- " mDataEnabled=" + mDataEnabled + " mDependencyMet=" + mDependencyMet + "}";
- }
-
- protected void log(String s) {
- Log.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("ApnContext: " + this.toString());
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/ApnSetting.java b/telephony/java/com/android/internal/telephony/ApnSetting.java
deleted file mode 100755
index ad69fdb..0000000
--- a/telephony/java/com/android/internal/telephony/ApnSetting.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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;
-
-/**
- * This class represents a apn setting for create PDP link
- */
-public class ApnSetting {
-
- static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*";
-
- public final String carrier;
- public final String apn;
- public final String proxy;
- public final String port;
- public final String mmsc;
- public final String mmsProxy;
- public final String mmsPort;
- public final String user;
- public final String password;
- public final int authType;
- public final String[] types;
- public final int id;
- public final String numeric;
- public final String protocol;
- public final String roamingProtocol;
- /**
- * Current status of APN
- * true : enabled APN, false : disabled APN.
- */
- public final boolean carrierEnabled;
- /**
- * Radio Access Technology info
- * To check what values can hold, refer to ServiceState.java.
- * This should be spread to other technologies,
- * but currently only used for LTE(14) and EHRPD(13).
- */
- public final int bearer;
-
- public ApnSetting(int id, String numeric, String carrier, String apn,
- String proxy, String port,
- String mmsc, String mmsProxy, String mmsPort,
- String user, String password, int authType, String[] types,
- String protocol, String roamingProtocol, boolean carrierEnabled, int bearer) {
- this.id = id;
- this.numeric = numeric;
- this.carrier = carrier;
- this.apn = apn;
- this.proxy = proxy;
- this.port = port;
- this.mmsc = mmsc;
- this.mmsProxy = mmsProxy;
- this.mmsPort = mmsPort;
- this.user = user;
- this.password = password;
- this.authType = authType;
- this.types = types;
- this.protocol = protocol;
- this.roamingProtocol = roamingProtocol;
- this.carrierEnabled = carrierEnabled;
- this.bearer = bearer;
- }
-
- /**
- * Creates an ApnSetting object from a string.
- *
- * @param data the string to read.
- *
- * The string must be in one of two formats (newlines added for clarity,
- * spaces are optional):
- *
- * v1 format:
- * <carrier>, <apn>, <proxy>, <port>, <mmsc>, <mmsproxy>,
- * <mmsport>, <user>, <password>, <authtype>, <mcc>,<mnc>,
- * <type>[, <type>...]
- *
- * v2 format:
- * [ApnSettingV2] <carrier>, <apn>, <proxy>, <port>, <mmsc>, <mmsproxy>,
- * <mmsport>, <user>, <password>, <authtype>, <mcc>, <mnc>,
- * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearer>
- *
- * Note that the strings generated by toString() do not contain the username
- * and password and thus cannot be read by this method.
- *
- * @see ApnSettingTest
- */
- public static ApnSetting fromString(String data) {
- if (data == null) return null;
-
- int version;
- // matches() operates on the whole string, so append .* to the regex.
- if (data.matches(V2_FORMAT_REGEX + ".*")) {
- version = 2;
- data = data.replaceFirst(V2_FORMAT_REGEX, "");
- } else {
- version = 1;
- }
-
- String[] a = data.split("\\s*,\\s*");
- if (a.length < 14) {
- return null;
- }
-
- int authType;
- try {
- authType = Integer.parseInt(a[12]);
- } catch (Exception e) {
- authType = 0;
- }
-
- String[] typeArray;
- String protocol, roamingProtocol;
- boolean carrierEnabled;
- int bearer;
- if (version == 1) {
- typeArray = new String[a.length - 13];
- System.arraycopy(a, 13, typeArray, 0, a.length - 13);
- protocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
- roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
- carrierEnabled = true;
- bearer = 0;
- } else {
- if (a.length < 18) {
- return null;
- }
- typeArray = a[13].split("\\s*\\|\\s*");
- protocol = a[14];
- roamingProtocol = a[15];
- try {
- carrierEnabled = Boolean.parseBoolean(a[16]);
- } catch (Exception e) {
- carrierEnabled = true;
- }
- bearer = Integer.parseInt(a[17]);
- }
-
- return new ApnSetting(-1,a[10]+a[11],a[0],a[1],a[2],a[3],a[7],a[8],
- a[9],a[4],a[5],authType,typeArray,protocol,roamingProtocol,carrierEnabled,bearer);
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("[ApnSettingV2] ")
- .append(carrier)
- .append(", ").append(id)
- .append(", ").append(numeric)
- .append(", ").append(apn)
- .append(", ").append(proxy)
- .append(", ").append(mmsc)
- .append(", ").append(mmsProxy)
- .append(", ").append(mmsPort)
- .append(", ").append(port)
- .append(", ").append(authType).append(", ");
- for (int i = 0; i < types.length; i++) {
- sb.append(types[i]);
- if (i < types.length - 1) {
- sb.append(" | ");
- }
- }
- sb.append(", ").append(protocol);
- sb.append(", ").append(roamingProtocol);
- sb.append(", ").append(carrierEnabled);
- sb.append(", ").append(bearer);
- return sb.toString();
- }
-
- public boolean canHandleType(String type) {
- for (String t : types) {
- // DEFAULT handles all, and HIPRI is handled by DEFAULT
- if (t.equalsIgnoreCase(type) ||
- t.equalsIgnoreCase(Phone.APN_TYPE_ALL) ||
- (t.equalsIgnoreCase(Phone.APN_TYPE_DEFAULT) &&
- type.equalsIgnoreCase(Phone.APN_TYPE_HIPRI))) {
- return true;
- }
- }
- return false;
- }
-
- // TODO - if we have this function we should also have hashCode.
- // Also should handle changes in type order and perhaps case-insensitivity
- public boolean equals(Object o) {
- if (o instanceof ApnSetting == false) return false;
- return (this.toString().equals(o.toString()));
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
deleted file mode 100644
index 35cdf9b..0000000
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * 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.os.SystemProperties;
-import android.util.Log;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * {@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 mCallStateRegistrants = new RegistrantList();
- protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
- protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
- protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
- protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
- protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
- protected RegistrantList mVoicePrivacyOffRegistrants = new RegistrantList();
- protected Registrant mUnsolOemHookRawRegistrant;
- protected RegistrantList mOtaProvisionRegistrants = new RegistrantList();
- protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
- protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
- protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
- protected RegistrantList mNumberInfoRegistrants = new RegistrantList();
- protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList();
- protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
- protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
- protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
- protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
- protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
- protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
- protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
- protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
- protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
- protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
-
- protected Registrant mGsmSmsRegistrant;
- protected Registrant mCdmaSmsRegistrant;
- protected Registrant mNITZTimeRegistrant;
- protected Registrant mSignalStrengthRegistrant;
- protected Registrant mUSSDRegistrant;
- protected Registrant mSmsOnSimRegistrant;
- protected Registrant mSmsStatusRegistrant;
- protected Registrant mSsnRegistrant;
- protected Registrant mCatSessionEndRegistrant;
- protected Registrant mCatProCmdRegistrant;
- protected Registrant mCatEventRegistrant;
- protected Registrant mCatCallSetUpRegistrant;
- protected Registrant mIccSmsFullRegistrant;
- protected Registrant mEmergencyCallbackModeRegistrant;
- protected Registrant mRingRegistrant;
- protected Registrant mRestrictedStateRegistrant;
- protected Registrant mGsmBroadcastSmsRegistrant;
-
- // Preferred network type received from PhoneFactory.
- // This is used when establishing a connection to the
- // vendor ril so it starts up in the correct mode.
- protected int mPreferredNetworkType;
- // CDMA subscription received from PhoneFactory
- protected int mCdmaSubscription;
- // Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
- protected int mPhoneType;
- // RIL Version
- protected int mRilVersion = -1;
-
- 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);
- }
- }
-
- 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 registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- mVoiceNetworkStateRegistrants.add(r);
- }
-
- public void unregisterForVoiceNetworkStateChanged(Handler h) {
- mVoiceNetworkStateRegistrants.remove(h);
- }
-
- public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- mDataNetworkStateRegistrants.add(r);
- }
-
- public void unregisterForDataNetworkStateChanged(Handler h) {
- mDataNetworkStateRegistrants.remove(h);
- }
-
- public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mVoiceRadioTechChangedRegistrants.add(r);
- }
-
- public void unregisterForVoiceRadioTechChanged(Handler h) {
- mVoiceRadioTechChangedRegistrants.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 setOnNewGsmSms(Handler h, int what, Object obj) {
- mGsmSmsRegistrant = new Registrant (h, what, obj);
- }
-
- public void unSetOnNewGsmSms(Handler h) {
- mGsmSmsRegistrant.clear();
- }
-
- public void setOnNewCdmaSms(Handler h, int what, Object obj) {
- mCdmaSmsRegistrant = new Registrant (h, what, obj);
- }
-
- public void unSetOnNewCdmaSms(Handler h) {
- mCdmaSmsRegistrant.clear();
- }
-
- public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
- mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj);
- }
-
- public void unSetOnNewGsmBroadcastSms(Handler h) {
- mGsmBroadcastSmsRegistrant.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 setOnCatSessionEnd(Handler h, int what, Object obj) {
- mCatSessionEndRegistrant = new Registrant (h, what, obj);
- }
-
- public void unSetOnCatSessionEnd(Handler h) {
- mCatSessionEndRegistrant.clear();
- }
-
- public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
- mCatProCmdRegistrant = new Registrant (h, what, obj);
- }
-
- public void unSetOnCatProactiveCmd(Handler h) {
- mCatProCmdRegistrant.clear();
- }
-
- public void setOnCatEvent(Handler h, int what, Object obj) {
- mCatEventRegistrant = new Registrant (h, what, obj);
- }
-
- public void unSetOnCatEvent(Handler h) {
- mCatEventRegistrant.clear();
- }
-
- public void setOnCatCallSetUp(Handler h, int what, Object obj) {
- mCatCallSetUpRegistrant = new Registrant (h, what, obj);
- }
-
- public void unSetOnCatCallSetUp(Handler h) {
- mCatCallSetUpRegistrant.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 registerForIccRefresh(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mIccRefreshRegistrants.add(r);
- }
- public void setOnIccRefresh(Handler h, int what, Object obj) {
- registerForIccRefresh(h, what, obj);
- }
-
- public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
- mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
- }
-
- public void unregisterForIccRefresh(Handler h) {
- mIccRefreshRegistrants.remove(h);
- }
- public void unsetOnIccRefresh(Handler h) {
- unregisterForIccRefresh(h);
- }
-
- 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();
- }
-
- public void registerForDisplayInfo(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mDisplayInfoRegistrants.add(r);
- }
-
- public void unregisterForDisplayInfo(Handler h) {
- mDisplayInfoRegistrants.remove(h);
- }
-
- public void registerForCallWaitingInfo(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mCallWaitingInfoRegistrants.add(r);
- }
-
- public void unregisterForCallWaitingInfo(Handler h) {
- mCallWaitingInfoRegistrants.remove(h);
- }
-
- public void registerForSignalInfo(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mSignalInfoRegistrants.add(r);
- }
-
- public void setOnUnsolOemHookRaw(Handler h, int what, Object obj) {
- mUnsolOemHookRawRegistrant = new Registrant (h, what, obj);
- }
-
- public void unSetOnUnsolOemHookRaw(Handler h) {
- mUnsolOemHookRawRegistrant.clear();
- }
-
- public void unregisterForSignalInfo(Handler h) {
- mSignalInfoRegistrants.remove(h);
- }
-
- public void registerForCdmaOtaProvision(Handler h,int what, Object obj){
- Registrant r = new Registrant (h, what, obj);
- mOtaProvisionRegistrants.add(r);
- }
-
- public void unregisterForCdmaOtaProvision(Handler h){
- mOtaProvisionRegistrants.remove(h);
- }
-
- public void registerForNumberInfo(Handler h,int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mNumberInfoRegistrants.add(r);
- }
-
- public void unregisterForNumberInfo(Handler h){
- mNumberInfoRegistrants.remove(h);
- }
-
- public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mRedirNumInfoRegistrants.add(r);
- }
-
- public void unregisterForRedirectedNumberInfo(Handler h) {
- mRedirNumInfoRegistrants.remove(h);
- }
-
- public void registerForLineControlInfo(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mLineControlInfoRegistrants.add(r);
- }
-
- public void unregisterForLineControlInfo(Handler h) {
- mLineControlInfoRegistrants.remove(h);
- }
-
- public void registerFoT53ClirlInfo(Handler h,int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mT53ClirInfoRegistrants.add(r);
- }
-
- public void unregisterForT53ClirInfo(Handler h) {
- mT53ClirInfoRegistrants.remove(h);
- }
-
- public void registerForT53AudioControlInfo(Handler h,int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mT53AudCntrlInfoRegistrants.add(r);
- }
-
- public void unregisterForT53AudioControlInfo(Handler h) {
- mT53AudCntrlInfoRegistrants.remove(h);
- }
-
- public void registerForRingbackTone(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mRingbackToneRegistrants.add(r);
- }
-
- public void unregisterForRingbackTone(Handler h) {
- mRingbackToneRegistrants.remove(h);
- }
-
- public void registerForResendIncallMute(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mResendIncallMuteRegistrants.add(r);
- }
-
- public void unregisterForResendIncallMute(Handler h) {
- mResendIncallMuteRegistrants.remove(h);
- }
-
- @Override
- public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mCdmaSubscriptionChangedRegistrants.add(r);
- }
-
- @Override
- public void unregisterForCdmaSubscriptionChanged(Handler h) {
- mCdmaSubscriptionChangedRegistrants.remove(h);
- }
-
- @Override
- public void registerForCdmaPrlChanged(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mCdmaPrlChangedRegistrants.add(r);
- }
-
- @Override
- public void unregisterForCdmaPrlChanged(Handler h) {
- mCdmaPrlChangedRegistrants.remove(h);
- }
-
- @Override
- public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mExitEmergencyCallbackModeRegistrants.add(r);
- }
-
- @Override
- public void unregisterForExitEmergencyCallbackMode(Handler h) {
- mExitEmergencyCallbackModeRegistrants.remove(h);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void registerForRilConnected(Handler h, int what, Object obj) {
- Log.d(LOG_TAG, "registerForRilConnected h=" + h + " w=" + what);
- Registrant r = new Registrant (h, what, obj);
- mRilConnectedRegistrants.add(r);
- if (mRilVersion != -1) {
- Log.d(LOG_TAG, "Notifying: ril connected mRilVersion=" + mRilVersion);
- r.notifyRegistrant(new AsyncResult(null, new Integer(mRilVersion), null));
- }
- }
-
- @Override
- public void unregisterForRilConnected(Handler h) {
- mRilConnectedRegistrants.remove(h);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setCurrentPreferredNetworkType() {
- }
-
- //***** 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 3 values : RADIO_OFF, RADIO_UNAVAILABLE, RADIO_ON.
- *
- * @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
- */
- protected void setRadioState(RadioState newState) {
- RadioState oldState;
-
- synchronized (mStateMonitor) {
- if (false) {
- Log.v(LOG_TAG, "setRadioState old: " + mState
- + " new " + newState);
- }
-
- oldState = mState;
- mState = newState;
-
- if (oldState == mState) {
- // no state transition
- return;
- }
-
- 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.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();
- }
- }
- }
-
- protected void onRadioAvailable() {
- }
-
- /**
- * The contents of the /proc/cmdline file
- */
- private static String getProcCmdLine()
- {
- String cmdline = "";
- FileInputStream is = null;
- try {
- is = new FileInputStream("/proc/cmdline");
- byte [] buffer = new byte[2048];
- int count = is.read(buffer);
- if (count > 0) {
- cmdline = new String(buffer, 0, count);
- }
- } catch (IOException e) {
- Log.d(LOG_TAG, "No /proc/cmdline exception=" + e);
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- }
- }
- }
- Log.d(LOG_TAG, "/proc/cmdline=" + cmdline);
- return cmdline;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getLteOnCdmaMode() {
- return getLteOnCdmaModeStatic();
- }
-
- /** Kernel command line */
- private static final String sKernelCmdLine = getProcCmdLine();
-
- /** Pattern for selecting the product type from the kernel command line */
- private static final Pattern sProductTypePattern =
- Pattern.compile("\\sproduct_type\\s*=\\s*(\\w+)");
-
- /** The ProductType used for LTE on CDMA devices */
- private static final String sLteOnCdmaProductType =
- SystemProperties.get(TelephonyProperties.PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE, "");
-
- /**
- * Return if the current radio is LTE on CDMA. This
- * is a tri-state return value as for a period of time
- * the mode may be unknown.
- *
- * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
- * or {@link Phone#LTE_ON_CDMA_TRUE}
- */
- public static int getLteOnCdmaModeStatic() {
- int retVal;
- int curVal;
- String productType = "";
-
- curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
- Phone.LTE_ON_CDMA_UNKNOWN);
- retVal = curVal;
- if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) {
- Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
- if (matcher.find()) {
- productType = matcher.group(1);
- if (sLteOnCdmaProductType.equals(productType)) {
- retVal = Phone.LTE_ON_CDMA_TRUE;
- } else {
- retVal = Phone.LTE_ON_CDMA_FALSE;
- }
- } else {
- retVal = Phone.LTE_ON_CDMA_FALSE;
- }
- }
-
- Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
- " product_type='" + productType +
- "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
- return retVal;
- }
-
- @Override
- public void testingEmergencyCall() {}
-}
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java
deleted file mode 100644
index 4967ab8..0000000
--- a/telephony/java/com/android/internal/telephony/Call.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * 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.List;
-
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public abstract class Call {
- /* Enums */
-
- public enum State {
- IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING;
-
- public boolean isAlive() {
- return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING);
- }
-
- public boolean isRinging() {
- return this == INCOMING || this == WAITING;
- }
-
- public boolean isDialing() {
- return this == DIALING || this == ALERTING;
- }
- }
-
-
- /* Instance Variables */
-
- public State state = State.IDLE;
-
-
- // Flag to indicate if the current calling/caller information
- // is accurate. If false the information is known to be accurate.
- //
- // For CDMA, during call waiting/3 way, there is no network response
- // if call waiting is answered, network timed out, dropped, 3 way
- // merged, etc.
- protected boolean isGeneric = false;
-
- protected final String LOG_TAG = "Call";
-
- /* Instance Methods */
-
- /** Do not modify the List result!!! This list is not yours to keep
- * It will change across event loop iterations top
- */
-
- public abstract List<Connection> getConnections();
- 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)
- */
- public boolean isIdle() {
- return !getState().isAlive();
- }
-
- /**
- * Returns the Connection associated with this Call that was created
- * first, or null if there are no Connections in this Call
- */
- public Connection
- getEarliestConnection() {
- List l;
- 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;
- time = t;
- }
- }
-
- return earliest;
- }
-
- public long
- getEarliestCreateTime() {
- List l;
- long time = Long.MAX_VALUE;
-
- l = getConnections();
-
- if (l.size() == 0) {
- return 0;
- }
-
- for (int i = 0, s = l.size() ; i < s ; i++) {
- Connection c = (Connection) l.get(i);
- long t;
-
- t = c.getCreateTime();
-
- time = t < time ? t : time;
- }
-
- return time;
- }
-
- public long
- getEarliestConnectTime() {
- long time = Long.MAX_VALUE;
- List l = getConnections();
-
- if (l.size() == 0) {
- return 0;
- }
-
- for (int i = 0, s = l.size() ; i < s ; i++) {
- Connection c = (Connection) l.get(i);
- long t;
-
- t = c.getConnectTime();
-
- time = t < time ? t : time;
- }
-
- return time;
- }
-
-
- public boolean
- isDialingOrAlerting() {
- return getState().isDialing();
- }
-
- public boolean
- isRinging() {
- return getState().isRinging();
- }
-
- /**
- * Returns the Connection associated with this Call that was created
- * last, or null if there are no Connections in this Call
- */
- public Connection
- getLatestConnection() {
- List l = getConnections();
- if (l.size() == 0) {
- return null;
- }
-
- long time = 0;
- Connection latest = null;
- for (int i = 0, s = l.size() ; i < s ; i++) {
- Connection c = (Connection) l.get(i);
- long t = c.getCreateTime();
-
- if (t > time) {
- latest = c;
- time = t;
- }
- }
-
- return latest;
- }
-
- /**
- * To indicate if the connection information is accurate
- * or not. false means accurate. Only used for CDMA.
- */
- public boolean isGeneric() {
- return isGeneric;
- }
-
- /**
- * Set the generic instance variable
- */
- public void setGeneric(boolean generic) {
- isGeneric = generic;
- }
-
- /**
- * Hangup call if it is alive
- */
- public void hangupIfAlive() {
- if (getState().isAlive()) {
- try {
- hangup();
- } catch (CallStateException ex) {
- Log.w(LOG_TAG, " hangupIfActive: caught " + ex);
- }
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallForwardInfo.java b/telephony/java/com/android/internal/telephony/CallForwardInfo.java
deleted file mode 100644
index 8b853b0..0000000
--- a/telephony/java/com/android/internal/telephony/CallForwardInfo.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.telephony.PhoneNumberUtils;
-
-/**
- * See also RIL_CallForwardInfo in include/telephony/ril.h
- *
- * {@hide}
- */
-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 */
- public int toa; /* "type" from TS 27.007 7.11 */
- public String number; /* "number" from TS 27.007 7.11 */
- public int timeSeconds; /* for CF no reply only */
-
- public String toString() {
- return super.toString() + (status == 0 ? " not active " : " active ")
- + " reason: " + reason
- + " serviceClass: " + serviceClass
- + " \"" + PhoneNumberUtils.stringFromStringAndTOA(number, toa) + "\" "
- + timeSeconds + " seconds";
-
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
deleted file mode 100644
index f825f31..0000000
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ /dev/null
@@ -1,1855 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.internal.telephony.sip.SipPhone;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RegistrantList;
-import android.os.Registrant;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-
-
-/**
- * @hide
- *
- * CallManager class provides an abstract layer for PhoneApp to access
- * and control calls. It implements Phone interface.
- *
- * CallManager provides call and connection control as well as
- * channel capability.
- *
- * There are three categories of APIs CallManager provided
- *
- * 1. Call control and operation, such as dial() and hangup()
- * 2. Channel capabilities, such as CanConference()
- * 3. Register notification
- *
- *
- */
-public final class CallManager {
-
- private static final String LOG_TAG ="CallManager";
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
-
- private static final int EVENT_DISCONNECT = 100;
- private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101;
- private static final int EVENT_NEW_RINGING_CONNECTION = 102;
- private static final int EVENT_UNKNOWN_CONNECTION = 103;
- private static final int EVENT_INCOMING_RING = 104;
- private static final int EVENT_RINGBACK_TONE = 105;
- private static final int EVENT_IN_CALL_VOICE_PRIVACY_ON = 106;
- private static final int EVENT_IN_CALL_VOICE_PRIVACY_OFF = 107;
- private static final int EVENT_CALL_WAITING = 108;
- private static final int EVENT_DISPLAY_INFO = 109;
- private static final int EVENT_SIGNAL_INFO = 110;
- private static final int EVENT_CDMA_OTA_STATUS_CHANGE = 111;
- private static final int EVENT_RESEND_INCALL_MUTE = 112;
- private static final int EVENT_MMI_INITIATE = 113;
- private static final int EVENT_MMI_COMPLETE = 114;
- private static final int EVENT_ECM_TIMER_RESET = 115;
- private static final int EVENT_SUBSCRIPTION_INFO_READY = 116;
- private static final int EVENT_SUPP_SERVICE_FAILED = 117;
- private static final int EVENT_SERVICE_STATE_CHANGED = 118;
- private static final int EVENT_POST_DIAL_CHARACTER = 119;
-
- // Singleton instance
- private static final CallManager INSTANCE = new CallManager();
-
- // list of registered phones, which are PhoneBase objs
- private final ArrayList<Phone> mPhones;
-
- // list of supported ringing calls
- private final ArrayList<Call> mRingingCalls;
-
- // list of supported background calls
- private final ArrayList<Call> mBackgroundCalls;
-
- // list of supported foreground calls
- private final ArrayList<Call> mForegroundCalls;
-
- // empty connection list
- private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
-
- // default phone as the first phone registered, which is PhoneBase obj
- private Phone mDefaultPhone;
-
- // state registrants
- protected final RegistrantList mPreciseCallStateRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mNewRingingConnectionRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mIncomingRingRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mDisconnectRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mMmiRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mUnknownConnectionRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mRingbackToneRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mInCallVoicePrivacyOnRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mInCallVoicePrivacyOffRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mCallWaitingRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mDisplayInfoRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mSignalInfoRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mCdmaOtaStatusChangeRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mResendIncallMuteRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mMmiInitiateRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mMmiCompleteRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mEcmTimerResetRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mSubscriptionInfoReadyRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mSuppServiceFailedRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mServiceStateChangedRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mPostDialCharacterRegistrants
- = new RegistrantList();
-
- private CallManager() {
- mPhones = new ArrayList<Phone>();
- mRingingCalls = new ArrayList<Call>();
- mBackgroundCalls = new ArrayList<Call>();
- mForegroundCalls = new ArrayList<Call>();
- mDefaultPhone = null;
- }
-
- /**
- * get singleton instance of CallManager
- * @return CallManager
- */
- public static CallManager getInstance() {
- return INSTANCE;
- }
-
- /**
- * Get the corresponding PhoneBase obj
- *
- * @param phone a Phone object
- * @return the corresponding PhoneBase obj in Phone if Phone
- * is a PhoneProxy obj
- * or the Phone itself if Phone is not a PhoneProxy obj
- */
- private static Phone getPhoneBase(Phone phone) {
- if (phone instanceof PhoneProxy) {
- return phone.getForegroundCall().getPhone();
- }
- return phone;
- }
-
- /**
- * Check if two phones refer to the same PhoneBase obj
- *
- * Note: PhoneBase, not PhoneProxy, is to be used inside of CallManager
- *
- * Both PhoneBase and PhoneProxy implement Phone interface, so
- * they have same phone APIs, such as dial(). The real implementation, for
- * example in GSM, is in GSMPhone as extend from PhoneBase, so that
- * foregroundCall.getPhone() returns GSMPhone obj. On the other hand,
- * PhoneFactory.getDefaultPhone() returns PhoneProxy obj, which has a class
- * member of GSMPhone.
- *
- * So for phone returned by PhoneFacotry, which is used by PhoneApp,
- * phone.getForegroundCall().getPhone() != phone
- * but
- * isSamePhone(phone, phone.getForegroundCall().getPhone()) == true
- *
- * @param p1 is the first Phone obj
- * @param p2 is the second Phone obj
- * @return true if p1 and p2 refer to the same phone
- */
- public static boolean isSamePhone(Phone p1, Phone p2) {
- return (getPhoneBase(p1) == getPhoneBase(p2));
- }
-
- /**
- * Returns all the registered phone objects.
- * @return all the registered phone objects.
- */
- public List<Phone> getAllPhones() {
- return Collections.unmodifiableList(mPhones);
- }
-
- /**
- * Get current coarse-grained voice call state.
- * If the Call Manager has an active call and call waiting occurs,
- * then the phone state is RINGING not OFFHOOK
- *
- */
- public Phone.State getState() {
- Phone.State s = Phone.State.IDLE;
-
- for (Phone phone : mPhones) {
- if (phone.getState() == Phone.State.RINGING) {
- s = Phone.State.RINGING;
- } else if (phone.getState() == Phone.State.OFFHOOK) {
- if (s == Phone.State.IDLE) s = Phone.State.OFFHOOK;
- }
- }
- return s;
- }
-
- /**
- * @return the service state of CallManager, which represents the
- * highest priority state of all the service states of phones
- *
- * The priority is defined as
- *
- * STATE_IN_SERIVCE > STATE_OUT_OF_SERIVCE > STATE_EMERGENCY > STATE_POWER_OFF
- *
- */
-
- public int getServiceState() {
- int resultState = ServiceState.STATE_OUT_OF_SERVICE;
-
- for (Phone phone : mPhones) {
- int serviceState = phone.getServiceState().getState();
- if (serviceState == ServiceState.STATE_IN_SERVICE) {
- // IN_SERVICE has the highest priority
- resultState = serviceState;
- break;
- } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) {
- // OUT_OF_SERVICE replaces EMERGENCY_ONLY and POWER_OFF
- // Note: EMERGENCY_ONLY is not in use at this moment
- if ( resultState == ServiceState.STATE_EMERGENCY_ONLY ||
- resultState == ServiceState.STATE_POWER_OFF) {
- resultState = serviceState;
- }
- } else if (serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
- if (resultState == ServiceState.STATE_POWER_OFF) {
- resultState = serviceState;
- }
- }
- }
- return resultState;
- }
-
- /**
- * Register phone to CallManager
- * @param phone to be registered
- * @return true if register successfully
- */
- public boolean registerPhone(Phone phone) {
- Phone basePhone = getPhoneBase(phone);
-
- if (basePhone != null && !mPhones.contains(basePhone)) {
-
- if (DBG) {
- Log.d(LOG_TAG, "registerPhone(" +
- phone.getPhoneName() + " " + phone + ")");
- }
-
- if (mPhones.isEmpty()) {
- mDefaultPhone = basePhone;
- }
- mPhones.add(basePhone);
- mRingingCalls.add(basePhone.getRingingCall());
- mBackgroundCalls.add(basePhone.getBackgroundCall());
- mForegroundCalls.add(basePhone.getForegroundCall());
- registerForPhoneStates(basePhone);
- return true;
- }
- return false;
- }
-
- /**
- * unregister phone from CallManager
- * @param phone to be unregistered
- */
- public void unregisterPhone(Phone phone) {
- Phone basePhone = getPhoneBase(phone);
-
- if (basePhone != null && mPhones.contains(basePhone)) {
-
- if (DBG) {
- Log.d(LOG_TAG, "unregisterPhone(" +
- phone.getPhoneName() + " " + phone + ")");
- }
-
- mPhones.remove(basePhone);
- mRingingCalls.remove(basePhone.getRingingCall());
- mBackgroundCalls.remove(basePhone.getBackgroundCall());
- mForegroundCalls.remove(basePhone.getForegroundCall());
- unregisterForPhoneStates(basePhone);
- if (basePhone == mDefaultPhone) {
- if (mPhones.isEmpty()) {
- mDefaultPhone = null;
- } else {
- mDefaultPhone = mPhones.get(0);
- }
- }
- }
- }
-
- /**
- * return the default phone or null if no phone available
- */
- public Phone getDefaultPhone() {
- return mDefaultPhone;
- }
-
- /**
- * @return the phone associated with the foreground call
- */
- public Phone getFgPhone() {
- return getActiveFgCall().getPhone();
- }
-
- /**
- * @return the phone associated with the background call
- */
- public Phone getBgPhone() {
- return getFirstActiveBgCall().getPhone();
- }
-
- /**
- * @return the phone associated with the ringing call
- */
- public Phone getRingingPhone() {
- return getFirstActiveRingingCall().getPhone();
- }
-
- public void setAudioMode() {
- Context context = getContext();
- if (context == null) return;
- AudioManager audioManager = (AudioManager)
- context.getSystemService(Context.AUDIO_SERVICE);
-
- // change the audio mode and request/abandon audio focus according to phone state,
- // but only on audio mode transitions
- switch (getState()) {
- case RINGING:
- if (audioManager.getMode() != AudioManager.MODE_RINGTONE) {
- // only request audio focus if the ringtone is going to be heard
- if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
- if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
- audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
- }
- audioManager.setMode(AudioManager.MODE_RINGTONE);
- }
- break;
- case OFFHOOK:
- Phone offhookPhone = getFgPhone();
- if (getActiveFgCallState() == Call.State.IDLE) {
- // There is no active Fg calls, the OFFHOOK state
- // is set by the Bg call. So set the phone to bgPhone.
- offhookPhone = getBgPhone();
- }
-
- int newAudioMode = AudioManager.MODE_IN_CALL;
- if (offhookPhone instanceof SipPhone) {
- // enable IN_COMMUNICATION audio mode instead for sipPhone
- newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
- }
- if (audioManager.getMode() != newAudioMode) {
- // request audio focus before setting the new mode
- if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
- audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
- audioManager.setMode(newAudioMode);
- }
- break;
- case IDLE:
- if (audioManager.getMode() != AudioManager.MODE_NORMAL) {
- audioManager.setMode(AudioManager.MODE_NORMAL);
- if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus");
- // abandon audio focus after the mode has been set back to normal
- audioManager.abandonAudioFocusForCall();
- }
- break;
- }
- }
-
- private Context getContext() {
- Phone defaultPhone = getDefaultPhone();
- return ((defaultPhone == null) ? null : defaultPhone.getContext());
- }
-
- private void registerForPhoneStates(Phone phone) {
- // for common events supported by all phones
- phone.registerForPreciseCallStateChanged(mHandler, EVENT_PRECISE_CALL_STATE_CHANGED, null);
- phone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
- phone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null);
- phone.registerForUnknownConnection(mHandler, EVENT_UNKNOWN_CONNECTION, null);
- phone.registerForIncomingRing(mHandler, EVENT_INCOMING_RING, null);
- phone.registerForRingbackTone(mHandler, EVENT_RINGBACK_TONE, null);
- phone.registerForInCallVoicePrivacyOn(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_ON, null);
- phone.registerForInCallVoicePrivacyOff(mHandler, EVENT_IN_CALL_VOICE_PRIVACY_OFF, null);
- phone.registerForDisplayInfo(mHandler, EVENT_DISPLAY_INFO, null);
- phone.registerForSignalInfo(mHandler, EVENT_SIGNAL_INFO, null);
- phone.registerForResendIncallMute(mHandler, EVENT_RESEND_INCALL_MUTE, null);
- phone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
- phone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
- phone.registerForSuppServiceFailed(mHandler, EVENT_SUPP_SERVICE_FAILED, null);
- phone.registerForServiceStateChanged(mHandler, EVENT_SERVICE_STATE_CHANGED, null);
-
- // for events supported only by GSM and CDMA phone
- if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM ||
- phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
- phone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL_CHARACTER, null);
- }
-
- // for events supported only by CDMA phone
- if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){
- phone.registerForCdmaOtaStatusChange(mHandler, EVENT_CDMA_OTA_STATUS_CHANGE, null);
- phone.registerForSubscriptionInfoReady(mHandler, EVENT_SUBSCRIPTION_INFO_READY, null);
- phone.registerForCallWaiting(mHandler, EVENT_CALL_WAITING, null);
- phone.registerForEcmTimerReset(mHandler, EVENT_ECM_TIMER_RESET, null);
- }
- }
-
- private void unregisterForPhoneStates(Phone phone) {
- // for common events supported by all phones
- phone.unregisterForPreciseCallStateChanged(mHandler);
- phone.unregisterForDisconnect(mHandler);
- phone.unregisterForNewRingingConnection(mHandler);
- phone.unregisterForUnknownConnection(mHandler);
- phone.unregisterForIncomingRing(mHandler);
- phone.unregisterForRingbackTone(mHandler);
- phone.unregisterForInCallVoicePrivacyOn(mHandler);
- phone.unregisterForInCallVoicePrivacyOff(mHandler);
- phone.unregisterForDisplayInfo(mHandler);
- phone.unregisterForSignalInfo(mHandler);
- phone.unregisterForResendIncallMute(mHandler);
- phone.unregisterForMmiInitiate(mHandler);
- phone.unregisterForMmiComplete(mHandler);
- phone.unregisterForSuppServiceFailed(mHandler);
- phone.unregisterForServiceStateChanged(mHandler);
-
- // for events supported only by GSM and CDMA phone
- if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM ||
- phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
- phone.setOnPostDialCharacter(null, EVENT_POST_DIAL_CHARACTER, null);
- }
-
- // for events supported only by CDMA phone
- if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA ){
- phone.unregisterForCdmaOtaStatusChange(mHandler);
- phone.unregisterForSubscriptionInfoReady(mHandler);
- phone.unregisterForCallWaiting(mHandler);
- phone.unregisterForEcmTimerReset(mHandler);
- }
- }
-
- /**
- * Answers a ringing or waiting call.
- *
- * Active call, if any, go on hold.
- * If active call can't be held, i.e., a background call of the same channel exists,
- * the active call will be hang up.
- *
- * Answering occurs asynchronously, and final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException when call is not ringing or waiting
- */
- public void acceptCall(Call ringingCall) throws CallStateException {
- Phone ringingPhone = ringingCall.getPhone();
-
- if (VDBG) {
- Log.d(LOG_TAG, "acceptCall(" +ringingCall + " from " + ringingCall.getPhone() + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if ( hasActiveFgCall() ) {
- Phone activePhone = getActiveFgCall().getPhone();
- boolean hasBgCall = ! (activePhone.getBackgroundCall().isIdle());
- boolean sameChannel = (activePhone == ringingPhone);
-
- if (VDBG) {
- Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + "sameChannel:" + sameChannel);
- }
-
- if (sameChannel && hasBgCall) {
- getActiveFgCall().hangup();
- } else if (!sameChannel && !hasBgCall) {
- activePhone.switchHoldingAndActive();
- } else if (!sameChannel && hasBgCall) {
- getActiveFgCall().hangup();
- }
- }
-
- ringingPhone.acceptCall();
-
- if (VDBG) {
- Log.d(LOG_TAG, "End acceptCall(" +ringingCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
- }
-
- /**
- * Reject (ignore) a ringing call. In GSM, this means UDUB
- * (User Determined User Busy). Reject occurs asynchronously,
- * and final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException when no call is ringing or waiting
- */
- public void rejectCall(Call ringingCall) throws CallStateException {
- if (VDBG) {
- Log.d(LOG_TAG, "rejectCall(" +ringingCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- Phone ringingPhone = ringingCall.getPhone();
-
- ringingPhone.rejectCall();
-
- if (VDBG) {
- Log.d(LOG_TAG, "End rejectCall(" +ringingCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
- }
-
- /**
- * Places active call on hold, and makes held call active.
- * Switch occurs asynchronously and may fail.
- *
- * There are 4 scenarios
- * 1. only active call but no held call, aka, hold
- * 2. no active call but only held call, aka, unhold
- * 3. both active and held calls from same phone, aka, swap
- * 4. active and held calls from different phones, aka, phone swap
- *
- * Final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException if active call is ringing, waiting, or
- * dialing/alerting, or heldCall can't be active.
- * In these cases, this operation may not be performed.
- */
- public void switchHoldingAndActive(Call heldCall) throws CallStateException {
- Phone activePhone = null;
- Phone heldPhone = null;
-
- if (VDBG) {
- Log.d(LOG_TAG, "switchHoldingAndActive(" +heldCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if (hasActiveFgCall()) {
- activePhone = getActiveFgCall().getPhone();
- }
-
- if (heldCall != null) {
- heldPhone = heldCall.getPhone();
- }
-
- if (activePhone != null) {
- activePhone.switchHoldingAndActive();
- }
-
- if (heldPhone != null && heldPhone != activePhone) {
- heldPhone.switchHoldingAndActive();
- }
-
- if (VDBG) {
- Log.d(LOG_TAG, "End switchHoldingAndActive(" +heldCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
- }
-
- /**
- * Hangup foreground call and resume the specific background call
- *
- * Note: this is noop if there is no foreground call or the heldCall is null
- *
- * @param heldCall to become foreground
- * @throws CallStateException
- */
- public void hangupForegroundResumeBackground(Call heldCall) throws CallStateException {
- Phone foregroundPhone = null;
- Phone backgroundPhone = null;
-
- if (VDBG) {
- Log.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if (hasActiveFgCall()) {
- foregroundPhone = getFgPhone();
- if (heldCall != null) {
- backgroundPhone = heldCall.getPhone();
- if (foregroundPhone == backgroundPhone) {
- getActiveFgCall().hangup();
- } else {
- // the call to be hangup and resumed belongs to different phones
- getActiveFgCall().hangup();
- switchHoldingAndActive(heldCall);
- }
- }
- }
-
- if (VDBG) {
- Log.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
- }
-
- /**
- * Whether or not the phone can conference in the current phone
- * state--that is, one call holding and one call active.
- * @return true if the phone can conference; false otherwise.
- */
- public boolean canConference(Call heldCall) {
- Phone activePhone = null;
- Phone heldPhone = null;
-
- if (hasActiveFgCall()) {
- activePhone = getActiveFgCall().getPhone();
- }
-
- if (heldCall != null) {
- heldPhone = heldCall.getPhone();
- }
-
- return heldPhone.getClass().equals(activePhone.getClass());
- }
-
- /**
- * Conferences holding and active. Conference occurs asynchronously
- * and may fail. Final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException if canConference() would return false.
- * In these cases, this operation may not be performed.
- */
- public void conference(Call heldCall) throws CallStateException {
-
- if (VDBG) {
- Log.d(LOG_TAG, "conference(" +heldCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
-
- Phone fgPhone = getFgPhone();
- if (fgPhone instanceof SipPhone) {
- ((SipPhone) fgPhone).conference(heldCall);
- } else if (canConference(heldCall)) {
- fgPhone.conference();
- } else {
- throw(new CallStateException("Can't conference foreground and selected background call"));
- }
-
- if (VDBG) {
- Log.d(LOG_TAG, "End conference(" +heldCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- }
-
- /**
- * Initiate a new voice connection. This happens asynchronously, so you
- * cannot assume the audio path is connected (or a call index has been
- * assigned) until PhoneStateChanged notification has occurred.
- *
- * @exception CallStateException if a new outgoing call is not currently
- * possible because no more call slots exist or a call exists that is
- * dialing, alerting, ringing, or waiting. Other errors are
- * handled asynchronously.
- */
- public Connection dial(Phone phone, String dialString) throws CallStateException {
- Phone basePhone = getPhoneBase(phone);
- Connection result;
-
- if (VDBG) {
- Log.d(LOG_TAG, " dial(" + basePhone + ", "+ dialString + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if (!canDial(phone)) {
- throw new CallStateException("cannot dial in current state");
- }
-
- if ( hasActiveFgCall() ) {
- Phone activePhone = getActiveFgCall().getPhone();
- boolean hasBgCall = !(activePhone.getBackgroundCall().isIdle());
-
- if (DBG) {
- Log.d(LOG_TAG, "hasBgCall: "+ hasBgCall + " sameChannel:" + (activePhone == basePhone));
- }
-
- if (activePhone != basePhone) {
- if (hasBgCall) {
- Log.d(LOG_TAG, "Hangup");
- getActiveFgCall().hangup();
- } else {
- Log.d(LOG_TAG, "Switch");
- activePhone.switchHoldingAndActive();
- }
- }
- }
-
- result = basePhone.dial(dialString);
-
- if (VDBG) {
- Log.d(LOG_TAG, "End dial(" + basePhone + ", "+ dialString + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- return result;
- }
-
- /**
- * Initiate a new voice connection. This happens asynchronously, so you
- * cannot assume the audio path is connected (or a call index has been
- * assigned) until PhoneStateChanged notification has occurred.
- *
- * @exception CallStateException if a new outgoing call is not currently
- * possible because no more call slots exist or a call exists that is
- * dialing, alerting, ringing, or waiting. Other errors are
- * handled asynchronously.
- */
- public Connection dial(Phone phone, String dialString, UUSInfo uusInfo) throws CallStateException {
- return phone.dial(dialString, uusInfo);
- }
-
- /**
- * clear disconnect connection for each phone
- */
- public void clearDisconnected() {
- for(Phone phone : mPhones) {
- phone.clearDisconnected();
- }
- }
-
- /**
- * Phone can make a call only if ALL of the following are true:
- * - Phone is not powered off
- * - There's no incoming or waiting call
- * - There's available call slot in either foreground or background
- * - The foreground call is ACTIVE or IDLE or DISCONNECTED.
- * (We mainly need to make sure it *isn't* DIALING or ALERTING.)
- * @param phone
- * @return true if the phone can make a new call
- */
- private boolean canDial(Phone phone) {
- int serviceState = phone.getServiceState().getState();
- boolean hasRingingCall = hasActiveRingingCall();
- boolean hasActiveCall = hasActiveFgCall();
- boolean hasHoldingCall = hasActiveBgCall();
- boolean allLinesTaken = hasActiveCall && hasHoldingCall;
- Call.State fgCallState = getActiveFgCallState();
-
- boolean result = (serviceState != ServiceState.STATE_POWER_OFF
- && !hasRingingCall
- && !allLinesTaken
- && ((fgCallState == Call.State.ACTIVE)
- || (fgCallState == Call.State.IDLE)
- || (fgCallState == Call.State.DISCONNECTED)));
-
- if (result == false) {
- Log.d(LOG_TAG, "canDial serviceState=" + serviceState
- + " hasRingingCall=" + hasRingingCall
- + " hasActiveCall=" + hasActiveCall
- + " hasHoldingCall=" + hasHoldingCall
- + " allLinesTaken=" + allLinesTaken
- + " fgCallState=" + fgCallState);
- }
- return result;
- }
-
- /**
- * Whether or not the phone can do explicit call transfer in the current
- * phone state--that is, one call holding and one call active.
- * @return true if the phone can do explicit call transfer; false otherwise.
- */
- public boolean canTransfer(Call heldCall) {
- Phone activePhone = null;
- Phone heldPhone = null;
-
- if (hasActiveFgCall()) {
- activePhone = getActiveFgCall().getPhone();
- }
-
- if (heldCall != null) {
- heldPhone = heldCall.getPhone();
- }
-
- return (heldPhone == activePhone && activePhone.canTransfer());
- }
-
- /**
- * Connects the held call and active call
- * Disconnects the subscriber from both calls
- *
- * Explicit Call Transfer occurs asynchronously
- * and may fail. Final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException if canTransfer() would return false.
- * In these cases, this operation may not be performed.
- */
- public void explicitCallTransfer(Call heldCall) throws CallStateException {
- if (VDBG) {
- Log.d(LOG_TAG, " explicitCallTransfer(" + heldCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if (canTransfer(heldCall)) {
- heldCall.getPhone().explicitCallTransfer();
- }
-
- if (VDBG) {
- Log.d(LOG_TAG, "End explicitCallTransfer(" + heldCall + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- }
-
- /**
- * Returns a list of MMI codes that are pending for a phone. (They have initiated
- * but have not yet completed).
- * Presently there is only ever one.
- *
- * Use <code>registerForMmiInitiate</code>
- * and <code>registerForMmiComplete</code> for change notification.
- * @return null if phone doesn't have or support mmi code
- */
- public List<? extends MmiCode> getPendingMmiCodes(Phone phone) {
- Log.e(LOG_TAG, "getPendingMmiCodes not implemented");
- return null;
- }
-
- /**
- * Sends user response to a USSD REQUEST message. An MmiCode instance
- * representing this response is sent to handlers registered with
- * registerForMmiInitiate.
- *
- * @param ussdMessge Message to send in the response.
- * @return false if phone doesn't support ussd service
- */
- public boolean sendUssdResponse(Phone phone, String ussdMessge) {
- Log.e(LOG_TAG, "sendUssdResponse not implemented");
- return false;
- }
-
- /**
- * Mutes or unmutes the microphone for the active call. The microphone
- * is automatically unmuted if a call is answered, dialed, or resumed
- * from a holding state.
- *
- * @param muted true to mute the microphone,
- * false to activate the microphone.
- */
-
- public void setMute(boolean muted) {
- if (VDBG) {
- Log.d(LOG_TAG, " setMute(" + muted + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if (hasActiveFgCall()) {
- getActiveFgCall().getPhone().setMute(muted);
- }
-
- if (VDBG) {
- Log.d(LOG_TAG, "End setMute(" + muted + ")");
- Log.d(LOG_TAG, this.toString());
- }
- }
-
- /**
- * Gets current mute status. Use
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}
- * as a change notifcation, although presently phone state changed is not
- * fired when setMute() is called.
- *
- * @return true is muting, false is unmuting
- */
- public boolean getMute() {
- if (hasActiveFgCall()) {
- return getActiveFgCall().getPhone().getMute();
- } else if (hasActiveBgCall()) {
- return getFirstActiveBgCall().getPhone().getMute();
- }
- return false;
- }
-
- /**
- * Enables or disables echo suppression.
- */
- public void setEchoSuppressionEnabled(boolean enabled) {
- if (VDBG) {
- Log.d(LOG_TAG, " setEchoSuppression(" + enabled + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if (hasActiveFgCall()) {
- getActiveFgCall().getPhone().setEchoSuppressionEnabled(enabled);
- }
-
- if (VDBG) {
- Log.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")");
- Log.d(LOG_TAG, this.toString());
- }
- }
-
- /**
- * Play a DTMF tone on the active call.
- *
- * @param c should be one of 0-9, '*' or '#'. Other values will be
- * silently ignored.
- * @return false if no active call or the active call doesn't support
- * dtmf tone
- */
- public boolean sendDtmf(char c) {
- boolean result = false;
-
- if (VDBG) {
- Log.d(LOG_TAG, " sendDtmf(" + c + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if (hasActiveFgCall()) {
- getActiveFgCall().getPhone().sendDtmf(c);
- result = true;
- }
-
- if (VDBG) {
- Log.d(LOG_TAG, "End sendDtmf(" + c + ")");
- Log.d(LOG_TAG, this.toString());
- }
- return result;
- }
-
- /**
- * Start to paly a DTMF tone on the active call.
- * or there is a playing DTMF tone.
- * @param c should be one of 0-9, '*' or '#'. Other values will be
- * silently ignored.
- *
- * @return false if no active call or the active call doesn't support
- * dtmf tone
- */
- public boolean startDtmf(char c) {
- boolean result = false;
-
- if (VDBG) {
- Log.d(LOG_TAG, " startDtmf(" + c + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- if (hasActiveFgCall()) {
- getActiveFgCall().getPhone().startDtmf(c);
- result = true;
- }
-
- if (VDBG) {
- Log.d(LOG_TAG, "End startDtmf(" + c + ")");
- Log.d(LOG_TAG, this.toString());
- }
-
- return result;
- }
-
- /**
- * Stop the playing DTMF tone. Ignored if there is no playing DTMF
- * tone or no active call.
- */
- public void stopDtmf() {
- if (VDBG) {
- Log.d(LOG_TAG, " stopDtmf()" );
- Log.d(LOG_TAG, this.toString());
- }
-
- if (hasActiveFgCall()) getFgPhone().stopDtmf();
-
- if (VDBG) {
- Log.d(LOG_TAG, "End stopDtmf()");
- Log.d(LOG_TAG, this.toString());
- }
- }
-
- /**
- * send burst DTMF tone, it can send the string as single character or multiple character
- * ignore if there is no active call or not valid digits string.
- * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
- * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
- * this api can send single character and multiple character, also, this api has response
- * back to caller.
- *
- * @param dtmfString is string representing the dialing digit(s) in the active call
- * @param on the DTMF ON length in milliseconds, or 0 for default
- * @param off the DTMF OFF length in milliseconds, or 0 for default
- * @param onComplete is the callback message when the action is processed by BP
- *
- */
- public boolean sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
- if (hasActiveFgCall()) {
- getActiveFgCall().getPhone().sendBurstDtmf(dtmfString, on, off, onComplete);
- return true;
- }
- return false;
- }
-
- /**
- * Notifies when a voice connection has disconnected, either due to local
- * or remote hangup or error.
- *
- * Messages received from this will have the following members:<p>
- * <ul><li>Message.obj will be an AsyncResult</li>
- * <li>AsyncResult.userObj = obj</li>
- * <li>AsyncResult.result = a Connection object that is
- * no longer connected.</li></ul>
- */
- public void registerForDisconnect(Handler h, int what, Object obj) {
- mDisconnectRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for voice disconnection notification.
- * Extraneous calls are tolerated silently
- */
- public void unregisterForDisconnect(Handler h){
- mDisconnectRegistrants.remove(h);
- }
-
- /**
- * Register for getting notifications for change in the Call State {@link Call.State}
- * This is called PreciseCallState because the call state is more precise than the
- * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
- *
- * Resulting events will have an AsyncResult in <code>Message.obj</code>.
- * AsyncResult.userData will be set to the obj argument here.
- * The <em>h</em> parameter is held only by a weak reference.
- */
- public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){
- mPreciseCallStateRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for voice call state change notifications.
- * Extraneous calls are tolerated silently.
- */
- public void unregisterForPreciseCallStateChanged(Handler h){
- mPreciseCallStateRegistrants.remove(h);
- }
-
- /**
- * Notifies when a previously untracked non-ringing/waiting connection has appeared.
- * This is likely due to some other entity (eg, SIM card application) initiating a call.
- */
- public void registerForUnknownConnection(Handler h, int what, Object obj){
- mUnknownConnectionRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for unknown connection notifications.
- */
- public void unregisterForUnknownConnection(Handler h){
- mUnknownConnectionRegistrants.remove(h);
- }
-
-
- /**
- * Notifies when a new ringing or waiting connection has appeared.<p>
- *
- * Messages received from this:
- * Message.obj will be an AsyncResult
- * AsyncResult.userObj = obj
- * AsyncResult.result = a Connection. <p>
- * Please check Connection.isRinging() to make sure the Connection
- * has not dropped since this message was posted.
- * If Connection.isRinging() is true, then
- * Connection.getCall() == Phone.getRingingCall()
- */
- public void registerForNewRingingConnection(Handler h, int what, Object obj){
- mNewRingingConnectionRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for new ringing connection notification.
- * Extraneous calls are tolerated silently
- */
-
- public void unregisterForNewRingingConnection(Handler h){
- mNewRingingConnectionRegistrants.remove(h);
- }
-
- /**
- * Notifies when an incoming call rings.<p>
- *
- * Messages received from this:
- * Message.obj will be an AsyncResult
- * AsyncResult.userObj = obj
- * AsyncResult.result = a Connection. <p>
- */
- public void registerForIncomingRing(Handler h, int what, Object obj){
- mIncomingRingRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for ring notification.
- * Extraneous calls are tolerated silently
- */
-
- public void unregisterForIncomingRing(Handler h){
- mIncomingRingRegistrants.remove(h);
- }
-
- /**
- * Notifies when out-band ringback tone is needed.<p>
- *
- * Messages received from this:
- * Message.obj will be an AsyncResult
- * AsyncResult.userObj = obj
- * AsyncResult.result = boolean, true to start play ringback tone
- * and false to stop. <p>
- */
- public void registerForRingbackTone(Handler h, int what, Object obj){
- mRingbackToneRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for ringback tone notification.
- */
-
- public void unregisterForRingbackTone(Handler h){
- mRingbackToneRegistrants.remove(h);
- }
-
- /**
- * Registers the handler to reset the uplink mute state to get
- * uplink audio.
- */
- public void registerForResendIncallMute(Handler h, int what, Object obj){
- mResendIncallMuteRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for resend incall mute notifications.
- */
- public void unregisterForResendIncallMute(Handler h){
- mResendIncallMuteRegistrants.remove(h);
- }
-
- /**
- * Register for notifications of initiation of a new MMI code request.
- * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
- *
- * Example: If Phone.dial is called with "*#31#", then the app will
- * be notified here.<p>
- *
- * The returned <code>Message.obj</code> will contain an AsyncResult.
- *
- * <code>obj.result</code> will be an "MmiCode" object.
- */
- public void registerForMmiInitiate(Handler h, int what, Object obj){
- mMmiInitiateRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for new MMI initiate notification.
- * Extraneous calls are tolerated silently
- */
- public void unregisterForMmiInitiate(Handler h){
- mMmiInitiateRegistrants.remove(h);
- }
-
- /**
- * Register for notifications that an MMI request has completed
- * its network activity and is in its final state. This may mean a state
- * of COMPLETE, FAILED, or CANCELLED.
- *
- * <code>Message.obj</code> will contain an AsyncResult.
- * <code>obj.result</code> will be an "MmiCode" object
- */
- public void registerForMmiComplete(Handler h, int what, Object obj){
- mMmiCompleteRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for MMI complete notification.
- * Extraneous calls are tolerated silently
- */
- public void unregisterForMmiComplete(Handler h){
- mMmiCompleteRegistrants.remove(h);
- }
-
- /**
- * Registration point for Ecm timer reset
- * @param h handler to notify
- * @param what user-defined message code
- * @param obj placed in Message.obj
- */
- public void registerForEcmTimerReset(Handler h, int what, Object obj){
- mEcmTimerResetRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregister for notification for Ecm timer reset
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForEcmTimerReset(Handler h){
- mEcmTimerResetRegistrants.remove(h);
- }
-
- /**
- * Register for ServiceState changed.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a ServiceState instance
- */
- public void registerForServiceStateChanged(Handler h, int what, Object obj){
- mServiceStateChangedRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for ServiceStateChange notification.
- * Extraneous calls are tolerated silently
- */
- public void unregisterForServiceStateChanged(Handler h){
- mServiceStateChangedRegistrants.remove(h);
- }
-
- /**
- * Register for notifications when a supplementary service attempt fails.
- * Message.obj will contain an AsyncResult.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- public void registerForSuppServiceFailed(Handler h, int what, Object obj){
- mSuppServiceFailedRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregister for notifications when a supplementary service attempt fails.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForSuppServiceFailed(Handler h){
- mSuppServiceFailedRegistrants.remove(h);
- }
-
- /**
- * Register for notifications when a sInCall VoicePrivacy is enabled
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
- mInCallVoicePrivacyOnRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregister for notifications when a sInCall VoicePrivacy is enabled
- *
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForInCallVoicePrivacyOn(Handler h){
- mInCallVoicePrivacyOnRegistrants.remove(h);
- }
-
- /**
- * Register for notifications when a sInCall VoicePrivacy is disabled
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
- mInCallVoicePrivacyOffRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregister for notifications when a sInCall VoicePrivacy is disabled
- *
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForInCallVoicePrivacyOff(Handler h){
- mInCallVoicePrivacyOffRegistrants.remove(h);
- }
-
- /**
- * Register for notifications when CDMA call waiting comes
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- public void registerForCallWaiting(Handler h, int what, Object obj){
- mCallWaitingRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregister for notifications when CDMA Call waiting comes
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForCallWaiting(Handler h){
- mCallWaitingRegistrants.remove(h);
- }
-
-
- /**
- * Register for signal information notifications from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a SuppServiceNotification instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
-
- public void registerForSignalInfo(Handler h, int what, Object obj){
- mSignalInfoRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for signal information notifications.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForSignalInfo(Handler h){
- mSignalInfoRegistrants.remove(h);
- }
-
- /**
- * Register for display information notifications from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a SuppServiceNotification instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- public void registerForDisplayInfo(Handler h, int what, Object obj){
- mDisplayInfoRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregisters for display information notifications.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForDisplayInfo(Handler h) {
- mDisplayInfoRegistrants.remove(h);
- }
-
- /**
- * Register for notifications when CDMA OTA Provision status change
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj){
- mCdmaOtaStatusChangeRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregister for notifications when CDMA OTA Provision status change
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForCdmaOtaStatusChange(Handler h){
- mCdmaOtaStatusChangeRegistrants.remove(h);
- }
-
- /**
- * Registration point for subscription info ready
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForSubscriptionInfoReady(Handler h, int what, Object obj){
- mSubscriptionInfoReadyRegistrants.addUnique(h, what, obj);
- }
-
- /**
- * Unregister for notifications for subscription info
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForSubscriptionInfoReady(Handler h){
- mSubscriptionInfoReadyRegistrants.remove(h);
- }
-
- /**
- * Sets an event to be fired when the telephony system processes
- * a post-dial character on an outgoing call.<p>
- *
- * Messages of type <code>what</code> will be sent to <code>h</code>.
- * The <code>obj</code> field of these Message's will be instances of
- * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
- * a Connection object.<p>
- *
- * Message.arg1 will be the post dial character being processed,
- * or 0 ('\0') if end of string.<p>
- *
- * If Connection.getPostDialState() == WAIT,
- * the application must call
- * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
- * Connection.proceedAfterWaitChar()} or
- * {@link com.android.internal.telephony.Connection#cancelPostDial()
- * Connection.cancelPostDial()}
- * for the telephony system to continue playing the post-dial
- * DTMF sequence.<p>
- *
- * If Connection.getPostDialState() == WILD,
- * the application must call
- * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
- * Connection.proceedAfterWildChar()}
- * or
- * {@link com.android.internal.telephony.Connection#cancelPostDial()
- * Connection.cancelPostDial()}
- * for the telephony system to continue playing the
- * post-dial DTMF sequence.<p>
- *
- */
- public void registerForPostDialCharacter(Handler h, int what, Object obj){
- mPostDialCharacterRegistrants.addUnique(h, what, obj);
- }
-
- public void unregisterForPostDialCharacter(Handler h){
- mPostDialCharacterRegistrants.remove(h);
- }
-
- /* APIs to access foregroudCalls, backgroudCalls, and ringingCalls
- * 1. APIs to access list of calls
- * 2. APIs to check if any active call, which has connection other than
- * disconnected ones, pleaser refer to Call.isIdle()
- * 3. APIs to return first active call
- * 4. APIs to return the connections of first active call
- * 5. APIs to return other property of first active call
- */
-
- /**
- * @return list of all ringing calls
- */
- public List<Call> getRingingCalls() {
- return Collections.unmodifiableList(mRingingCalls);
- }
-
- /**
- * @return list of all foreground calls
- */
- public List<Call> getForegroundCalls() {
- return Collections.unmodifiableList(mForegroundCalls);
- }
-
- /**
- * @return list of all background calls
- */
- public List<Call> getBackgroundCalls() {
- return Collections.unmodifiableList(mBackgroundCalls);
- }
-
- /**
- * Return true if there is at least one active foreground call
- */
- public boolean hasActiveFgCall() {
- return (getFirstActiveCall(mForegroundCalls) != null);
- }
-
- /**
- * Return true if there is at least one active background call
- */
- public boolean hasActiveBgCall() {
- // TODO since hasActiveBgCall may get called often
- // better to cache it to improve performance
- return (getFirstActiveCall(mBackgroundCalls) != null);
- }
-
- /**
- * Return true if there is at least one active ringing call
- *
- */
- public boolean hasActiveRingingCall() {
- return (getFirstActiveCall(mRingingCalls) != null);
- }
-
- /**
- * return the active foreground call from foreground calls
- *
- * Active call means the call is NOT in Call.State.IDLE
- *
- * 1. If there is active foreground call, return it
- * 2. If there is no active foreground call, return the
- * foreground call associated with default phone, which state is IDLE.
- * 3. If there is no phone registered at all, return null.
- *
- */
- public Call getActiveFgCall() {
- Call call = getFirstNonIdleCall(mForegroundCalls);
- if (call == null) {
- call = (mDefaultPhone == null)
- ? null
- : mDefaultPhone.getForegroundCall();
- }
- return call;
- }
-
- // Returns the first call that is not in IDLE state. If both active calls
- // and disconnecting/disconnected calls exist, return the first active call.
- private Call getFirstNonIdleCall(List<Call> calls) {
- Call result = null;
- for (Call call : calls) {
- if (!call.isIdle()) {
- return call;
- } else if (call.getState() != Call.State.IDLE) {
- if (result == null) result = call;
- }
- }
- return result;
- }
-
- /**
- * return one active background call from background calls
- *
- * Active call means the call is NOT idle defined by Call.isIdle()
- *
- * 1. If there is only one active background call, return it
- * 2. If there is more than one active background call, return the first one
- * 3. If there is no active background call, return the background call
- * associated with default phone, which state is IDLE.
- * 4. If there is no background call at all, return null.
- *
- * Complete background calls list can be get by getBackgroundCalls()
- */
- public Call getFirstActiveBgCall() {
- Call call = getFirstNonIdleCall(mBackgroundCalls);
- if (call == null) {
- call = (mDefaultPhone == null)
- ? null
- : mDefaultPhone.getBackgroundCall();
- }
- return call;
- }
-
- /**
- * return one active ringing call from ringing calls
- *
- * Active call means the call is NOT idle defined by Call.isIdle()
- *
- * 1. If there is only one active ringing call, return it
- * 2. If there is more than one active ringing call, return the first one
- * 3. If there is no active ringing call, return the ringing call
- * associated with default phone, which state is IDLE.
- * 4. If there is no ringing call at all, return null.
- *
- * Complete ringing calls list can be get by getRingingCalls()
- */
- public Call getFirstActiveRingingCall() {
- Call call = getFirstNonIdleCall(mRingingCalls);
- if (call == null) {
- call = (mDefaultPhone == null)
- ? null
- : mDefaultPhone.getRingingCall();
- }
- return call;
- }
-
- /**
- * @return the state of active foreground call
- * return IDLE if there is no active foreground call
- */
- public Call.State getActiveFgCallState() {
- Call fgCall = getActiveFgCall();
-
- if (fgCall != null) {
- return fgCall.getState();
- }
-
- return Call.State.IDLE;
- }
-
- /**
- * @return the connections of active foreground call
- * return empty list if there is no active foreground call
- */
- public List<Connection> getFgCallConnections() {
- Call fgCall = getActiveFgCall();
- if ( fgCall != null) {
- return fgCall.getConnections();
- }
- return emptyConnections;
- }
-
- /**
- * @return the connections of active background call
- * return empty list if there is no active background call
- */
- public List<Connection> getBgCallConnections() {
- Call bgCall = getFirstActiveBgCall();
- if ( bgCall != null) {
- return bgCall.getConnections();
- }
- return emptyConnections;
- }
-
- /**
- * @return the latest connection of active foreground call
- * return null if there is no active foreground call
- */
- public Connection getFgCallLatestConnection() {
- Call fgCall = getActiveFgCall();
- if ( fgCall != null) {
- return fgCall.getLatestConnection();
- }
- return null;
- }
-
- /**
- * @return true if there is at least one Foreground call in disconnected state
- */
- public boolean hasDisconnectedFgCall() {
- return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED) != null);
- }
-
- /**
- * @return true if there is at least one background call in disconnected state
- */
- public boolean hasDisconnectedBgCall() {
- return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED) != null);
- }
-
- /**
- * @return the first active call from a call list
- */
- private Call getFirstActiveCall(ArrayList<Call> calls) {
- for (Call call : calls) {
- if (!call.isIdle()) {
- return call;
- }
- }
- return null;
- }
-
- /**
- * @return the first call in a the Call.state from a call list
- */
- private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state) {
- for (Call call : calls) {
- if (call.getState() == state) {
- return call;
- }
- }
- return null;
- }
-
-
- private boolean hasMoreThanOneRingingCall() {
- int count = 0;
- for (Call call : mRingingCalls) {
- if (call.getState().isRinging()) {
- if (++count > 1) return true;
- }
- }
- return false;
- }
-
- private Handler mHandler = new Handler() {
-
- @Override
- public void handleMessage(Message msg) {
-
- switch (msg.what) {
- case EVENT_DISCONNECT:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISCONNECT)");
- mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_PRECISE_CALL_STATE_CHANGED:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_PRECISE_CALL_STATE_CHANGED)");
- mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_NEW_RINGING_CONNECTION:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_NEW_RINGING_CONNECTION)");
- if (getActiveFgCallState().isDialing() || hasMoreThanOneRingingCall()) {
- Connection c = (Connection) ((AsyncResult) msg.obj).result;
- try {
- Log.d(LOG_TAG, "silently drop incoming call: " + c.getCall());
- c.getCall().hangup();
- } catch (CallStateException e) {
- Log.w(LOG_TAG, "new ringing connection", e);
- }
- } else {
- mNewRingingConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- }
- break;
- case EVENT_UNKNOWN_CONNECTION:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_UNKNOWN_CONNECTION)");
- mUnknownConnectionRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_INCOMING_RING:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_INCOMING_RING)");
- // The event may come from RIL who's not aware of an ongoing fg call
- if (!hasActiveFgCall()) {
- mIncomingRingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- }
- break;
- case EVENT_RINGBACK_TONE:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RINGBACK_TONE)");
- mRingbackToneRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_IN_CALL_VOICE_PRIVACY_ON:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_ON)");
- mInCallVoicePrivacyOnRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_IN_CALL_VOICE_PRIVACY_OFF:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_IN_CALL_VOICE_PRIVACY_OFF)");
- mInCallVoicePrivacyOffRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_CALL_WAITING:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CALL_WAITING)");
- mCallWaitingRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_DISPLAY_INFO:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_DISPLAY_INFO)");
- mDisplayInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_SIGNAL_INFO:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SIGNAL_INFO)");
- mSignalInfoRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_CDMA_OTA_STATUS_CHANGE:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_CDMA_OTA_STATUS_CHANGE)");
- mCdmaOtaStatusChangeRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_RESEND_INCALL_MUTE:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_RESEND_INCALL_MUTE)");
- mResendIncallMuteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_MMI_INITIATE:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_INITIATE)");
- mMmiInitiateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_MMI_COMPLETE:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_MMI_COMPLETE)");
- mMmiCompleteRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_ECM_TIMER_RESET:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_ECM_TIMER_RESET)");
- mEcmTimerResetRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_SUBSCRIPTION_INFO_READY:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUBSCRIPTION_INFO_READY)");
- mSubscriptionInfoReadyRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_SUPP_SERVICE_FAILED:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SUPP_SERVICE_FAILED)");
- mSuppServiceFailedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_SERVICE_STATE_CHANGED:
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_SERVICE_STATE_CHANGED)");
- mServiceStateChangedRegistrants.notifyRegistrants((AsyncResult) msg.obj);
- break;
- case EVENT_POST_DIAL_CHARACTER:
- // we need send the character that is being processed in msg.arg1
- // so can't use notifyRegistrants()
- if (VDBG) Log.d(LOG_TAG, " handleMessage (EVENT_POST_DIAL_CHARACTER)");
- for(int i=0; i < mPostDialCharacterRegistrants.size(); i++) {
- Message notifyMsg;
- notifyMsg = ((Registrant)mPostDialCharacterRegistrants.get(i)).messageForRegistrant();
- notifyMsg.obj = msg.obj;
- notifyMsg.arg1 = msg.arg1;
- notifyMsg.sendToTarget();
- }
- break;
- }
- }
- };
-
- @Override
- public String toString() {
- Call call;
- StringBuilder b = new StringBuilder();
-
- b.append("CallManager {");
- b.append("\nstate = " + getState());
- call = getActiveFgCall();
- b.append("\n- Foreground: " + getActiveFgCallState());
- b.append(" from " + call.getPhone());
- b.append("\n Conn: ").append(getFgCallConnections());
- call = getFirstActiveBgCall();
- b.append("\n- Background: " + call.getState());
- b.append(" from " + call.getPhone());
- b.append("\n Conn: ").append(getBgCallConnections());
- call = getFirstActiveRingingCall();
- b.append("\n- Ringing: " +call.getState());
- b.append(" from " + call.getPhone());
-
- for (Phone phone : getAllPhones()) {
- if (phone != null) {
- b.append("\nPhone: " + phone + ", name = " + phone.getPhoneName()
- + ", state = " + phone.getState());
- call = phone.getForegroundCall();
- b.append("\n- Foreground: ").append(call);
- call = phone.getBackgroundCall();
- b.append(" Background: ").append(call);
- call = phone.getRingingCall();
- b.append(" Ringing: ").append(call);
- }
- }
- b.append("\n}");
- return b.toString();
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallStateException.java b/telephony/java/com/android/internal/telephony/CallStateException.java
deleted file mode 100644
index 6087124..0000000
--- a/telephony/java/com/android/internal/telephony/CallStateException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public class CallStateException extends Exception
-{
- public
- CallStateException()
- {
- }
-
- public
- CallStateException(String string)
- {
- super(string);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
deleted file mode 100644
index 62caf01..0000000
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandException;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-
-/**
- * {@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 static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14;
- protected static final int EVENT_CALL_WAITING_INFO_CDMA = 15;
- protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16;
-
- 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;
- }
-
- /**
- * Routine called from dial to check if the number is a test Emergency number
- * and if so remap the number. This allows a short emergency number to be remapped
- * to a regular number for testing how the frameworks handles emergency numbers
- * without actually calling an emergency number.
- *
- * This is not a full test and is not a substitute for testing real emergency
- * numbers but can be useful.
- *
- * To use this feature set a system property ril.test.emergencynumber to a pair of
- * numbers separated by a colon. If the first number matches the number parameter
- * this routine returns the second number. Example:
- *
- * ril.test.emergencynumber=112:1-123-123-45678
- *
- * To test Dial 112 take call then hang up on MO device to enter ECM
- * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
- *
- * @param number to test if it should be remapped
- * @return the same number or the remapped number.
- */
- protected String checkForTestEmergencyNumber(String dialString) {
- String testEn = SystemProperties.get("ril.test.emergencynumber");
- if (DBG_POLL) {
- log("checkForTestEmergencyNumber: dialString=" + dialString +
- " testEn=" + testEn);
- }
- if (!TextUtils.isEmpty(testEn)) {
- String values[] = testEn.split(":");
- log("checkForTestEmergencyNumber: values.length=" + values.length);
- if (values.length == 2) {
- if (values[0].equals(
- android.telephony.PhoneNumberUtils.stripSeparators(dialString))) {
- cm.testingEmergencyCall();
- log("checkForTestEmergencyNumber: remap " +
- dialString + " to " + values[1]);
- dialString = values[1];
- }
- }
- }
- return dialString;
- }
-
- //***** Overridden from Handler
- public abstract void handleMessage (Message msg);
- public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj);
- public abstract void unregisterForVoiceCallStarted(Handler h);
- public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj);
- public abstract void unregisterForVoiceCallEnded(Handler h);
-
- protected abstract void log(String msg);
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("CallTracker:");
- pw.println(" pendingOperations=" + pendingOperations);
- pw.println(" needsPoll=" + needsPoll);
- pw.println(" lastRelevantPoll=" + lastRelevantPoll);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java
deleted file mode 100644
index 94c544e..0000000
--- a/telephony/java/com/android/internal/telephony/CommandException.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.RILConstants;
-
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public class CommandException extends RuntimeException {
- private Error e;
-
- public enum Error {
- INVALID_RESPONSE,
- RADIO_NOT_AVAILABLE,
- GENERIC_FAILURE,
- PASSWORD_INCORRECT,
- SIM_PIN2,
- SIM_PUK2,
- REQUEST_NOT_SUPPORTED,
- OP_NOT_ALLOWED_DURING_VOICE_CALL,
- OP_NOT_ALLOWED_BEFORE_REG_NW,
- SMS_FAIL_RETRY,
- SIM_ABSENT,
- SUBSCRIPTION_NOT_AVAILABLE,
- MODE_NOT_SUPPORTED,
- FDN_CHECK_FAILURE,
- ILLEGAL_SIM_OR_ME,
- }
-
- public CommandException(Error e) {
- super(e.toString());
- this.e = e;
- }
-
- public static CommandException
- fromRilErrno(int ril_errno) {
- switch(ril_errno) {
- case RILConstants.SUCCESS: return null;
- case RILConstants.RIL_ERRNO_INVALID_RESPONSE:
- return new CommandException(Error.INVALID_RESPONSE);
- case RILConstants.RADIO_NOT_AVAILABLE:
- return new CommandException(Error.RADIO_NOT_AVAILABLE);
- case RILConstants.GENERIC_FAILURE:
- return new CommandException(Error.GENERIC_FAILURE);
- case RILConstants.PASSWORD_INCORRECT:
- return new CommandException(Error.PASSWORD_INCORRECT);
- case RILConstants.SIM_PIN2:
- return new CommandException(Error.SIM_PIN2);
- case RILConstants.SIM_PUK2:
- return new CommandException(Error.SIM_PUK2);
- 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);
- case RILConstants.OP_NOT_ALLOWED_BEFORE_REG_NW:
- return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW);
- case RILConstants.SMS_SEND_FAIL_RETRY:
- return new CommandException(Error.SMS_FAIL_RETRY);
- case RILConstants.SIM_ABSENT:
- return new CommandException(Error.SIM_ABSENT);
- case RILConstants.SUBSCRIPTION_NOT_AVAILABLE:
- return new CommandException(Error.SUBSCRIPTION_NOT_AVAILABLE);
- case RILConstants.MODE_NOT_SUPPORTED:
- return new CommandException(Error.MODE_NOT_SUPPORTED);
- case RILConstants.FDN_CHECK_FAILURE:
- return new CommandException(Error.FDN_CHECK_FAILURE);
- case RILConstants.ILLEGAL_SIM_OR_ME:
- return new CommandException(Error.ILLEGAL_SIM_OR_ME);
- default:
- Log.e("GSM", "Unrecognized RIL errno " + ril_errno);
- return new CommandException(Error.INVALID_RESPONSE);
- }
- }
-
- public Error getCommandError() {
- return e;
- }
-
-
-
-}
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
deleted file mode 100644
index f7757b3..0000000
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ /dev/null
@@ -1,1579 +0,0 @@
-/*
- * 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 com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-import android.os.Message;
-import android.os.Handler;
-import android.util.Log;
-
-/**
- * {@hide}
- */
-public interface CommandsInterface {
- enum RadioState {
- RADIO_OFF, /* Radio explicitly powered off (eg CFUN=0) */
- RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */
- RADIO_ON; /* Radio is on */
-
- public boolean isOn() /* and available...*/ {
- return this == RADIO_ON;
- }
-
- public boolean isAvailable() {
- return this != RADIO_UNAVAILABLE;
- }
- }
-
- //***** Constants
-
- // Used as parameter to dial() and setCLIR() below
- static final int CLIR_DEFAULT = 0; // "use subscription default value"
- static final int CLIR_INVOCATION = 1; // (restrict CLI presentation)
- static final int CLIR_SUPPRESSION = 2; // (allow CLI presentation)
-
-
- // Used as parameters for call forward methods below
- static final int CF_ACTION_DISABLE = 0;
- static final int CF_ACTION_ENABLE = 1;
-// static final int CF_ACTION_UNUSED = 2;
- static final int CF_ACTION_REGISTRATION = 3;
- static final int CF_ACTION_ERASURE = 4;
-
- static final int CF_REASON_UNCONDITIONAL = 0;
- static final int CF_REASON_BUSY = 1;
- static final int CF_REASON_NO_REPLY = 2;
- static final int CF_REASON_NOT_REACHABLE = 3;
- static final int CF_REASON_ALL = 4;
- static final int CF_REASON_ALL_CONDITIONAL = 5;
-
- // Used for call barring methods below
- static final String CB_FACILITY_BAOC = "AO";
- static final String CB_FACILITY_BAOIC = "OI";
- static final String CB_FACILITY_BAOICxH = "OX";
- static final String CB_FACILITY_BAIC = "AI";
- static final String CB_FACILITY_BAICr = "IR";
- static final String CB_FACILITY_BA_ALL = "AB";
- static final String CB_FACILITY_BA_MO = "AG";
- 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
- static final int SERVICE_CLASS_NONE = 0; // no user input
- static final int SERVICE_CLASS_VOICE = (1 << 0);
- static final int SERVICE_CLASS_DATA = (1 << 1); //synonym 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_ASYNC = (1 << 5);
- static final int SERVICE_CLASS_PACKET = (1 << 6);
- static final int SERVICE_CLASS_PAD = (1 << 7);
- static final int SERVICE_CLASS_MAX = (1 << 7); // Max SERVICE_CLASS value
-
- // Numeric representation of string values returned
- // by messages sent to setOnUSSD handler
- static final int USSD_MODE_NOTIFY = 0;
- static final int USSD_MODE_REQUEST = 1;
-
- // GSM SMS fail cause for acknowledgeLastIncomingSMS. From TS 23.040, 9.2.3.22.
- static final int GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED = 0xD3;
- static final int GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY = 0xD4;
- static final int GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR = 0xD5;
- static final int GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR = 0xFF;
-
- // CDMA SMS fail cause for acknowledgeLastIncomingCdmaSms. From TS N.S0005, 6.5.2.125.
- static final int CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID = 4;
- static final int CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE = 35;
- static final int CDMA_SMS_FAIL_CAUSE_OTHER_TERMINAL_PROBLEM = 39;
- static final int CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM = 96;
-
- //***** Methods
- RadioState getRadioState();
-
- void getVoiceRadioTechnology(Message result);
-
- /**
- * Fires on any RadioState transition
- * Always fires immediately as well
- *
- * do not attempt to calculate transitions by storing getRadioState() values
- * on previous invocations of this notification. Instead, use the other
- * registration methods
- */
- void registerForRadioStateChanged(Handler h, int what, Object obj);
- void unregisterForRadioStateChanged(Handler h);
-
- void registerForVoiceRadioTechChanged(Handler h, int what, Object obj);
- void unregisterForVoiceRadioTechChanged(Handler h);
-
- /**
- * 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 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);
-
- /**
- * 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);
-
- /**
- * 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 unregisterForOffOrNotAvailable(Handler h);
-
- /**
- * Fires on any change in ICC status
- */
- void registerForIccStatusChanged(Handler h, int what, Object obj);
- void unregisterForIccStatusChanged(Handler h);
-
- void registerForCallStateChanged(Handler h, int what, Object obj);
- void unregisterForCallStateChanged(Handler h);
- void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj);
- void unregisterForVoiceNetworkStateChanged(Handler h);
- void registerForDataNetworkStateChanged(Handler h, int what, Object obj);
- void unregisterForDataNetworkStateChanged(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);
-
- /**
- * unlike the register* methods, there's only one new 3GPP format SMS handler.
- * if you need to unregister, you should also tell the radio to stop
- * sending SMS's to you (via AT+CNMI)
- *
- * AsyncResult.result is a String containing the SMS PDU
- */
- void setOnNewGsmSms(Handler h, int what, Object obj);
- void unSetOnNewGsmSms(Handler h);
-
- /**
- * unlike the register* methods, there's only one new 3GPP2 format SMS handler.
- * if you need to unregister, you should also tell the radio to stop
- * sending SMS's to you (via AT+CNMI)
- *
- * AsyncResult.result is a String containing the SMS PDU
- */
- void setOnNewCdmaSms(Handler h, int what, Object obj);
- void unSetOnNewCdmaSms(Handler h);
-
- /**
- * Set the handler for SMS Cell Broadcast messages.
- *
- * AsyncResult.result is a byte array containing the SMS-CB PDU
- */
- void setOnNewGsmBroadcastSms(Handler h, int what, Object obj);
- void unSetOnNewGsmBroadcastSms(Handler h);
-
- /**
- * 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
- *
- * 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
- *
- * AsyncResult.result is an Object[]
- * ((Object[])AsyncResult.result)[0] is a String containing the NITZ time string
- * ((Object[])AsyncResult.result)[1] is a Long containing the milliseconds since boot as
- * returned by elapsedRealtime() when this NITZ time
- * was posted.
- *
- * Please note that the delivery of this message may be delayed several
- * 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]
- * "1" USSD-Request -- text in ((const char **)data)[1]
- * "2" Session terminated by network
- * "3" other local client (eg, SIM Toolkit) has responded
- * "4" Operation not supported
- * "5" Network timeout
- *
- * ((String[])(AsyncResult.result))[1] contains the USSD message
- * The numeric representations of these are in USSD_MODE_*
- */
-
- 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)
- * 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/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 setOnIccSmsFull(Handler h, int what, Object obj);
- void unSetOnIccSmsFull(Handler h);
-
- /**
- * Sets the handler for SIM Refresh notifications.
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForIccRefresh(Handler h, int what, Object obj);
- void unregisterForIccRefresh(Handler h);
-
- 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
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @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
- * unlike the register* methods, there's only one signal strength handler
- *
- * AsyncResult.result is an int[1]
- * response.obj.result[0] is a bitmask of RIL_RESTRICTED_STATE_* values
- */
-
- 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
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void setOnSuppServiceNotification(Handler h, int what, Object obj);
- void unSetOnSuppServiceNotification(Handler h);
-
- /**
- * Sets the handler for Session End Notifications for CAT.
- * 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 setOnCatSessionEnd(Handler h, int what, Object obj);
- void unSetOnCatSessionEnd(Handler h);
-
- /**
- * Sets the handler for Proactive Commands for CAT.
- * 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 setOnCatProactiveCmd(Handler h, int what, Object obj);
- void unSetOnCatProactiveCmd(Handler h);
-
- /**
- * Sets the handler for Event Notifications for CAT.
- * 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 setOnCatEvent(Handler h, int what, Object obj);
- void unSetOnCatEvent(Handler h);
-
- /**
- * Sets the handler for Call Set Up Notifications for CAT.
- * 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 setOnCatCallSetUp(Handler h, int what, Object obj);
- void unSetOnCatCallSetUp(Handler h);
-
- /**
- * Enables/disbables supplementary service related notifications from
- * the network.
- *
- * @param enable true to enable notifications, false to disable.
- * @param result Message to be posted when command completes.
- */
- void setSuppServiceNotifications(boolean enable, Message result);
- //void unSetSuppServiceNotifications(Handler h);
-
- /**
- * Sets the handler for Event Notifications for CDMA Display Info.
- * 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 registerForDisplayInfo(Handler h, int what, Object obj);
- void unregisterForDisplayInfo(Handler h);
-
- /**
- * Sets the handler for Event Notifications for CallWaiting Info.
- * 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 registerForCallWaitingInfo(Handler h, int what, Object obj);
- void unregisterForCallWaitingInfo(Handler h);
-
- /**
- * Sets the handler for Event Notifications for Signal Info.
- * 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 registerForSignalInfo(Handler h, int what, Object obj);
- void unregisterForSignalInfo(Handler h);
-
- /**
- * Registers the handler for CDMA number information record
- * 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 registerForNumberInfo(Handler h, int what, Object obj);
- void unregisterForNumberInfo(Handler h);
-
- /**
- * Registers the handler for CDMA redirected number Information record
- * 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 registerForRedirectedNumberInfo(Handler h, int what, Object obj);
- void unregisterForRedirectedNumberInfo(Handler h);
-
- /**
- * Registers the handler for CDMA line control information record
- * 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 registerForLineControlInfo(Handler h, int what, Object obj);
- void unregisterForLineControlInfo(Handler h);
-
- /**
- * Registers the handler for CDMA T53 CLIR information record
- * 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 registerFoT53ClirlInfo(Handler h, int what, Object obj);
- void unregisterForT53ClirInfo(Handler h);
-
- /**
- * Registers the handler for CDMA T53 audio control information record
- * 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 registerForT53AudioControlInfo(Handler h, int what, Object obj);
- void unregisterForT53AudioControlInfo(Handler h);
-
- /**
- * Fires on if Modem enters Emergency Callback mode
- */
- void setEmergencyCallbackMode(Handler h, int what, Object obj);
-
- /**
- * Fires on any CDMA OTA provision status change
- */
- void registerForCdmaOtaProvision(Handler h,int what, Object obj);
- void unregisterForCdmaOtaProvision(Handler h);
-
- /**
- * Registers the handler when out-band ringback tone is needed.<p>
- *
- * Messages received from this:
- * Message.obj will be an AsyncResult
- * AsyncResult.userObj = obj
- * AsyncResult.result = boolean. <p>
- */
- void registerForRingbackTone(Handler h, int what, Object obj);
- void unregisterForRingbackTone(Handler h);
-
- /**
- * Registers the handler when mute/unmute need to be resent to get
- * uplink audio during a call.<p>
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @param obj User object.
- *
- */
- void registerForResendIncallMute(Handler h, int what, Object obj);
- void unregisterForResendIncallMute(Handler h);
-
- /**
- * Registers the handler for when Cdma subscription changed events
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @param obj User object.
- *
- */
- void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj);
- void unregisterForCdmaSubscriptionChanged(Handler h);
-
- /**
- * Registers the handler for when Cdma prl changed events
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @param obj User object.
- *
- */
- void registerForCdmaPrlChanged(Handler h, int what, Object obj);
- void unregisterForCdmaPrlChanged(Handler h);
-
- /**
- * Registers the handler for when Cdma prl changed events
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @param obj User object.
- *
- */
- void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj);
- void unregisterForExitEmergencyCallbackMode(Handler h);
-
- /**
- * Registers the handler for RIL_UNSOL_RIL_CONNECT events.
- *
- * When ril connects or disconnects a message is sent to the registrant
- * which contains an AsyncResult, ar, in msg.obj. The ar.result is an
- * Integer which is the version of the ril or -1 if the ril disconnected.
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForRilConnected(Handler h, int what, Object obj);
- void unregisterForRilConnected(Handler h);
-
- /**
- * Supply the ICC PIN to the ICC card
- *
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * This exception is CommandException with an error of PASSWORD_INCORRECT
- * if the password is incorrect
- *
- * ar.exception and ar.result are null on success
- */
-
- void supplyIccPin(String pin, Message result);
-
- /**
- * Supply the PIN for the app with this AID on the ICC card
- *
- * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
- *
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * This exception is CommandException with an error of PASSWORD_INCORRECT
- * if the password is incorrect
- *
- * ar.exception and ar.result are null on success
- */
-
- void supplyIccPinForApp(String pin, String aid, Message result);
-
- /**
- * Supply the ICC PUK and newPin to the ICC card
- *
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * This exception is CommandException with an error of PASSWORD_INCORRECT
- * if the password is incorrect
- *
- * ar.exception and ar.result are null on success
- */
-
- void supplyIccPuk(String puk, String newPin, Message result);
-
- /**
- * Supply the PUK, new pin for the app with this AID on the ICC card
- *
- * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
- *
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * This exception is CommandException with an error of PASSWORD_INCORRECT
- * if the password is incorrect
- *
- * ar.exception and ar.result are null on success
- */
-
- void supplyIccPukForApp(String puk, String newPin, String aid, Message result);
-
- /**
- * 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
- * This exception is CommandException with an error of PASSWORD_INCORRECT
- * if the password is incorrect
- *
- * ar.exception and ar.result are null on success
- */
-
- void supplyIccPin2(String pin2, Message result);
-
- /**
- * Supply the PIN2 for the app with this AID on the ICC card
- * Only called following operation where ICC_PIN2 was
- * returned as a a failure from a previous operation
- *
- * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
- *
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * This exception is CommandException with an error of PASSWORD_INCORRECT
- * if the password is incorrect
- *
- * ar.exception and ar.result are null on success
- */
-
- void supplyIccPin2ForApp(String pin2, String aid, 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
- * This exception is CommandException with an error of PASSWORD_INCORRECT
- * if the password is incorrect
- *
- * ar.exception and ar.result are null on success
- */
-
- void supplyIccPuk2(String puk2, String newPin2, Message result);
-
- /**
- * Supply the PUK2, newPin2 for the app with this AID on the ICC card
- * Only called following operation where SIM_PUK2 was
- * returned as a a failure from a previous operation
- *
- * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
- *
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * This exception is CommandException with an error of PASSWORD_INCORRECT
- * if the password is incorrect
- *
- * ar.exception and ar.result are null on success
- */
-
- void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result);
-
- void changeIccPin(String oldPin, String newPin, Message result);
- void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result);
- void changeIccPin2(String oldPin2, String newPin2, Message result);
- void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, 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
- * ar.userObject contains the orignal value of result.obj
- * ar.result contains a List of DriverCall
- * The ar.result List is sorted by DriverCall.index
- */
- 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 DataCallState
- * @deprecated Do not use.
- */
- @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 DataCallState
- */
- void getDataCallList(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 is null on success and failure
- *
- * CLIR_DEFAULT == on "use subscription default value"
- * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
- * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation)
- */
- void dial (String address, int clirMode, 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 is null on success and failure
- *
- * CLIR_DEFAULT == on "use subscription default value"
- * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
- * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation)
- */
- void dial(String address, int clirMode, UUSInfo uusInfo, 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 is String containing IMSI on success
- */
- void getIMSI(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 is String containing IMSI on success
- */
- void getIMSIForApp(String aid, 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 is String containing IMEI on success
- */
- void getIMEI(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 is String containing IMEISV on success
- */
- void getIMEISV(Message result);
-
- /**
- * Hang up one individual connection.
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
- * ar.result is null on success and failure
- *
- * 3GPP 22.030 6.5.5
- * "Releases a specific active call X"
- */
- void hangupConnection (int gsmIndex, Message result);
-
- /**
- * 3GPP 22.030 6.5.5
- * "Releases all held calls or sets User Determined User Busy (UDUB)
- * for a waiting call."
- * ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
- * ar.result is null on success and failure
- */
- void hangupWaitingOrBackground (Message result);
-
- /**
- * 3GPP 22.030 6.5.5
- * "Releases all active calls (if any exist) and accepts
- * the other (held or waiting) call."
- *
- * ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
- * ar.result is null on success and failure
- */
- void hangupForegroundResumeBackground (Message result);
-
- /**
- * 3GPP 22.030 6.5.5
- * "Places all active calls (if any exist) on hold and accepts
- * the other (held or waiting) call."
- *
- * ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
- * ar.result is null on success and failure
- */
- void switchWaitingOrHoldingAndActive (Message result);
-
- /**
- * 3GPP 22.030 6.5.5
- * "Adds a held call to the conversation"
- *
- * 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
- * communication shall be supported."
- */
- void separateConnection (int gsmIndex, Message result);
-
- /**
- *
- * 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);
-
- /**
- * 3GPP 22.030 6.5.5
- * "Connects the two calls and disconnects the subscriber from both calls"
- *
- * ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
- * ar.result is null on success and failure
- */
- void explicitCallTransfer (Message result);
-
- /**
- * cause code returned as int[0] in Message.obj.response
- * Returns integer cause code defined in TS 24.008
- * Annex H or closest approximation.
- * Most significant codes:
- * - Any defined in 22.001 F.4 (for generating busy/congestion)
- * - Cause 68: ACM >= ACMMax
- */
- 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 Do not use.
- */
- @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);
-
- /**
- * 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)
- * as defined in TS 27.007 8.5
- */
- void getSignalStrength (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
- * valid LAC and CIDs are 0x0000 - 0xffff
- *
- * Please note that registration state 4 ("unknown") is treated
- * as "out of service" above
- */
- void getVoiceRegistrationState (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
- * valid LAC and CIDs are 0x0000 - 0xffff
- *
- * Please note that registration state 4 ("unknown") is treated
- * as "out of service" above
- */
- void getDataRegistrationState (Message response);
-
- /**
- * response.obj.result is a String[3]
- * 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);
-
-
- /**
- * ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
- * ar.result is null on success and failure
- */
- void startDtmf(char c, Message result);
-
- /**
- * ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
- * ar.result is null on success and failure
- */
- void stopDtmf(Message result);
-
- /**
- * ar.exception carries exception on failure
- * ar.userObject contains the orignal value of result.obj
- * ar.result is null on success and failure
- */
- void sendBurstDtmf(String dtmfString, int on, int off, Message result);
-
- /**
- * 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
- */
- 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_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
- * any error that may have occurred (eg, out of memory).
- */
- void writeSmsToSim(int status, String smsc, String pdu, Message response);
-
- void writeSmsToRuim(int status, String pdu, Message response);
-
- void setRadioPower(boolean on, Message response);
-
- void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message response);
-
- void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response);
-
- /**
- * Acknowledge successful or failed receipt of last incoming SMS,
- * including acknowledgement TPDU to send as the RP-User-Data element
- * of the RP-ACK or RP-ERROR PDU.
- *
- * @param success true to send RP-ACK, false to send RP-ERROR
- * @param ackPdu the acknowledgement TPDU in hexadecimal format
- * @param response sent when operation completes.
- */
- void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message response);
-
- /**
- * parameters equivalent to 27.007 AT+CRSM command
- * response.obj will be an AsyncResult
- * response.obj.result will be an IccIoResult on success
- */
- void iccIO (int command, int fileid, String path, int p1, int p2, int p3,
- String data, String pin2, Message response);
-
- /**
- * parameters equivalent to 27.007 AT+CRSM command
- * response.obj will be an AsyncResult
- * response.obj.userObj will be a IccIoResult on success
- */
- void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3,
- String data, String pin2, String aid, 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".
- *
- * @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
- *
- * 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
- */
-
- 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.
- *
- * @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_*
- */
- 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,
- String number, Message response);
-
- void setNetworkSelectionModeAutomatic(Message response);
-
- void setNetworkSelectionModeManual(String operatorNumeric, Message response);
-
- /**
- * Queries whether the current network selection mode is automatic
- * or manual
- *
- * ((AsyncResult)response.obj).result is an int[] with element [0] being
- * a 0 for automatic selection and a 1 for manual selection
- */
-
- void getNetworkSelectionMode(Message response);
-
- /**
- * Queries the currently available networks
- *
- * ((AsyncResult)response.obj).result is a List of NetworkInfo objects
- */
- void getAvailableNetworks(Message response);
-
- void getBasebandVersion (Message response);
-
-
- /**
- * (AsyncResult)response.obj).result will be an Integer representing
- * the sum of enabled service classes (sum of SERVICE_CLASS_*)
- *
- * @param facility one of CB_FACILTY_*
- * @param password password or "" if not required
- * @param serviceClass is a sum of SERVICE_CLASS_*
- * @param response is callback message
- */
-
- void queryFacilityLock (String facility, String password, int serviceClass,
- Message response);
-
- /**
- * (AsyncResult)response.obj).result will be an Integer representing
- * the sum of enabled service classes (sum of SERVICE_CLASS_*) for the
- * application with appId.
- *
- * @param facility one of CB_FACILTY_*
- * @param password password or "" if not required
- * @param serviceClass is a sum of SERVICE_CLASS_*
- * @param appId is application Id or null if none
- * @param response is callback message
- */
-
- void queryFacilityLockForApp(String facility, String password, int serviceClass, String appId,
- Message response);
-
- /**
- * @param facility one of CB_FACILTY_*
- * @param lockState true means lock, false means unlock
- * @param password password or "" if not required
- * @param serviceClass is a sum of SERVICE_CLASS_*
- * @param response is callback message
- */
- void setFacilityLock (String facility, boolean lockState, String password,
- int serviceClass, Message response);
-
- /**
- * Set the facility lock for the app with this AID on the ICC card.
- *
- * @param facility one of CB_FACILTY_*
- * @param lockState true means lock, false means unlock
- * @param password password or "" if not required
- * @param serviceClass is a sum of SERVICE_CLASS_*
- * @param appId is application Id or null if none
- * @param response is callback message
- */
- void setFacilityLockForApp(String facility, boolean lockState, String password,
- int serviceClass, String appId, Message response);
-
- void sendUSSD (String ussdString, Message response);
-
- /**
- * Cancels a pending USSD session if one exists.
- * @param response callback message
- */
- void cancelPendingUssd (Message response);
-
- void resetRadio(Message result);
-
- /**
- * Assign a specified band for RF configuration.
- *
- * @param bandMode one of BM_*_BAND
- * @param response is callback message
- */
- void setBandMode (int bandMode, Message response);
-
- /**
- * 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
- */
- void queryAvailableBandMode (Message response);
-
- /**
- * Set the current preferred network type. This will be the last
- * networkType that was passed to setPreferredNetworkType.
- */
- void setCurrentPreferredNetworkType();
-
- /**
- * Requests to set the preferred network type for searching and registering
- * (CS/PS domain, RAT, and operation mode)
- * @param networkType one of NT_*_TYPE
- * @param response is callback message
- */
- void setPreferredNetworkType(int networkType , Message response);
-
- /**
- * Query the preferred network type setting
- *
- * @param response is callback message to report one of NT_*_TYPE
- */
- void getPreferredNetworkType(Message response);
-
- /**
- * Query neighboring cell ids
- *
- * @param response s callback message to cell ids
- */
- void getNeighboringCids(Message response);
-
- /**
- * Request to enable/disable network state change notifications when
- * location information (lac and/or cid) has changed.
- *
- * @param enable true to enable, false to disable
- * @param response callback message
- */
- void setLocationUpdates(boolean enable, Message response);
-
- /**
- * Gets the default SMSC address.
- *
- * @param result Callback message contains the SMSC address.
- */
- void getSmscAddress(Message result);
-
- /**
- * Sets the default SMSC address.
- *
- * @param address new SMSC address
- * @param result Callback message is empty on completion
- */
- void setSmscAddress(String address, Message result);
-
- /**
- * Indicates whether there is storage available for new SMS messages.
- * @param available true if storage is available
- * @param result callback message
- */
- void reportSmsMemoryStatus(boolean available, Message result);
-
- /**
- * Indicates to the vendor ril that StkService is running
- * and is ready to receive RIL_UNSOL_STK_XXXX commands.
- *
- * @param result callback message
- */
- void reportStkServiceIsRunning(Message result);
-
- void invokeOemRilRequestRaw(byte[] data, Message response);
-
- void invokeOemRilRequestStrings(String[] strings, Message response);
-
-
- /**
- * Send TERMINAL RESPONSE to the SIM, after processing a proactive command
- * sent by the SIM.
- *
- * @param contents String containing SAT/USAT response in hexadecimal
- * format starting with first byte of response data. See
- * TS 102 223 for details.
- * @param response Callback message
- */
- public void sendTerminalResponse(String contents, Message response);
-
- /**
- * Send ENVELOPE to the SIM, after processing a proactive command sent by
- * the SIM.
- *
- * @param contents String containing SAT/USAT response in hexadecimal
- * format starting with command tag. See TS 102 223 for
- * details.
- * @param response Callback message
- */
- public void sendEnvelope(String contents, Message response);
-
- /**
- * Send ENVELOPE to the SIM, such as an SMS-PP data download envelope
- * for a SIM data download message. This method has one difference
- * from {@link #sendEnvelope}: The SW1 and SW2 status bytes from the UICC response
- * are returned along with the response data.
- *
- * response.obj will be an AsyncResult
- * response.obj.result will be an IccIoResult on success
- *
- * @param contents String containing SAT/USAT response in hexadecimal
- * format starting with command tag. See TS 102 223 for
- * details.
- * @param response Callback message
- */
- public void sendEnvelopeWithStatus(String contents, Message response);
-
- /**
- * Accept or reject the call setup request from SIM.
- *
- * @param accept true if the call is to be accepted, false otherwise.
- * @param response Callback message
- */
- public void handleCallSetupRequestFromSim(boolean accept, Message response);
-
- /**
- * Activate or deactivate cell broadcast SMS for GSM.
- *
- * @param activate
- * true = activate, false = deactivate
- * @param result Callback message is empty on completion
- */
- public void setGsmBroadcastActivation(boolean activate, Message result);
-
- /**
- * Configure cell broadcast SMS for GSM.
- *
- * @param response Callback message is empty on completion
- */
- public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response);
-
- /**
- * Query the current configuration of cell broadcast SMS of GSM.
- *
- * @param response
- * Callback message contains the configuration from the modem
- * on completion
- */
- public void getGsmBroadcastConfig(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 MDN / H_SID / H_NID / MIN.
- * "response" is const char **
- * [0] is MDN if CDMA subscription is available
- * [1] is a comma separated list of H_SID (Home SID) in decimal format
- * if CDMA subscription is available
- * [2] is a comma separated list of H_NID (Home NID) in decimal format
- * if CDMA subscription is available
- * [3] is MIN (10 digits, MIN2+MIN1) 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 setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response);
-
- /**
- * Requests to get the CDMA subscription srouce
- * @param response is callback message
- */
- void getCdmaSubscriptionSource(Message response);
-
- /**
- * Set the TTY mode
- *
- * @param ttyMode one of the following:
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
- * @param response is callback message
- */
- void setTTYMode(int ttyMode, Message response);
-
- /**
- * Query the TTY mode
- * (AsyncResult)response.obj).result is an int[] with element [0] set to
- * tty mode:
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
- * @param response is callback message
- */
- void queryTTYMode(Message response);
-
- /**
- * Setup a packet data connection On successful completion, the result
- * message will return a {@link DataCallState} object containing the connection
- * information.
- *
- * @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 authType
- * the PAP / CHAP auth type. Values is one of SETUP_DATA_AUTH_*
- * @param protocol
- * one of the PDP_type values in TS 27.007 section 10.1.1.
- * For example, "IP", "IPV6", "IPV4V6", or "PPP".
- * @param result
- * Callback message
- */
- public void setupDataCall(String radioTechnology, String profile,
- String apn, String user, String password, String authType,
- String protocol, Message result);
-
- /**
- * Deactivate packet data connection
- *
- * @param cid
- * The connection ID
- * @param reason
- * Data disconnect reason.
- * @param result
- * Callback message is empty on completion
- */
- public void deactivateDataCall(int cid, int reason, Message result);
-
- /**
- * Activate or deactivate cell broadcast SMS for CDMA.
- *
- * @param activate
- * true = activate, false = deactivate
- * @param result
- * Callback message is empty on completion
- */
- public void setCdmaBroadcastActivation(boolean activate, Message result);
-
- /**
- * Configure cdma cell broadcast SMS.
- *
- * @param result
- * Callback message is empty on completion
- */
- // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
- 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);
-
- /**
- * Requests the radio's system selection module to exit emergency callback mode.
- * This function should only be called from CDMAPHone.java.
- *
- * @param response callback message
- */
- public void exitEmergencyCallbackMode(Message response);
-
- /**
- * Request the status of the ICC and UICC cards.
- *
- * @param result
- * Callback message containing {@link IccCardStatus} structure for the card.
- */
- public void getIccCardStatus(Message result);
-
- /**
- * Return if the current radio is LTE on CDMA. This
- * is a tri-state return value as for a period of time
- * the mode may be unknown.
- *
- * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
- * or {@link Phone#LTE_ON_CDMA_TRUE}
- */
- public int getLteOnCdmaMode();
-
- /**
- * Request the ISIM application on the UICC to perform the AKA
- * challenge/response algorithm for IMS authentication. The nonce string
- * and challenge response are Base64 encoded Strings.
- *
- * @param nonce the nonce string to pass with the ISIM authentication request
- * @param response a callback message with the String response in the obj field
- */
- public void requestIsimAuthentication(String nonce, Message response);
-
- /**
- * Notifiy that we are testing an emergency call
- */
- public void testingEmergencyCall();
-}
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
deleted file mode 100644
index 07f90cd..0000000
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * 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.util.Log;
-
-/**
- * {@hide}
- */
-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
- public static int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network
- public static int PRESENTATION_PAYPHONE = 4; // show pay phone info
-
- private static String LOG_TAG = "TelephonyConnection";
-
- public enum DisconnectCause {
- NOT_DISCONNECTED, /* has not yet disconnected */
- INCOMING_MISSED, /* an incoming call that was missed and never answered */
- NORMAL, /* normal; remote */
- LOCAL, /* normal; local hangup */
- BUSY, /* outgoing call to busy line */
- CONGESTION, /* outgoing call to congested network */
- MMI, /* not presently used; dial() returns null */
- INVALID_NUMBER, /* invalid dial string */
- NUMBER_UNREACHABLE, /* cannot reach the peer */
- SERVER_UNREACHABLE, /* cannot reach the server */
- INVALID_CREDENTIALS, /* invalid credentials */
- OUT_OF_NETWORK, /* calling from out of network is not allowed */
- SERVER_ERROR, /* server error */
- TIMED_OUT, /* client timed out */
- LOST_SIGNAL,
- LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */
- INCOMING_REJECTED, /* an incoming call that was rejected */
- POWER_OFF, /* radio is turned off explicitly */
- OUT_OF_SERVICE, /* out of service */
- ICC_ERROR, /* No ICC, ICC locked, or other ICC error */
- CALL_BARRED, /* call was blocked by call barring */
- FDN_BLOCKED, /* call was blocked by fixed dial number */
- CS_RESTRICTED, /* call was blocked by restricted all voice access */
- CS_RESTRICTED_NORMAL, /* call was blocked by restricted normal voice access */
- CS_RESTRICTED_EMERGENCY, /* call was blocked by restricted emergency voice access */
- UNOBTAINABLE_NUMBER, /* Unassigned number (3GPP TS 24.008 table 10.5.123) */
- CDMA_LOCKED_UNTIL_POWER_CYCLE, /* MS is locked until next power cycle */
- CDMA_DROP,
- CDMA_INTERCEPT, /* INTERCEPT order received, MS state idle entered */
- CDMA_REORDER, /* MS has been redirected, call is cancelled */
- CDMA_SO_REJECT, /* service option rejection */
- CDMA_RETRY_ORDER, /* requested service is rejected, retry delay is set */
- CDMA_ACCESS_FAILURE,
- CDMA_PREEMPTED,
- CDMA_NOT_EMERGENCY, /* not an emergency call */
- CDMA_ACCESS_BLOCKED, /* Access Blocked by CDMA network */
- ERROR_UNSPECIFIED
- }
-
- Object userData;
-
- /* Instance Methods */
-
- /**
- * Gets address (e.g. phone number) associated with connection.
- * TODO: distinguish reasons for unavailability
- *
- * @return address or null if unavailable
- */
-
- public abstract String getAddress();
-
- /**
- * Gets CDMA CNAP name associated with connection.
- * @return cnap name or null if unavailable
- */
- public String getCnapName() {
- return null;
- }
-
- /**
- * Get original dial string.
- * @return original dial string or null if unavailable
- */
- public String getOrigDialString(){
- return null;
- }
-
- /**
- * Gets CDMA CNAP presentation associated with connection.
- * @return cnap name or null if unavailable
- */
-
- public int getCnapNamePresentation() {
- return 0;
- };
-
- /**
- * @return Call that owns this Connection, or null if none
- */
- public abstract Call getCall();
-
- /**
- * Connection create time in currentTimeMillis() format
- * Basically, set when object is created.
- * Effectively, when an incoming call starts ringing or an
- * outgoing call starts dialing
- */
- public abstract long getCreateTime();
-
- /**
- * Connection connect time in currentTimeMillis() format.
- * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition.
- * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition.
- * Returns 0 before then.
- */
- public abstract long getConnectTime();
-
- /**
- * Disconnect time in currentTimeMillis() format.
- * The time when this Connection makes a transition into ENDED or FAIL.
- * Returns 0 before then.
- */
- public abstract long getDisconnectTime();
-
- /**
- * 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.
- */
- public abstract long getDurationMillis();
-
- /**
- * If this connection is HOLDING, return the number of milliseconds
- * that it has been on hold for (approximately).
- * If this connection is in any other state, return 0.
- */
-
- public abstract long getHoldDurationMillis();
-
- /**
- * Returns "NOT_DISCONNECTED" if not yet disconnected.
- */
- public abstract DisconnectCause getDisconnectCause();
-
- /**
- * 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();
-
- /**
- * 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() {
- Call c;
-
- c = getCall();
-
- 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() {
- return getState().isAlive();
- }
-
- /**
- * Returns true if Connection is connected and is INCOMING or WAITING
- */
- public boolean
- isRinging() {
- return getState().isRinging();
- }
-
- /**
- *
- * @return the userdata set in setUserData()
- */
- public Object getUserData() {
- return userData;
- }
-
- /**
- *
- * @param userdata user can store an any userdata in the Connection object.
- */
- public void setUserData(Object userdata) {
- this.userData = userdata;
- }
-
- /**
- * Hangup individual Connection
- */
- public abstract void hangup() throws CallStateException;
-
- /**
- * Separate this call from its owner Call and assigns it to a new Call
- * (eg if it is currently part of a Conference call
- * TODO: Throw exception? Does GSM require error display on failure here?
- */
- 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
- 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
- call to proceedAfterWaitChar() */
- 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
- with cancelPostDial() */
- PAUSE /* The post dial string playback is pausing for a
- call to processNextPostDialChar*/
- }
-
- public void clearUserData(){
- userData = null;
- }
-
- public abstract PostDialState getPostDialState();
-
- /**
- * Returns the portion of the post dial string that has not
- * yet been dialed, or "" if none
- */
- public abstract String getRemainingPostDialString();
-
- /**
- * See Phone.setOnPostDialWaitCharacter()
- */
-
- public abstract void proceedAfterWaitChar();
-
- /**
- * See Phone.setOnPostDialWildCharacter()
- */
- public abstract void proceedAfterWildChar(String str);
- /**
- * Cancel any post
- */
- public abstract void cancelPostDial();
-
- /**
- * Returns the caller id presentation type for incoming and waiting calls
- * @return one of PRESENTATION_*
- */
- public abstract int getNumberPresentation();
-
- /**
- * Returns the User to User Signaling (UUS) information associated with
- * incoming and waiting calls
- * @return UUSInfo containing the UUS userdata.
- */
- public abstract UUSInfo getUUSInfo();
-
- /**
- * Build a human representation of a connection instance, suitable for debugging.
- * Don't log personal stuff unless in debug mode.
- * @return a string representing the internal state of this connection.
- */
- public String toString() {
- StringBuilder str = new StringBuilder(128);
-
- if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
- str.append("addr: " + getAddress())
- .append(" pres.: " + getNumberPresentation())
- .append(" dial: " + getOrigDialString())
- .append(" postdial: " + getRemainingPostDialString())
- .append(" cnap name: " + getCnapName())
- .append("(" + getCnapNamePresentation() + ")");
- }
- str.append(" incoming: " + isIncoming())
- .append(" state: " + getState())
- .append(" post dial state: " + getPostDialState());
- return str.toString();
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
deleted file mode 100644
index efbf608..0000000
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved.
- * Copyright (C) 2009 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.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkUtils;
-import android.net.RouteInfo;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.DataConnection.FailCause;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * This is RIL_Data_Call_Response_v5 from ril.h
- * TODO: Rename to DataCallResponse.
- */
-public class DataCallState {
- private final boolean DBG = true;
- private final String LOG_TAG = "GSM";
-
- public int version = 0;
- public int status = 0;
- public int cid = 0;
- public int active = 0;
- public String type = "";
- public String ifname = "";
- public String [] addresses = new String[0];
- public String [] dnses = new String[0];
- public String[] gateways = new String[0];
- public int suggestedRetryTime = -1;
-
- /**
- * Class returned by onSetupConnectionCompleted.
- */
- public enum SetupResult {
- SUCCESS,
- ERR_BadCommand,
- ERR_UnacceptableParameter,
- ERR_GetLastErrorFromRil,
- ERR_Stale,
- ERR_RilError;
-
- public FailCause mFailCause;
-
- SetupResult() {
- mFailCause = FailCause.fromInt(0);
- }
-
- @Override
- public String toString() {
- return name() + " SetupResult.mFailCause=" + mFailCause;
- }
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("DataCallState: {")
- .append("version=").append(version)
- .append(" status=").append(status)
- .append(" retry=").append(suggestedRetryTime)
- .append(" cid=").append(cid)
- .append(" active=").append(active)
- .append(" type=").append(type)
- .append("' ifname='").append(ifname);
- sb.append("' addresses=[");
- for (String addr : addresses) {
- sb.append(addr);
- sb.append(",");
- }
- if (addresses.length > 0) sb.deleteCharAt(sb.length()-1);
- sb.append("] dnses=[");
- for (String addr : dnses) {
- sb.append(addr);
- sb.append(",");
- }
- if (dnses.length > 0) sb.deleteCharAt(sb.length()-1);
- sb.append("] gateways=[");
- for (String addr : gateways) {
- sb.append(addr);
- sb.append(",");
- }
- if (gateways.length > 0) sb.deleteCharAt(sb.length()-1);
- sb.append("]}");
- return sb.toString();
- }
-
- public SetupResult setLinkProperties(LinkProperties linkProperties,
- boolean okToUseSystemPropertyDns) {
- SetupResult result;
-
- // Start with clean network properties and if we have
- // a failure we'll clear again at the bottom of this code.
- if (linkProperties == null)
- linkProperties = new LinkProperties();
- else
- linkProperties.clear();
-
- if (status == FailCause.NONE.getErrorCode()) {
- String propertyPrefix = "net." + ifname + ".";
-
- try {
- // set interface name
- linkProperties.setInterfaceName(ifname);
-
- // set link addresses
- if (addresses != null && addresses.length > 0) {
- for (String addr : addresses) {
- addr = addr.trim();
- if (addr.isEmpty()) continue;
- LinkAddress la;
- int addrPrefixLen;
-
- String [] ap = addr.split("/");
- if (ap.length == 2) {
- addr = ap[0];
- addrPrefixLen = Integer.parseInt(ap[1]);
- } else {
- addrPrefixLen = 0;
- }
- InetAddress ia;
- try {
- ia = NetworkUtils.numericToInetAddress(addr);
- } catch (IllegalArgumentException e) {
- throw new UnknownHostException("Non-numeric ip addr=" + addr);
- }
- if (! ia.isAnyLocalAddress()) {
- if (addrPrefixLen == 0) {
- // Assume point to point
- addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128;
- }
- if (DBG) Log.d(LOG_TAG, "addr/pl=" + addr + "/" + addrPrefixLen);
- la = new LinkAddress(ia, addrPrefixLen);
- linkProperties.addLinkAddress(la);
- }
- }
- } else {
- throw new UnknownHostException("no address for ifname=" + ifname);
- }
-
- // set dns servers
- if (dnses != null && dnses.length > 0) {
- for (String addr : dnses) {
- addr = addr.trim();
- if (addr.isEmpty()) continue;
- InetAddress ia;
- try {
- ia = NetworkUtils.numericToInetAddress(addr);
- } catch (IllegalArgumentException e) {
- throw new UnknownHostException("Non-numeric dns addr=" + addr);
- }
- if (! ia.isAnyLocalAddress()) {
- linkProperties.addDns(ia);
- }
- }
- } else if (okToUseSystemPropertyDns){
- String dnsServers[] = new String[2];
- dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
- dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
- for (String dnsAddr : dnsServers) {
- dnsAddr = dnsAddr.trim();
- if (dnsAddr.isEmpty()) continue;
- InetAddress ia;
- try {
- ia = NetworkUtils.numericToInetAddress(dnsAddr);
- } catch (IllegalArgumentException e) {
- throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr);
- }
- if (! ia.isAnyLocalAddress()) {
- linkProperties.addDns(ia);
- }
- }
- } else {
- throw new UnknownHostException("Empty dns response and no system default dns");
- }
-
- // set gateways
- if ((gateways == null) || (gateways.length == 0)) {
- String sysGateways = SystemProperties.get(propertyPrefix + "gw");
- if (sysGateways != null) {
- gateways = sysGateways.split(" ");
- } else {
- gateways = new String[0];
- }
- }
- for (String addr : gateways) {
- addr = addr.trim();
- if (addr.isEmpty()) continue;
- InetAddress ia;
- try {
- ia = NetworkUtils.numericToInetAddress(addr);
- } catch (IllegalArgumentException e) {
- throw new UnknownHostException("Non-numeric gateway addr=" + addr);
- }
- if (! ia.isAnyLocalAddress()) {
- linkProperties.addRoute(new RouteInfo(ia));
- }
- }
-
- result = SetupResult.SUCCESS;
- } catch (UnknownHostException e) {
- Log.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e);
- e.printStackTrace();
- result = SetupResult.ERR_UnacceptableParameter;
- }
- } else {
- if (version < 4) {
- result = SetupResult.ERR_GetLastErrorFromRil;
- } else {
- result = SetupResult.ERR_RilError;
- }
- }
-
- // An error occurred so clear properties
- if (result != SetupResult.SUCCESS) {
- if(DBG) {
- Log.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " +
- "status=" + status + " result=" + result);
- }
- linkProperties.clear();
- }
-
- return result;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
deleted file mode 100644
index 3f7e71e3..0000000
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ /dev/null
@@ -1,1269 +0,0 @@
-/*
- * 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 com.android.internal.telephony.DataCallState.SetupResult;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import android.app.PendingIntent;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.ProxyProperties;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.TimeUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * {@hide}
- *
- * DataConnection StateMachine.
- *
- * This is an abstract base class for representing a single data connection.
- * Instances of this class such as <code>CdmaDataConnection</code> and
- * <code>GsmDataConnection</code>, * represent a connection via the cellular network.
- * There may be multiple data connections and all of them are managed by the
- * <code>DataConnectionTracker</code>.
- *
- * Instances are asynchronous state machines and have two primary entry points
- * <code>connect()</code> and <code>disconnect</code>. The message a parameter will be returned
- * hen the operation completes. The <code>msg.obj</code> will contain an AsyncResult
- * object and <code>AsyncResult.userObj</code> is the original <code>msg.obj</code>. if successful
- * with the <code>AsyncResult.result == null</code> and <code>AsyncResult.exception == null</code>.
- * If an error <code>AsyncResult.result = FailCause</code> and
- * <code>AsyncResult.exception = new Exception()</code>.
- *
- * The other public methods are provided for debugging.
- */
-public abstract class DataConnection extends StateMachine {
- protected static final boolean DBG = true;
- protected static final boolean VDBG = false;
-
- protected static Object mCountLock = new Object();
- protected static int mCount;
- protected AsyncChannel mAc;
-
- protected List<ApnContext> mApnList = null;
- PendingIntent mReconnectIntent = null;
-
- private DataConnectionTracker mDataConnectionTracker = null;
-
- /**
- * Used internally for saving connecting parameters.
- */
- protected static class ConnectionParams {
- public ConnectionParams(ApnSetting apn, Message onCompletedMsg) {
- this.apn = apn;
- this.onCompletedMsg = onCompletedMsg;
- }
-
- public int tag;
- public ApnSetting apn;
- public Message onCompletedMsg;
- }
-
- /**
- * Used internally for saving disconnecting parameters.
- */
- protected static class DisconnectParams {
- public DisconnectParams(String reason, Message onCompletedMsg) {
- this.reason = reason;
- this.onCompletedMsg = onCompletedMsg;
- }
- public int tag;
- public String reason;
- public Message onCompletedMsg;
- }
-
- /**
- * Returned as the reason for a connection failure as defined
- * by RIL_DataCallFailCause in ril.h and some local errors.
- */
- public enum FailCause {
- NONE(0),
-
- // This series of errors as specified by the standards
- // specified in ril.h
- OPERATOR_BARRED(0x08),
- INSUFFICIENT_RESOURCES(0x1A),
- MISSING_UNKNOWN_APN(0x1B),
- UNKNOWN_PDP_ADDRESS_TYPE(0x1C),
- USER_AUTHENTICATION(0x1D),
- ACTIVATION_REJECT_GGSN(0x1E),
- ACTIVATION_REJECT_UNSPECIFIED(0x1F),
- SERVICE_OPTION_NOT_SUPPORTED(0x20),
- SERVICE_OPTION_NOT_SUBSCRIBED(0x21),
- SERVICE_OPTION_OUT_OF_ORDER(0x22),
- NSAPI_IN_USE(0x23),
- ONLY_IPV4_ALLOWED(0x32),
- ONLY_IPV6_ALLOWED(0x33),
- ONLY_SINGLE_BEARER_ALLOWED(0x34),
- PROTOCOL_ERRORS(0x6F),
-
- // Local errors generated by Vendor RIL
- // specified in ril.h
- REGISTRATION_FAIL(-1),
- GPRS_REGISTRATION_FAIL(-2),
- SIGNAL_LOST(-3),
- PREF_RADIO_TECH_CHANGED(-4),
- RADIO_POWER_OFF(-5),
- TETHERED_CALL_ACTIVE(-6),
- ERROR_UNSPECIFIED(0xFFFF),
-
- // Errors generated by the Framework
- // specified here
- UNKNOWN(0x10000),
- RADIO_NOT_AVAILABLE(0x10001),
- UNACCEPTABLE_NETWORK_PARAMETER(0x10002),
- CONNECTION_TO_DATACONNECTIONAC_BROKEN(0x10003);
-
- private final int mErrorCode;
- private static final HashMap<Integer, FailCause> sErrorCodeToFailCauseMap;
- static {
- sErrorCodeToFailCauseMap = new HashMap<Integer, FailCause>();
- for (FailCause fc : values()) {
- sErrorCodeToFailCauseMap.put(fc.getErrorCode(), fc);
- }
- }
-
- FailCause(int errorCode) {
- mErrorCode = errorCode;
- }
-
- int getErrorCode() {
- return mErrorCode;
- }
-
- public boolean isPermanentFail() {
- return (this == OPERATOR_BARRED) || (this == MISSING_UNKNOWN_APN) ||
- (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) ||
- (this == SERVICE_OPTION_NOT_SUPPORTED) ||
- (this == SERVICE_OPTION_NOT_SUBSCRIBED) || (this == NSAPI_IN_USE) ||
- (this == PROTOCOL_ERRORS);
- }
-
- public boolean isEventLoggable() {
- return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) ||
- (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) ||
- (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
- (this == SERVICE_OPTION_NOT_SUBSCRIBED) ||
- (this == SERVICE_OPTION_NOT_SUPPORTED) ||
- (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) ||
- (this == PROTOCOL_ERRORS) ||
- (this == UNACCEPTABLE_NETWORK_PARAMETER);
- }
-
- public static FailCause fromInt(int errorCode) {
- FailCause fc = sErrorCodeToFailCauseMap.get(errorCode);
- if (fc == null) {
- fc = UNKNOWN;
- }
- return fc;
- }
- }
-
- public static class CallSetupException extends Exception {
- private int mRetryOverride = -1;
-
- CallSetupException (int retryOverride) {
- mRetryOverride = retryOverride;
- }
-
- public int getRetryOverride() {
- return mRetryOverride;
- }
- }
-
- // ***** Event codes for driving the state machine
- protected static final int BASE = Protocol.BASE_DATA_CONNECTION;
- protected static final int EVENT_CONNECT = BASE + 0;
- protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1;
- protected static final int EVENT_GET_LAST_FAIL_DONE = BASE + 2;
- protected static final int EVENT_DEACTIVATE_DONE = BASE + 3;
- protected static final int EVENT_DISCONNECT = BASE + 4;
- protected static final int EVENT_RIL_CONNECTED = BASE + 5;
- protected static final int EVENT_DISCONNECT_ALL = BASE + 6;
-
- private static final int CMD_TO_STRING_COUNT = EVENT_DISCONNECT_ALL - BASE + 1;
- private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
- static {
- sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT";
- sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] =
- "EVENT_SETUP_DATA_CONNECTION_DONE";
- sCmdToString[EVENT_GET_LAST_FAIL_DONE - BASE] = "EVENT_GET_LAST_FAIL_DONE";
- sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE";
- sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT";
- sCmdToString[EVENT_RIL_CONNECTED - BASE] = "EVENT_RIL_CONNECTED";
- sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL";
- }
- protected static String cmdToString(int cmd) {
- cmd -= BASE;
- if ((cmd >= 0) && (cmd < sCmdToString.length)) {
- return sCmdToString[cmd];
- } else {
- return null;
- }
- }
-
- //***** Tag IDs for EventLog
- protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
-
- //***** Member Variables
- protected ApnSetting mApn;
- protected int mTag;
- protected PhoneBase phone;
- protected int mRilVersion = -1;
- protected int cid;
- protected LinkProperties mLinkProperties = new LinkProperties();
- protected LinkCapabilities mCapabilities = new LinkCapabilities();
- protected long createTime;
- protected long lastFailTime;
- protected FailCause lastFailCause;
- protected int mRetryOverride = -1;
- protected static final String NULL_IP = "0.0.0.0";
- protected int mRefCount;
- Object userData;
-
- //***** Abstract methods
- @Override
- public abstract String toString();
-
- protected abstract void onConnect(ConnectionParams cp);
-
- protected abstract boolean isDnsOk(String[] domainNameServers);
-
- protected abstract void log(String s);
-
-
- //***** Constructor
- protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm,
- DataConnectionTracker dct) {
- super(name);
- setProcessedMessagesSize(100);
- if (DBG) log("DataConnection constructor E");
- this.phone = phone;
- this.mDataConnectionTracker = dct;
- mId = id;
- mRetryMgr = rm;
- this.cid = -1;
-
- setDbg(false);
- addState(mDefaultState);
- addState(mInactiveState, mDefaultState);
- addState(mActivatingState, mDefaultState);
- addState(mActiveState, mDefaultState);
- addState(mDisconnectingState, mDefaultState);
- addState(mDisconnectingErrorCreatingConnection, mDefaultState);
- setInitialState(mInactiveState);
-
- mApnList = new ArrayList<ApnContext>();
- if (DBG) log("DataConnection constructor X");
- }
-
- /**
- * TearDown the data connection.
- *
- * @param o will be returned in AsyncResult.userObj
- * and is either a DisconnectParams or ConnectionParams.
- */
- private void tearDownData(Object o) {
- int discReason = RILConstants.DEACTIVATE_REASON_NONE;
- if ((o != null) && (o instanceof DisconnectParams)) {
- DisconnectParams dp = (DisconnectParams)o;
- Message m = dp.onCompletedMsg;
- if (TextUtils.equals(dp.reason, Phone.REASON_RADIO_TURNED_OFF)) {
- discReason = RILConstants.DEACTIVATE_REASON_RADIO_OFF;
- } else if (TextUtils.equals(dp.reason, Phone.REASON_PDP_RESET)) {
- discReason = RILConstants.DEACTIVATE_REASON_PDP_RESET;
- }
- }
- if (phone.mCM.getRadioState().isOn()) {
- if (DBG) log("tearDownData radio is on, call deactivateDataCall");
- phone.mCM.deactivateDataCall(cid, discReason, obtainMessage(EVENT_DEACTIVATE_DONE, o));
- } else {
- if (DBG) log("tearDownData radio is off sendMessage EVENT_DEACTIVATE_DONE immediately");
- AsyncResult ar = new AsyncResult(o, null, null);
- sendMessage(obtainMessage(EVENT_DEACTIVATE_DONE, ar));
- }
- }
-
- /**
- * Send the connectionCompletedMsg.
- *
- * @param cp is the ConnectionParams
- * @param cause
- */
- private void notifyConnectCompleted(ConnectionParams cp, FailCause cause) {
- Message connectionCompletedMsg = cp.onCompletedMsg;
- if (connectionCompletedMsg == null) {
- return;
- }
-
- long timeStamp = System.currentTimeMillis();
- connectionCompletedMsg.arg1 = cid;
-
- if (cause == FailCause.NONE) {
- createTime = timeStamp;
- AsyncResult.forMessage(connectionCompletedMsg);
- } else {
- lastFailCause = cause;
- lastFailTime = timeStamp;
- AsyncResult.forMessage(connectionCompletedMsg, cause,
- new CallSetupException(mRetryOverride));
- }
- if (DBG) log("notifyConnectionCompleted at " + timeStamp + " cause=" + cause);
-
- connectionCompletedMsg.sendToTarget();
- }
-
- /**
- * Send ar.userObj if its a message, which is should be back to originator.
- *
- * @param dp is the DisconnectParams.
- */
- private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) {
- if (VDBG) log("NotifyDisconnectCompleted");
-
- ApnContext alreadySent = null;
- String reason = null;
-
- if (dp.onCompletedMsg != null) {
- // Get ApnContext, but only valid on GSM devices this is a string on CDMA devices.
- Message msg = dp.onCompletedMsg;
- if (msg.obj instanceof ApnContext) {
- alreadySent = (ApnContext)msg.obj;
- }
- reason = dp.reason;
- if (VDBG) {
- log(String.format("msg=%s msg.obj=%s", msg.toString(),
- ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
- }
- AsyncResult.forMessage(msg);
- msg.sendToTarget();
- }
- if (sendAll) {
- for (ApnContext a : mApnList) {
- if (a == alreadySent) continue;
- if (reason != null) a.setReason(reason);
- Message msg = mDataConnectionTracker.obtainMessage(
- DataConnectionTracker.EVENT_DISCONNECT_DONE, a);
- AsyncResult.forMessage(msg);
- msg.sendToTarget();
- }
- }
-
- if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
- }
-
- protected int getRilRadioTechnology(int defaultRilRadioTechnology) {
- int rilRadioTechnology;
- if (mRilVersion < 6) {
- rilRadioTechnology = defaultRilRadioTechnology;
- } else {
- rilRadioTechnology = phone.getServiceState().getRilRadioTechnology() + 2;
- }
- return rilRadioTechnology;
- }
-
- /*
- * **************************************************************************
- * Begin Members and methods owned by DataConnectionTracker but stored
- * in a DataConnection because there is one per connection.
- * **************************************************************************
- */
-
- /*
- * The id is owned by DataConnectionTracker.
- */
- private int mId;
-
- /**
- * Get the DataConnection ID
- */
- public int getDataConnectionId() {
- return mId;
- }
-
- /*
- * The retry manager is currently owned by the DataConnectionTracker but is stored
- * in the DataConnection because there is one per connection. These methods
- * should only be used by the DataConnectionTracker although someday the retrying
- * maybe managed by the DataConnection itself and these methods could disappear.
- */
- private RetryManager mRetryMgr;
-
- /**
- * @return retry manager retryCount
- */
- public int getRetryCount() {
- return mRetryMgr.getRetryCount();
- }
-
- /**
- * set retry manager retryCount
- */
- public void setRetryCount(int retryCount) {
- if (DBG) log("setRetryCount: " + retryCount);
- mRetryMgr.setRetryCount(retryCount);
- }
-
- /**
- * @return retry manager retryTimer
- */
- public int getRetryTimer() {
- return mRetryMgr.getRetryTimer();
- }
-
- /**
- * increaseRetryCount of retry manager
- */
- public void increaseRetryCount() {
- mRetryMgr.increaseRetryCount();
- }
-
- /**
- * @return retry manager isRetryNeeded
- */
- public boolean isRetryNeeded() {
- return mRetryMgr.isRetryNeeded();
- }
-
- /**
- * resetRetryCount of retry manager
- */
- public void resetRetryCount() {
- mRetryMgr.resetRetryCount();
- }
-
- /**
- * set retryForeverUsingLasttimeout of retry manager
- */
- public void retryForeverUsingLastTimeout() {
- mRetryMgr.retryForeverUsingLastTimeout();
- }
-
- /**
- * @return retry manager isRetryForever
- */
- public boolean isRetryForever() {
- return mRetryMgr.isRetryForever();
- }
-
- /**
- * @return whether the retry config is set successfully or not
- */
- public boolean configureRetry(int maxRetryCount, int retryTime, int randomizationTime) {
- return mRetryMgr.configure(maxRetryCount, retryTime, randomizationTime);
- }
-
- /**
- * @return whether the retry config is set successfully or not
- */
- public boolean configureRetry(String configStr) {
- return mRetryMgr.configure(configStr);
- }
-
- /*
- * **************************************************************************
- * End members owned by DataConnectionTracker
- * **************************************************************************
- */
-
- /**
- * Clear all settings called when entering mInactiveState.
- */
- protected void clearSettings() {
- if (DBG) log("clearSettings");
-
- createTime = -1;
- lastFailTime = -1;
- lastFailCause = FailCause.NONE;
- mRetryOverride = -1;
- mRefCount = 0;
- cid = -1;
-
- mLinkProperties = new LinkProperties();
- mApn = null;
- }
-
- /**
- * Process setup completion.
- *
- * @param ar is the result
- * @return SetupResult.
- */
- private DataCallState.SetupResult onSetupConnectionCompleted(AsyncResult ar) {
- DataCallState response = (DataCallState) ar.result;
- ConnectionParams cp = (ConnectionParams) ar.userObj;
- DataCallState.SetupResult result;
-
- if (ar.exception != null) {
- if (DBG) {
- log("onSetupConnectionCompleted failed, ar.exception=" + ar.exception +
- " response=" + response);
- }
-
- if (ar.exception instanceof CommandException
- && ((CommandException) (ar.exception)).getCommandError()
- == CommandException.Error.RADIO_NOT_AVAILABLE) {
- result = DataCallState.SetupResult.ERR_BadCommand;
- result.mFailCause = FailCause.RADIO_NOT_AVAILABLE;
- } else if ((response == null) || (response.version < 4)) {
- result = DataCallState.SetupResult.ERR_GetLastErrorFromRil;
- } else {
- result = DataCallState.SetupResult.ERR_RilError;
- result.mFailCause = FailCause.fromInt(response.status);
- }
- } else if (cp.tag != mTag) {
- if (DBG) {
- log("BUG: onSetupConnectionCompleted is stale cp.tag=" + cp.tag + ", mtag=" + mTag);
- }
- result = DataCallState.SetupResult.ERR_Stale;
- } else if (response.status != 0) {
- result = DataCallState.SetupResult.ERR_RilError;
- result.mFailCause = FailCause.fromInt(response.status);
- } else {
- if (DBG) log("onSetupConnectionCompleted received DataCallState: " + response);
- cid = response.cid;
- result = updateLinkProperty(response).setupResult;
- }
-
- return result;
- }
-
- private int getSuggestedRetryTime(AsyncResult ar) {
- int retry = -1;
- if (ar.exception == null) {
- DataCallState response = (DataCallState) ar.result;
- retry = response.suggestedRetryTime;
- }
- return retry;
- }
-
- private DataCallState.SetupResult setLinkProperties(DataCallState response,
- LinkProperties lp) {
- // Check if system property dns usable
- boolean okToUseSystemPropertyDns = false;
- String propertyPrefix = "net." + response.ifname + ".";
- String dnsServers[] = new String[2];
- dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
- dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
- okToUseSystemPropertyDns = isDnsOk(dnsServers);
-
- // set link properties based on data call response
- return response.setLinkProperties(lp, okToUseSystemPropertyDns);
- }
-
- public static class UpdateLinkPropertyResult {
- public DataCallState.SetupResult setupResult = DataCallState.SetupResult.SUCCESS;
- public LinkProperties oldLp;
- public LinkProperties newLp;
- public UpdateLinkPropertyResult(LinkProperties curLp) {
- oldLp = curLp;
- newLp = curLp;
- }
- }
-
- private UpdateLinkPropertyResult updateLinkProperty(DataCallState newState) {
- UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties);
-
- if (newState == null) return result;
-
- DataCallState.SetupResult setupResult;
- result.newLp = new LinkProperties();
-
- // set link properties based on data call response
- result.setupResult = setLinkProperties(newState, result.newLp);
- if (result.setupResult != DataCallState.SetupResult.SUCCESS) {
- if (DBG) log("updateLinkProperty failed : " + result.setupResult);
- return result;
- }
- // copy HTTP proxy as it is not part DataCallState.
- result.newLp.setHttpProxy(mLinkProperties.getHttpProxy());
-
- if (DBG && (! result.oldLp.equals(result.newLp))) {
- log("updateLinkProperty old LP=" + result.oldLp);
- log("updateLinkProperty new LP=" + result.newLp);
- }
- mLinkProperties = result.newLp;
-
- return result;
- }
-
- /**
- * The parent state for all other states.
- */
- private class DcDefaultState extends State {
- @Override
- public void enter() {
- phone.mCM.registerForRilConnected(getHandler(), EVENT_RIL_CONNECTED, null);
- }
- @Override
- public void exit() {
- phone.mCM.unregisterForRilConnected(getHandler());
- }
- @Override
- public boolean processMessage(Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
- if (mAc != null) {
- if (VDBG) log("Disconnecting to previous connection mAc=" + mAc);
- mAc.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
- AsyncChannel.STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED);
- } else {
- mAc = new AsyncChannel();
- mAc.connected(null, getHandler(), msg.replyTo);
- if (VDBG) log("DcDefaultState: FULL_CONNECTION reply connected");
- mAc.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
- AsyncChannel.STATUS_SUCCESSFUL, mId, "hi");
- }
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
- if (VDBG) log("CMD_CHANNEL_DISCONNECT");
- mAc.disconnect();
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- if (VDBG) log("CMD_CHANNEL_DISCONNECTED");
- mAc = null;
- break;
- }
- case DataConnectionAc.REQ_IS_INACTIVE: {
- boolean val = getCurrentState() == mInactiveState;
- if (VDBG) log("REQ_IS_INACTIVE isInactive=" + val);
- mAc.replyToMessage(msg, DataConnectionAc.RSP_IS_INACTIVE, val ? 1 : 0);
- break;
- }
- case DataConnectionAc.REQ_GET_CID: {
- if (VDBG) log("REQ_GET_CID cid=" + cid);
- mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_CID, cid);
- break;
- }
- case DataConnectionAc.REQ_GET_APNSETTING: {
- if (VDBG) log("REQ_GET_APNSETTING apnSetting=" + mApn);
- mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNSETTING, mApn);
- break;
- }
- case DataConnectionAc.REQ_GET_LINK_PROPERTIES: {
- LinkProperties lp = new LinkProperties(mLinkProperties);
- if (VDBG) log("REQ_GET_LINK_PROPERTIES linkProperties" + lp);
- mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_PROPERTIES, lp);
- break;
- }
- case DataConnectionAc.REQ_SET_LINK_PROPERTIES_HTTP_PROXY: {
- ProxyProperties proxy = (ProxyProperties) msg.obj;
- if (VDBG) log("REQ_SET_LINK_PROPERTIES_HTTP_PROXY proxy=" + proxy);
- mLinkProperties.setHttpProxy(proxy);
- mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_LINK_PROPERTIES_HTTP_PROXY);
- break;
- }
- case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
- DataCallState newState = (DataCallState) msg.obj;
- UpdateLinkPropertyResult result =
- updateLinkProperty(newState);
- if (VDBG) {
- log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE result="
- + result + " newState=" + newState);
- }
- mAc.replyToMessage(msg,
- DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
- result);
- break;
- }
- case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
- LinkCapabilities lc = new LinkCapabilities(mCapabilities);
- if (VDBG) log("REQ_GET_LINK_CAPABILITIES linkCapabilities" + lc);
- mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_CAPABILITIES, lc);
- break;
- }
- case DataConnectionAc.REQ_RESET:
- if (VDBG) log("DcDefaultState: msg.what=REQ_RESET");
- mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
- transitionTo(mInactiveState);
- break;
- case DataConnectionAc.REQ_GET_REFCOUNT: {
- if (VDBG) log("REQ_GET_REFCOUNT refCount=" + mRefCount);
- mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_REFCOUNT, mRefCount);
- break;
- }
- case DataConnectionAc.REQ_ADD_APNCONTEXT: {
- ApnContext apnContext = (ApnContext) msg.obj;
- if (VDBG) log("REQ_ADD_APNCONTEXT apn=" + apnContext.getApnType());
- if (!mApnList.contains(apnContext)) {
- mApnList.add(apnContext);
- }
- mAc.replyToMessage(msg, DataConnectionAc.RSP_ADD_APNCONTEXT);
- break;
- }
- case DataConnectionAc.REQ_REMOVE_APNCONTEXT: {
- ApnContext apnContext = (ApnContext) msg.obj;
- if (VDBG) log("REQ_REMOVE_APNCONTEXT apn=" + apnContext.getApnType());
- mApnList.remove(apnContext);
- mAc.replyToMessage(msg, DataConnectionAc.RSP_REMOVE_APNCONTEXT);
- break;
- }
- case DataConnectionAc.REQ_GET_APNCONTEXT_LIST: {
- if (VDBG) log("REQ_GET_APNCONTEXT_LIST num in list=" + mApnList.size());
- mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_APNCONTEXT_LIST,
- new ArrayList<ApnContext>(mApnList));
- break;
- }
- case DataConnectionAc.REQ_SET_RECONNECT_INTENT: {
- PendingIntent intent = (PendingIntent) msg.obj;
- if (VDBG) log("REQ_SET_RECONNECT_INTENT");
- mReconnectIntent = intent;
- mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_RECONNECT_INTENT);
- break;
- }
- case DataConnectionAc.REQ_GET_RECONNECT_INTENT: {
- if (VDBG) log("REQ_GET_RECONNECT_INTENT");
- mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_RECONNECT_INTENT,
- mReconnectIntent);
- break;
- }
- case EVENT_CONNECT:
- if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected");
- ConnectionParams cp = (ConnectionParams) msg.obj;
- notifyConnectCompleted(cp, FailCause.UNKNOWN);
- break;
-
- case EVENT_DISCONNECT:
- if (DBG) {
- log("DcDefaultState deferring msg.what=EVENT_DISCONNECT" + mRefCount);
- }
- deferMessage(msg);
- break;
-
- case EVENT_DISCONNECT_ALL:
- if (DBG) {
- log("DcDefaultState deferring msg.what=EVENT_DISCONNECT_ALL" + mRefCount);
- }
- deferMessage(msg);
- break;
-
- case EVENT_RIL_CONNECTED:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- mRilVersion = (Integer)ar.result;
- if (DBG) {
- log("DcDefaultState: msg.what=EVENT_RIL_CONNECTED mRilVersion=" +
- mRilVersion);
- }
- } else {
- log("Unexpected exception on EVENT_RIL_CONNECTED");
- mRilVersion = -1;
- }
- break;
-
- default:
- if (DBG) {
- log("DcDefaultState: shouldn't happen but ignore msg.what=0x" +
- Integer.toHexString(msg.what));
- }
- break;
- }
-
- return HANDLED;
- }
- }
- private DcDefaultState mDefaultState = new DcDefaultState();
-
- /**
- * The state machine is inactive and expects a EVENT_CONNECT.
- */
- private class DcInactiveState extends State {
- private ConnectionParams mConnectionParams = null;
- private FailCause mFailCause = null;
- private DisconnectParams mDisconnectParams = null;
-
- public void setEnterNotificationParams(ConnectionParams cp, FailCause cause,
- int retryOverride) {
- if (VDBG) log("DcInactiveState: setEnterNoticationParams cp,cause");
- mConnectionParams = cp;
- mFailCause = cause;
- mRetryOverride = retryOverride;
- }
-
- public void setEnterNotificationParams(DisconnectParams dp) {
- if (VDBG) log("DcInactiveState: setEnterNoticationParams dp");
- mDisconnectParams = dp;
- }
-
- @Override
- public void enter() {
- mTag += 1;
-
- /**
- * Now that we've transitioned to Inactive state we
- * can send notifications. Previously we sent the
- * notifications in the processMessage handler but
- * that caused a race condition because the synchronous
- * call to isInactive.
- */
- if ((mConnectionParams != null) && (mFailCause != null)) {
- if (VDBG) log("DcInactiveState: enter notifyConnectCompleted");
- notifyConnectCompleted(mConnectionParams, mFailCause);
- }
- if (mDisconnectParams != null) {
- if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted");
- notifyDisconnectCompleted(mDisconnectParams, true);
- }
- clearSettings();
- }
-
- @Override
- public void exit() {
- // clear notifications
- mConnectionParams = null;
- mFailCause = null;
- mDisconnectParams = null;
- }
-
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
-
- switch (msg.what) {
- case DataConnectionAc.REQ_RESET:
- if (DBG) {
- log("DcInactiveState: msg.what=RSP_RESET, ignore we're already reset");
- }
- mAc.replyToMessage(msg, DataConnectionAc.RSP_RESET);
- retVal = HANDLED;
- break;
-
- case EVENT_CONNECT:
- ConnectionParams cp = (ConnectionParams) msg.obj;
- cp.tag = mTag;
- if (DBG) {
- log("DcInactiveState msg.what=EVENT_CONNECT." + "RefCount = "
- + mRefCount);
- }
- mRefCount = 1;
- onConnect(cp);
- transitionTo(mActivatingState);
- retVal = HANDLED;
- break;
-
- case EVENT_DISCONNECT:
- if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT");
- notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
- retVal = HANDLED;
- break;
-
- case EVENT_DISCONNECT_ALL:
- if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL");
- notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
- retVal = HANDLED;
- break;
-
- default:
- if (VDBG) {
- log("DcInactiveState nothandled msg.what=0x" +
- Integer.toHexString(msg.what));
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcInactiveState mInactiveState = new DcInactiveState();
-
- /**
- * The state machine is activating a connection.
- */
- private class DcActivatingState extends State {
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
- AsyncResult ar;
- ConnectionParams cp;
-
- switch (msg.what) {
- case EVENT_CONNECT:
- if (DBG) log("DcActivatingState deferring msg.what=EVENT_CONNECT refCount = "
- + mRefCount);
- deferMessage(msg);
- retVal = HANDLED;
- break;
-
- case EVENT_SETUP_DATA_CONNECTION_DONE:
- if (DBG) log("DcActivatingState msg.what=EVENT_SETUP_DATA_CONNECTION_DONE");
-
- ar = (AsyncResult) msg.obj;
- cp = (ConnectionParams) ar.userObj;
-
- DataCallState.SetupResult result = onSetupConnectionCompleted(ar);
- if (DBG) log("DcActivatingState onSetupConnectionCompleted result=" + result);
- switch (result) {
- case SUCCESS:
- // All is well
- mActiveState.setEnterNotificationParams(cp, FailCause.NONE);
- transitionTo(mActiveState);
- break;
- case ERR_BadCommand:
- // Vendor ril rejected the command and didn't connect.
- // Transition to inactive but send notifications after
- // we've entered the mInactive state.
- mInactiveState.setEnterNotificationParams(cp, result.mFailCause, -1);
- transitionTo(mInactiveState);
- break;
- case ERR_UnacceptableParameter:
- // The addresses given from the RIL are bad
- tearDownData(cp);
- transitionTo(mDisconnectingErrorCreatingConnection);
- break;
- case ERR_GetLastErrorFromRil:
- // Request failed and this is an old RIL
- phone.mCM.getLastDataCallFailCause(
- obtainMessage(EVENT_GET_LAST_FAIL_DONE, cp));
- break;
- case ERR_RilError:
- // Request failed and mFailCause has the reason
- mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
- getSuggestedRetryTime(ar));
- transitionTo(mInactiveState);
- break;
- case ERR_Stale:
- // Request is stale, ignore.
- break;
- default:
- throw new RuntimeException("Unknown SetupResult, should not happen");
- }
- retVal = HANDLED;
- break;
-
- case EVENT_GET_LAST_FAIL_DONE:
- ar = (AsyncResult) msg.obj;
- cp = (ConnectionParams) ar.userObj;
- FailCause cause = FailCause.UNKNOWN;
-
- if (cp.tag == mTag) {
- if (DBG) log("DcActivatingState msg.what=EVENT_GET_LAST_FAIL_DONE");
- if (ar.exception == null) {
- int rilFailCause = ((int[]) (ar.result))[0];
- cause = FailCause.fromInt(rilFailCause);
- }
- // Transition to inactive but send notifications after
- // we've entered the mInactive state.
- mInactiveState.setEnterNotificationParams(cp, cause, -1);
- transitionTo(mInactiveState);
- } else {
- if (DBG) {
- log("DcActivatingState EVENT_GET_LAST_FAIL_DONE is stale cp.tag="
- + cp.tag + ", mTag=" + mTag);
- }
- }
-
- retVal = HANDLED;
- break;
-
- default:
- if (VDBG) {
- log("DcActivatingState not handled msg.what=0x" +
- Integer.toHexString(msg.what));
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcActivatingState mActivatingState = new DcActivatingState();
-
- /**
- * The state machine is connected, expecting an EVENT_DISCONNECT.
- */
- private class DcActiveState extends State {
- private ConnectionParams mConnectionParams = null;
- private FailCause mFailCause = null;
-
- public void setEnterNotificationParams(ConnectionParams cp, FailCause cause) {
- if (VDBG) log("DcInactiveState: setEnterNoticationParams cp,cause");
- mConnectionParams = cp;
- mFailCause = cause;
- }
-
- @Override public void enter() {
- /**
- * Now that we've transitioned to Active state we
- * can send notifications. Previously we sent the
- * notifications in the processMessage handler but
- * that caused a race condition because the synchronous
- * call to isActive.
- */
- if ((mConnectionParams != null) && (mFailCause != null)) {
- if (VDBG) log("DcActiveState: enter notifyConnectCompleted");
- notifyConnectCompleted(mConnectionParams, mFailCause);
- }
- }
-
- @Override
- public void exit() {
- // clear notifications
- mConnectionParams = null;
- mFailCause = null;
- }
-
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
-
- switch (msg.what) {
- case EVENT_CONNECT:
- mRefCount++;
- if (DBG) log("DcActiveState msg.what=EVENT_CONNECT RefCount=" + mRefCount);
- if (msg.obj != null) {
- notifyConnectCompleted((ConnectionParams) msg.obj, FailCause.NONE);
- }
- retVal = HANDLED;
- break;
- case EVENT_DISCONNECT:
- mRefCount--;
- if (DBG) log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" + mRefCount);
- if (mRefCount == 0)
- {
- DisconnectParams dp = (DisconnectParams) msg.obj;
- dp.tag = mTag;
- tearDownData(dp);
- transitionTo(mDisconnectingState);
- } else {
- if (msg.obj != null) {
- notifyDisconnectCompleted((DisconnectParams) msg.obj, false);
- }
- }
- retVal = HANDLED;
- break;
-
- case EVENT_DISCONNECT_ALL:
- if (DBG) {
- log("DcActiveState msg.what=EVENT_DISCONNECT_ALL RefCount=" + mRefCount);
- }
- mRefCount = 0;
- DisconnectParams dp = (DisconnectParams) msg.obj;
- dp.tag = mTag;
- tearDownData(dp);
- transitionTo(mDisconnectingState);
- retVal = HANDLED;
- break;
-
- default:
- if (VDBG) {
- log("DcActiveState not handled msg.what=0x" +
- Integer.toHexString(msg.what));
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcActiveState mActiveState = new DcActiveState();
-
- /**
- * The state machine is disconnecting.
- */
- private class DcDisconnectingState extends State {
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
-
- switch (msg.what) {
- case EVENT_CONNECT:
- if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = "
- + mRefCount);
- deferMessage(msg);
- retVal = HANDLED;
- break;
-
- case EVENT_DEACTIVATE_DONE:
- if (DBG) log("DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE");
- AsyncResult ar = (AsyncResult) msg.obj;
- DisconnectParams dp = (DisconnectParams) ar.userObj;
- if (dp.tag == mTag) {
- // Transition to inactive but send notifications after
- // we've entered the mInactive state.
- mInactiveState.setEnterNotificationParams((DisconnectParams) ar.userObj);
- transitionTo(mInactiveState);
- } else {
- if (DBG) log("DcDisconnectState EVENT_DEACTIVATE_DONE stale dp.tag="
- + dp.tag + " mTag=" + mTag);
- }
- retVal = HANDLED;
- break;
-
- default:
- if (VDBG) {
- log("DcDisconnectingState not handled msg.what=0x" +
- Integer.toHexString(msg.what));
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcDisconnectingState mDisconnectingState = new DcDisconnectingState();
-
- /**
- * The state machine is disconnecting after an creating a connection.
- */
- private class DcDisconnectionErrorCreatingConnection extends State {
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
-
- switch (msg.what) {
- case EVENT_DEACTIVATE_DONE:
- AsyncResult ar = (AsyncResult) msg.obj;
- ConnectionParams cp = (ConnectionParams) ar.userObj;
- if (cp.tag == mTag) {
- if (DBG) {
- log("DcDisconnectionErrorCreatingConnection" +
- " msg.what=EVENT_DEACTIVATE_DONE");
- }
-
- // Transition to inactive but send notifications after
- // we've entered the mInactive state.
- mInactiveState.setEnterNotificationParams(cp,
- FailCause.UNACCEPTABLE_NETWORK_PARAMETER, -1);
- transitionTo(mInactiveState);
- } else {
- if (DBG) {
- log("DcDisconnectionErrorCreatingConnection EVENT_DEACTIVATE_DONE" +
- " stale dp.tag=" + cp.tag + ", mTag=" + mTag);
- }
- }
- retVal = HANDLED;
- break;
-
- default:
- if (VDBG) {
- log("DcDisconnectionErrorCreatingConnection not handled msg.what=0x"
- + Integer.toHexString(msg.what));
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection =
- new DcDisconnectionErrorCreatingConnection();
-
- // ******* public interface
-
- /**
- * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg.
- * Used for cellular networks that use Acesss Point Names (APN) such
- * as GSM networks.
- *
- * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
- * With AsyncResult.userObj set to the original msg.obj,
- * AsyncResult.result = FailCause and AsyncResult.exception = Exception().
- * @param apn is the Access Point Name to bring up a connection to
- */
- public void bringUp(Message onCompletedMsg, ApnSetting apn) {
- sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, onCompletedMsg)));
- }
-
- /**
- * Tear down the connection through the apn on the network.
- *
- * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
- * With AsyncResult.userObj set to the original msg.obj.
- */
- public void tearDown(String reason, Message onCompletedMsg) {
- sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(reason, onCompletedMsg)));
- }
-
- /**
- * Tear down the connection through the apn on the network. Ignores refcount and
- * and always tears down.
- *
- * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
- * With AsyncResult.userObj set to the original msg.obj.
- */
- public void tearDownAll(String reason, Message onCompletedMsg) {
- sendMessage(obtainMessage(EVENT_DISCONNECT_ALL,
- new DisconnectParams(reason, onCompletedMsg)));
- }
-
- /**
- * @return the string for msg.what as our info.
- */
- @Override
- protected String getMessageInfo(Message msg) {
- String info = null;
- info = cmdToString(msg.what);
- if (info == null) {
- info = DataConnectionAc.cmdToString(msg.what);
- }
- return info;
- }
-
- /**
- * Dump the current state.
- *
- * @param fd
- * @param pw
- * @param args
- */
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.print("DataConnection ");
- super.dump(fd, pw, args);
- pw.println(" mApnList=" + mApnList);
- pw.flush();
- pw.println(" mDataConnectionTracker=" + mDataConnectionTracker);
- pw.println(" mApn=" + mApn);
- pw.println(" mTag=" + mTag);
- pw.flush();
- pw.println(" phone=" + phone);
- pw.println(" mRilVersion=" + mRilVersion);
- pw.println(" cid=" + cid);
- pw.flush();
- pw.println(" mLinkProperties=" + mLinkProperties);
- pw.flush();
- pw.println(" mCapabilities=" + mCapabilities);
- pw.println(" createTime=" + TimeUtils.logTimeOfDay(createTime));
- pw.println(" lastFailTime=" + TimeUtils.logTimeOfDay(lastFailTime));
- pw.println(" lastFailCause=" + lastFailCause);
- pw.flush();
- pw.println(" mRetryOverride=" + mRetryOverride);
- pw.println(" mRefCount=" + mRefCount);
- pw.println(" userData=" + userData);
- if (mRetryMgr != null) pw.println(" " + mRetryMgr);
- pw.flush();
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionAc.java b/telephony/java/com/android/internal/telephony/DataConnectionAc.java
deleted file mode 100644
index a24414f..0000000
--- a/telephony/java/com/android/internal/telephony/DataConnectionAc.java
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import android.app.PendingIntent;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.ProxyProperties;
-import android.os.Message;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * AsyncChannel to a DataConnection
- */
-public class DataConnectionAc extends AsyncChannel {
- private static final boolean DBG = false;
- private String mLogTag;
-
- public DataConnection dataConnection;
-
- public static final int BASE = Protocol.BASE_DATA_CONNECTION_AC;
-
- public static final int REQ_IS_INACTIVE = BASE + 0;
- public static final int RSP_IS_INACTIVE = BASE + 1;
-
- public static final int REQ_GET_CID = BASE + 2;
- public static final int RSP_GET_CID = BASE + 3;
-
- public static final int REQ_GET_APNSETTING = BASE + 4;
- public static final int RSP_GET_APNSETTING = BASE + 5;
-
- public static final int REQ_GET_LINK_PROPERTIES = BASE + 6;
- public static final int RSP_GET_LINK_PROPERTIES = BASE + 7;
-
- public static final int REQ_SET_LINK_PROPERTIES_HTTP_PROXY = BASE + 8;
- public static final int RSP_SET_LINK_PROPERTIES_HTTP_PROXY = BASE + 9;
-
- public static final int REQ_GET_LINK_CAPABILITIES = BASE + 10;
- public static final int RSP_GET_LINK_CAPABILITIES = BASE + 11;
-
- public static final int REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE = BASE + 12;
- public static final int RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE = BASE + 13;
-
- public static final int REQ_RESET = BASE + 14;
- public static final int RSP_RESET = BASE + 15;
-
- public static final int REQ_GET_REFCOUNT = BASE + 16;
- public static final int RSP_GET_REFCOUNT = BASE + 17;
-
- public static final int REQ_ADD_APNCONTEXT = BASE + 18;
- public static final int RSP_ADD_APNCONTEXT = BASE + 19;
-
- public static final int REQ_REMOVE_APNCONTEXT = BASE + 20;
- public static final int RSP_REMOVE_APNCONTEXT = BASE + 21;
-
- public static final int REQ_GET_APNCONTEXT_LIST = BASE + 22;
- public static final int RSP_GET_APNCONTEXT_LIST = BASE + 23;
-
- public static final int REQ_SET_RECONNECT_INTENT = BASE + 24;
- public static final int RSP_SET_RECONNECT_INTENT = BASE + 25;
-
- public static final int REQ_GET_RECONNECT_INTENT = BASE + 26;
- public static final int RSP_GET_RECONNECT_INTENT = BASE + 27;
-
- private static final int CMD_TO_STRING_COUNT = RSP_GET_RECONNECT_INTENT - BASE + 1;
- private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
- static {
- sCmdToString[REQ_IS_INACTIVE - BASE] = "REQ_IS_INACTIVE";
- sCmdToString[RSP_IS_INACTIVE - BASE] = "RSP_IS_INACTIVE";
- sCmdToString[REQ_GET_CID - BASE] = "REQ_GET_CID";
- sCmdToString[RSP_GET_CID - BASE] = "RSP_GET_CID";
- sCmdToString[REQ_GET_APNSETTING - BASE] = "REQ_GET_APNSETTING";
- sCmdToString[RSP_GET_APNSETTING - BASE] = "RSP_GET_APNSETTING";
- sCmdToString[REQ_GET_LINK_PROPERTIES - BASE] = "REQ_GET_LINK_PROPERTIES";
- sCmdToString[RSP_GET_LINK_PROPERTIES - BASE] = "RSP_GET_LINK_PROPERTIES";
- sCmdToString[REQ_SET_LINK_PROPERTIES_HTTP_PROXY - BASE] =
- "REQ_SET_LINK_PROPERTIES_HTTP_PROXY";
- sCmdToString[RSP_SET_LINK_PROPERTIES_HTTP_PROXY - BASE] =
- "RSP_SET_LINK_PROPERTIES_HTTP_PROXY";
- sCmdToString[REQ_GET_LINK_CAPABILITIES - BASE] = "REQ_GET_LINK_CAPABILITIES";
- sCmdToString[RSP_GET_LINK_CAPABILITIES - BASE] = "RSP_GET_LINK_CAPABILITIES";
- sCmdToString[REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE - BASE] =
- "REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE";
- sCmdToString[RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE - BASE] =
- "RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE";
- sCmdToString[REQ_RESET - BASE] = "REQ_RESET";
- sCmdToString[RSP_RESET - BASE] = "RSP_RESET";
- sCmdToString[REQ_GET_REFCOUNT - BASE] = "REQ_GET_REFCOUNT";
- sCmdToString[RSP_GET_REFCOUNT - BASE] = "RSP_GET_REFCOUNT";
- sCmdToString[REQ_ADD_APNCONTEXT - BASE] = "REQ_ADD_APNCONTEXT";
- sCmdToString[RSP_ADD_APNCONTEXT - BASE] = "RSP_ADD_APNCONTEXT";
- sCmdToString[REQ_REMOVE_APNCONTEXT - BASE] = "REQ_REMOVE_APNCONTEXT";
- sCmdToString[RSP_REMOVE_APNCONTEXT - BASE] = "RSP_REMOVE_APNCONTEXT";
- sCmdToString[REQ_GET_APNCONTEXT_LIST - BASE] = "REQ_GET_APNCONTEXT_LIST";
- sCmdToString[RSP_GET_APNCONTEXT_LIST - BASE] = "RSP_GET_APNCONTEXT_LIST";
- sCmdToString[REQ_SET_RECONNECT_INTENT - BASE] = "REQ_SET_RECONNECT_INTENT";
- sCmdToString[RSP_SET_RECONNECT_INTENT - BASE] = "RSP_SET_RECONNECT_INTENT";
- sCmdToString[REQ_GET_RECONNECT_INTENT - BASE] = "REQ_GET_RECONNECT_INTENT";
- sCmdToString[RSP_GET_RECONNECT_INTENT - BASE] = "RSP_GET_RECONNECT_INTENT";
- }
- protected static String cmdToString(int cmd) {
- cmd -= BASE;
- if ((cmd >= 0) && (cmd < sCmdToString.length)) {
- return sCmdToString[cmd];
- } else {
- return AsyncChannel.cmdToString(cmd + BASE);
- }
- }
-
- /**
- * enum used to notify action taken or necessary to be
- * taken after the link property is changed.
- */
- public enum LinkPropertyChangeAction {
- NONE, CHANGED, RESET;
-
- public static LinkPropertyChangeAction fromInt(int value) {
- if (value == NONE.ordinal()) {
- return NONE;
- } else if (value == CHANGED.ordinal()) {
- return CHANGED;
- } else if (value == RESET.ordinal()) {
- return RESET;
- } else {
- throw new RuntimeException("LinkPropertyChangeAction.fromInt: bad value=" + value);
- }
- }
- }
-
- public DataConnectionAc(DataConnection dc, String logTag) {
- dataConnection = dc;
- mLogTag = logTag;
- }
-
- /**
- * Request if the state machine is in the inactive state.
- * Response {@link #rspIsInactive}
- */
- public void reqIsInactive() {
- sendMessage(REQ_IS_INACTIVE);
- if (DBG) log("reqIsInactive");
- }
-
- /**
- * Evaluate RSP_IS_INACTIVE.
- *
- * @return true if the state machine is in the inactive state.
- */
- public boolean rspIsInactive(Message response) {
- boolean retVal = response.arg1 == 1;
- if (DBG) log("rspIsInactive=" + retVal);
- return retVal;
- }
-
- /**
- * @return true if the state machine is in the inactive state.
- */
- public boolean isInactiveSync() {
- Message response = sendMessageSynchronously(REQ_IS_INACTIVE);
- if ((response != null) && (response.what == RSP_IS_INACTIVE)) {
- return rspIsInactive(response);
- } else {
- log("rspIsInactive error response=" + response);
- return false;
- }
- }
-
- /**
- * Request the Connection ID.
- * Response {@link #rspCid}
- */
- public void reqCid() {
- sendMessage(REQ_GET_CID);
- if (DBG) log("reqCid");
- }
-
- /**
- * Evaluate a RSP_GET_CID message and return the cid.
- *
- * @param response Message
- * @return connection id or -1 if an error
- */
- public int rspCid(Message response) {
- int retVal = response.arg1;
- if (DBG) log("rspCid=" + retVal);
- return retVal;
- }
-
- /**
- * @return connection id or -1 if an error
- */
- public int getCidSync() {
- Message response = sendMessageSynchronously(REQ_GET_CID);
- if ((response != null) && (response.what == RSP_GET_CID)) {
- return rspCid(response);
- } else {
- log("rspCid error response=" + response);
- return -1;
- }
- }
-
- /**
- * Request the Reference Count.
- * Response {@link #rspRefCount}
- */
- public void reqRefCount() {
- sendMessage(REQ_GET_REFCOUNT);
- if (DBG) log("reqRefCount");
- }
-
- /**
- * Evaluate a RSP_GET_REFCOUNT message and return the refCount.
- *
- * @param response Message
- * @return ref count or -1 if an error
- */
- public int rspRefCount(Message response) {
- int retVal = response.arg1;
- if (DBG) log("rspRefCount=" + retVal);
- return retVal;
- }
-
- /**
- * @return connection id or -1 if an error
- */
- public int getRefCountSync() {
- Message response = sendMessageSynchronously(REQ_GET_REFCOUNT);
- if ((response != null) && (response.what == RSP_GET_REFCOUNT)) {
- return rspRefCount(response);
- } else {
- log("rspRefCount error response=" + response);
- return -1;
- }
- }
-
- /**
- * Request the connections ApnSetting.
- * Response {@link #rspApnSetting}
- */
- public void reqApnSetting() {
- sendMessage(REQ_GET_APNSETTING);
- if (DBG) log("reqApnSetting");
- }
-
- /**
- * Evaluate a RSP_APN_SETTING message and return the ApnSetting.
- *
- * @param response Message
- * @return ApnSetting, maybe null
- */
- public ApnSetting rspApnSetting(Message response) {
- ApnSetting retVal = (ApnSetting) response.obj;
- if (DBG) log("rspApnSetting=" + retVal);
- return retVal;
- }
-
- /**
- * Get the connections ApnSetting.
- *
- * @return ApnSetting or null if an error
- */
- public ApnSetting getApnSettingSync() {
- Message response = sendMessageSynchronously(REQ_GET_APNSETTING);
- if ((response != null) && (response.what == RSP_GET_APNSETTING)) {
- return rspApnSetting(response);
- } else {
- log("getApnSetting error response=" + response);
- return null;
- }
- }
-
- /**
- * Request the connections LinkProperties.
- * Response {@link #rspLinkProperties}
- */
- public void reqLinkProperties() {
- sendMessage(REQ_GET_LINK_PROPERTIES);
- if (DBG) log("reqLinkProperties");
- }
-
- /**
- * Evaluate RSP_GET_LINK_PROPERTIES
- *
- * @param response
- * @return LinkProperties, maybe null.
- */
- public LinkProperties rspLinkProperties(Message response) {
- LinkProperties retVal = (LinkProperties) response.obj;
- if (DBG) log("rspLinkProperties=" + retVal);
- return retVal;
- }
-
- /**
- * Get the connections LinkProperties.
- *
- * @return LinkProperties or null if an error
- */
- public LinkProperties getLinkPropertiesSync() {
- Message response = sendMessageSynchronously(REQ_GET_LINK_PROPERTIES);
- if ((response != null) && (response.what == RSP_GET_LINK_PROPERTIES)) {
- return rspLinkProperties(response);
- } else {
- log("getLinkProperties error response=" + response);
- return null;
- }
- }
-
- /**
- * Request setting the connections LinkProperties.HttpProxy.
- * Response RSP_SET_LINK_PROPERTIES when complete.
- */
- public void reqSetLinkPropertiesHttpProxy(ProxyProperties proxy) {
- sendMessage(REQ_SET_LINK_PROPERTIES_HTTP_PROXY, proxy);
- if (DBG) log("reqSetLinkPropertiesHttpProxy proxy=" + proxy);
- }
-
- /**
- * Set the connections LinkProperties.HttpProxy
- */
- public void setLinkPropertiesHttpProxySync(ProxyProperties proxy) {
- Message response =
- sendMessageSynchronously(REQ_SET_LINK_PROPERTIES_HTTP_PROXY, proxy);
- if ((response != null) && (response.what == RSP_SET_LINK_PROPERTIES_HTTP_PROXY)) {
- if (DBG) log("setLinkPropertiesHttpPoxy ok");
- } else {
- log("setLinkPropertiesHttpPoxy error response=" + response);
- }
- }
-
- /**
- * Request update LinkProperties from DataCallState
- * Response {@link #rspUpdateLinkPropertiesDataCallState}
- */
- public void reqUpdateLinkPropertiesDataCallState(DataCallState newState) {
- sendMessage(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
- if (DBG) log("reqUpdateLinkPropertiesDataCallState");
- }
-
- public UpdateLinkPropertyResult rspUpdateLinkPropertiesDataCallState(Message response) {
- UpdateLinkPropertyResult retVal = (UpdateLinkPropertyResult)response.obj;
- if (DBG) log("rspUpdateLinkPropertiesState: retVal=" + retVal);
- return retVal;
- }
-
- /**
- * Update link properties in the data connection
- *
- * @return the removed and added addresses.
- */
- public UpdateLinkPropertyResult updateLinkPropertiesDataCallStateSync(DataCallState newState) {
- Message response =
- sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
- if ((response != null) &&
- (response.what == RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE)) {
- return rspUpdateLinkPropertiesDataCallState(response);
- } else {
- log("getLinkProperties error response=" + response);
- return new UpdateLinkPropertyResult(new LinkProperties());
- }
- }
-
- /**
- * Request the connections LinkCapabilities.
- * Response {@link #rspLinkCapabilities}
- */
- public void reqLinkCapabilities() {
- sendMessage(REQ_GET_LINK_CAPABILITIES);
- if (DBG) log("reqLinkCapabilities");
- }
-
- /**
- * Evaluate RSP_GET_LINK_CAPABILITIES
- *
- * @param response
- * @return LinkCapabilites, maybe null.
- */
- public LinkCapabilities rspLinkCapabilities(Message response) {
- LinkCapabilities retVal = (LinkCapabilities) response.obj;
- if (DBG) log("rspLinkCapabilities=" + retVal);
- return retVal;
- }
-
- /**
- * Get the connections LinkCapabilities.
- *
- * @return LinkCapabilities or null if an error
- */
- public LinkCapabilities getLinkCapabilitiesSync() {
- Message response = sendMessageSynchronously(REQ_GET_LINK_CAPABILITIES);
- if ((response != null) && (response.what == RSP_GET_LINK_CAPABILITIES)) {
- return rspLinkCapabilities(response);
- } else {
- log("getLinkCapabilities error response=" + response);
- return null;
- }
- }
-
- /**
- * Request the connections LinkCapabilities.
- * Response RSP_RESET when complete
- */
- public void reqReset() {
- sendMessage(REQ_RESET);
- if (DBG) log("reqReset");
- }
-
- /**
- * Reset the connection and wait for it to complete.
- */
- public void resetSync() {
- Message response = sendMessageSynchronously(REQ_RESET);
- if ((response != null) && (response.what == RSP_RESET)) {
- if (DBG) log("restSync ok");
- } else {
- log("restSync error response=" + response);
- }
- }
-
- /**
- * Request to add ApnContext association.
- * Response RSP_ADD_APNCONTEXT when complete.
- */
- public void reqAddApnContext(ApnContext apnContext) {
- Message response = sendMessageSynchronously(REQ_ADD_APNCONTEXT, apnContext);
- if (DBG) log("reqAddApnContext");
- }
-
- /**
- * Add ApnContext association synchronoulsy.
- *
- * @param ApnContext to associate
- */
- public void addApnContextSync(ApnContext apnContext) {
- Message response = sendMessageSynchronously(REQ_ADD_APNCONTEXT, apnContext);
- if ((response != null) && (response.what == RSP_ADD_APNCONTEXT)) {
- if (DBG) log("addApnContext ok");
- } else {
- log("addApnContext error response=" + response);
- }
- }
-
- /**
- * Request to remove ApnContext association.
- * Response RSP_REMOVE_APNCONTEXT when complete.
- */
- public void reqRemomveApnContext(ApnContext apnContext) {
- Message response = sendMessageSynchronously(REQ_REMOVE_APNCONTEXT, apnContext);
- if (DBG) log("reqRemomveApnContext");
- }
-
- /**
- * Remove ApnContext associateion.
- *
- * @param ApnContext to dissociate
- */
- public void removeApnContextSync(ApnContext apnContext) {
- Message response = sendMessageSynchronously(REQ_REMOVE_APNCONTEXT, apnContext);
- if ((response != null) && (response.what == RSP_REMOVE_APNCONTEXT)) {
- if (DBG) log("removeApnContext ok");
- } else {
- log("removeApnContext error response=" + response);
- }
- }
-
- /**
- * Request to retrive ApnContext List associated with DC.
- * Response RSP_GET_APNCONTEXT_LIST when complete.
- */
- public void reqGetApnList(ApnContext apnContext) {
- Message response = sendMessageSynchronously(REQ_GET_APNCONTEXT_LIST);
- if (DBG) log("reqGetApnList");
- }
-
- /**
- * Retrieve Collection of ApnContext from the response message.
- *
- * @param Message sent from DC in response to REQ_GET_APNCONTEXT_LIST.
- * @return Collection of ApnContext
- */
- public Collection<ApnContext> rspApnList(Message response) {
- Collection<ApnContext> retVal = (Collection<ApnContext>)response.obj;
- if (retVal == null) retVal = new ArrayList<ApnContext>();
- return retVal;
- }
-
- /**
- * Retrieve collection of ApnContext currently associated with
- * the DataConnectionA synchronously.
- *
- * @return Collection of ApnContext
- */
- public Collection<ApnContext> getApnListSync() {
- Message response = sendMessageSynchronously(REQ_GET_APNCONTEXT_LIST);
- if ((response != null) && (response.what == RSP_GET_APNCONTEXT_LIST)) {
- if (DBG) log("getApnList ok");
- return rspApnList(response);
- } else {
- log("getApnList error response=" + response);
- // return dummy list with no entry
- return new ArrayList<ApnContext>();
- }
- }
-
- /**
- * Request to set Pending ReconnectIntent to DC.
- * Response RSP_SET_RECONNECT_INTENT when complete.
- */
- public void reqSetReconnectIntent(PendingIntent intent) {
- Message response = sendMessageSynchronously(REQ_SET_RECONNECT_INTENT, intent);
- if (DBG) log("reqSetReconnectIntent");
- }
-
- /**
- * Set pending reconnect intent to DC synchronously.
- *
- * @param PendingIntent to set.
- */
- public void setReconnectIntentSync(PendingIntent intent) {
- Message response = sendMessageSynchronously(REQ_SET_RECONNECT_INTENT, intent);
- if ((response != null) && (response.what == RSP_SET_RECONNECT_INTENT)) {
- if (DBG) log("setReconnectIntent ok");
- } else {
- log("setReconnectIntent error response=" + response);
- }
- }
-
- /**
- * Request to get Pending ReconnectIntent to DC.
- * Response RSP_GET_RECONNECT_INTENT when complete.
- */
- public void reqGetReconnectIntent() {
- Message response = sendMessageSynchronously(REQ_GET_RECONNECT_INTENT);
- if (DBG) log("reqGetReconnectIntent");
- }
-
- /**
- * Retrieve reconnect intent from response message from DC.
- *
- * @param Message which contains the reconnect intent.
- * @return PendingIntent from the response.
- */
- public PendingIntent rspReconnectIntent(Message response) {
- PendingIntent retVal = (PendingIntent) response.obj;
- return retVal;
- }
-
- /**
- * Retrieve reconnect intent currently set in DC synchronously.
- *
- * @return PendingIntent reconnect intent current ly set in DC
- */
- public PendingIntent getReconnectIntentSync() {
- Message response = sendMessageSynchronously(REQ_GET_RECONNECT_INTENT);
- if ((response != null) && (response.what == RSP_GET_RECONNECT_INTENT)) {
- if (DBG) log("getReconnectIntent ok");
- return rspReconnectIntent(response);
- } else {
- log("getReconnectIntent error response=" + response);
- return null;
- }
- }
-
- @Override
- public String toString() {
- return dataConnection.getName();
- }
-
- private void log(String s) {
- android.util.Log.d(mLogTag, "DataConnectionAc " + s);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
deleted file mode 100644
index 0dee7a1..0000000
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ /dev/null
@@ -1,1289 +0,0 @@
-/*
- * 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.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.database.ContentObserver;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.NetworkInfo;
-import android.net.TrafficStats;
-import android.net.wifi.WifiManager;
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.R;
-import com.android.internal.telephony.DataConnection.FailCause;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * {@hide}
- */
-public abstract class DataConnectionTracker extends Handler {
- protected static final boolean DBG = true;
- protected static final boolean VDBG = false;
-
- /**
- * 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,
- DORMANT
- }
-
- public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER =
- "com.android.internal.telephony";
- public static String EXTRA_MESSENGER = "EXTRA_MESSENGER";
-
- /***** Event Codes *****/
- protected static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER;
- protected static final int EVENT_DATA_SETUP_COMPLETE = BASE + 0;
- protected static final int EVENT_RADIO_AVAILABLE = BASE + 1;
- protected static final int EVENT_RECORDS_LOADED = BASE + 2;
- protected static final int EVENT_TRY_SETUP_DATA = BASE + 3;
- protected static final int EVENT_DATA_STATE_CHANGED = BASE + 4;
- protected static final int EVENT_POLL_PDP = BASE + 5;
- protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6;
- protected static final int EVENT_VOICE_CALL_STARTED = BASE + 7;
- protected static final int EVENT_VOICE_CALL_ENDED = BASE + 8;
- protected static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9;
- protected static final int EVENT_LINK_STATE_CHANGED = BASE + 10;
- protected static final int EVENT_ROAMING_ON = BASE + 11;
- protected static final int EVENT_ROAMING_OFF = BASE + 12;
- protected static final int EVENT_ENABLE_NEW_APN = BASE + 13;
- protected static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14;
- protected static final int EVENT_DISCONNECT_DONE = BASE + 15;
- protected static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16;
- protected static final int EVENT_DATA_STALL_ALARM = BASE + 17;
- protected static final int EVENT_DO_RECOVERY = BASE + 18;
- protected static final int EVENT_APN_CHANGED = BASE + 19;
- protected static final int EVENT_CDMA_DATA_DETACHED = BASE + 20;
- protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21;
- protected static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22;
- protected static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
- public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
- protected static final int EVENT_CDMA_OTA_PROVISION = BASE + 25;
- protected static final int EVENT_RESTART_RADIO = BASE + 26;
- protected static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27;
- protected static final int EVENT_RESET_DONE = BASE + 28;
- public static final int CMD_SET_USER_DATA_ENABLE = BASE + 29;
- public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 30;
- public static final int CMD_SET_DEPENDENCY_MET = BASE + 31;
- public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
-
- /***** Constants *****/
-
- protected static final int APN_INVALID_ID = -1;
- protected static final int APN_DEFAULT_ID = 0;
- protected static final int APN_MMS_ID = 1;
- protected static final int APN_SUPL_ID = 2;
- protected static final int APN_DUN_ID = 3;
- protected static final int APN_HIPRI_ID = 4;
- protected static final int APN_IMS_ID = 5;
- protected static final int APN_FOTA_ID = 6;
- protected static final int APN_CBS_ID = 7;
- protected static final int APN_NUM_TYPES = 8;
-
- public static final int DISABLED = 0;
- public static final int ENABLED = 1;
-
- public static final String APN_TYPE_KEY = "apnType";
-
- /** Delay between APN attempts.
- Note the property override mechanism is there just for testing purpose only. */
- protected static final int APN_DELAY_MILLIS =
- SystemProperties.getInt("persist.radio.apn_delay", 5000);
-
- protected Object mDataEnabledLock = new Object();
-
- // responds to the setInternalDataEnabled call - used internally to turn off data
- // for example during emergency calls
- protected boolean mInternalDataEnabled = true;
-
- // responds to public (user) API to enable/disable data use
- // independent of mInternalDataEnabled and requests for APN access
- // persisted
- protected boolean mUserDataEnabled = true;
-
- // TODO: move away from static state once 5587429 is fixed.
- protected static boolean sPolicyDataEnabled = true;
-
- private boolean[] dataEnabled = new boolean[APN_NUM_TYPES];
-
- private int enabledCount = 0;
-
- /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
- protected String mRequestedApnType = Phone.APN_TYPE_DEFAULT;
-
- /** Retry configuration: A doubling of retry times from 5secs to 30minutes */
- protected static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000,"
- + "5000,10000,20000,40000,80000:5000,160000:5000,"
- + "320000:5000,640000:5000,1280000:5000,1800000:5000";
-
- /** Retry configuration for secondary networks: 4 tries in 20 sec */
- protected static final String SECONDARY_DATA_RETRY_CONFIG =
- "max_retries=3, 5000, 5000, 5000";
-
- /** Slow poll when attempting connection recovery. */
- protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
- /** Default max failure count before attempting to network re-registration. */
- protected static final int DEFAULT_MAX_PDP_RESET_FAIL = 3;
-
- /**
- * After detecting a potential connection problem, this is the max number
- * of subsequent polls before attempting recovery.
- */
- 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;
- // Default sent packets without ack which triggers initial recovery steps
- 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";
-
- // Default for the data stall alarm while non-aggressive stall detection
- protected static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
- // Default for the data stall alarm for aggressive stall detection
- protected static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
- // If attempt is less than this value we're doing first level recovery
- protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1;
- // Tag for tracking stale alarms
- protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag";
-
- // TODO: See if we can remove INTENT_RECONNECT_ALARM
- // having to have different values for GSM and
- // CDMA. If so we can then remove the need for
- // getActionIntentReconnectAlarm.
- protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
- "reconnect_alarm_extra_reason";
-
- // Used for debugging. Send the INTENT with an optional counter value with the number
- // of times the setup is to fail before succeeding. If the counter isn't passed the
- // setup will fail once. Example fail two times with FailCause.SIGNAL_LOST(-3)
- // adb shell am broadcast \
- // -a com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter \
- // --ei fail_data_setup_counter 3 --ei fail_data_setup_fail_cause -3
- protected static final String INTENT_SET_FAIL_DATA_SETUP_COUNTER =
- "com.android.internal.telephony.dataconnectiontracker.intent_set_fail_data_setup_counter";
- protected static final String FAIL_DATA_SETUP_COUNTER = "fail_data_setup_counter";
- protected int mFailDataSetupCounter = 0;
- protected static final String FAIL_DATA_SETUP_FAIL_CAUSE = "fail_data_setup_fail_cause";
- protected FailCause mFailDataSetupFailCause = FailCause.ERROR_UNSPECIFIED;
-
- protected static final String DEFALUT_DATA_ON_BOOT_PROP = "net.def_data_on_boot";
-
- // member variables
- protected PhoneBase mPhone;
- protected Activity mActivity = Activity.NONE;
- protected State mState = State.IDLE;
- protected Handler mDataConnectionTracker = null;
-
-
- protected long mTxPkts;
- protected long mRxPkts;
- protected int mNetStatPollPeriod;
- protected boolean mNetStatPollEnabled = false;
-
- protected TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
- // Used to track stale data stall alarms.
- protected int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
- // The current data stall alarm intent
- protected PendingIntent mDataStallAlarmIntent = null;
- // Number of packets sent since the last received packet
- protected long mSentSinceLastRecv;
- // Controls when a simple recovery attempt it to be tried
- protected int mNoRecvPollCount = 0;
-
- // 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 mCidActive;
-
- // When false we will not auto attach and manually attaching is required.
- protected boolean mAutoAttachOnCreation = false;
-
- // State of screen
- // (TODO: Reconsider tying directly to screen, maybe this is
- // really a lower power mode")
- protected boolean mIsScreenOn = true;
-
- /** Allows the generation of unique Id's for DataConnection objects */
- protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
-
- /** The data connections. */
- protected HashMap<Integer, DataConnection> mDataConnections =
- new HashMap<Integer, DataConnection>();
-
- /** The data connection async channels */
- protected HashMap<Integer, DataConnectionAc> mDataConnectionAsyncChannels =
- new HashMap<Integer, DataConnectionAc>();
-
- /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
- protected HashMap<String, Integer> mApnToDataConnectionId =
- new HashMap<String, Integer>();
-
- /** Phone.APN_TYPE_* ===> ApnContext */
- protected ConcurrentHashMap<String, ApnContext> mApnContexts =
- new ConcurrentHashMap<String, ApnContext>();
-
- /* Currently active APN */
- protected ApnSetting mActiveApn;
-
- /** allApns holds all apns */
- protected ArrayList<ApnSetting> mAllApns = null;
-
- /** preferred apn */
- protected ApnSetting mPreferredApn = null;
-
- /** Is packet service restricted by network */
- protected boolean mIsPsRestricted = false;
-
- /* Once disposed dont handle any messages */
- protected boolean mIsDisposed = false;
-
- protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- String action = intent.getAction();
- if (DBG) log("onReceive: action=" + action);
- if (action.equals(Intent.ACTION_SCREEN_ON)) {
- mIsScreenOn = true;
- stopNetStatPoll();
- startNetStatPoll();
- restartDataStallAlarm();
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- mIsScreenOn = false;
- stopNetStatPoll();
- startNetStatPoll();
- restartDataStallAlarm();
- } else if (action.startsWith(getActionIntentReconnectAlarm())) {
- log("Reconnect alarm. Previous state was " + mState);
- onActionIntentReconnectAlarm(intent);
- } else if (action.equals(getActionIntentDataStallAlarm())) {
- onActionIntentDataStallAlarm(intent);
- } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- final android.net.NetworkInfo networkInfo = (NetworkInfo)
- intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
- } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
- WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
- if (!enabled) {
- // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
- // quit and won't report disconnected until next enabling.
- mIsWifiConnected = false;
- }
- } else if (action.equals(INTENT_SET_FAIL_DATA_SETUP_COUNTER)) {
- mFailDataSetupCounter = intent.getIntExtra(FAIL_DATA_SETUP_COUNTER, 1);
- mFailDataSetupFailCause = FailCause.fromInt(
- intent.getIntExtra(FAIL_DATA_SETUP_FAIL_CAUSE,
- FailCause.ERROR_UNSPECIFIED.getErrorCode()));
- if (DBG) log("set mFailDataSetupCounter=" + mFailDataSetupCounter +
- " mFailDataSetupFailCause=" + mFailDataSetupFailCause);
- }
- }
- };
-
- private final DataRoamingSettingObserver mDataRoamingSettingObserver;
-
- private class DataRoamingSettingObserver extends ContentObserver {
- public DataRoamingSettingObserver(Handler handler) {
- super(handler);
- }
-
- public void register(Context context) {
- final ContentResolver resolver = context.getContentResolver();
- resolver.registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.DATA_ROAMING), false, this);
- }
-
- public void unregister(Context context) {
- final ContentResolver resolver = context.getContentResolver();
- resolver.unregisterContentObserver(this);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- // already running on mPhone handler thread
- handleDataOnRoamingChange();
- }
- }
-
- /**
- * Maintian the sum of transmit and receive packets.
- *
- * The packet counts are initizlied and reset to -1 and
- * remain -1 until they can be updated.
- */
- public class TxRxSum {
- public long txPkts;
- public long rxPkts;
-
- public TxRxSum() {
- reset();
- }
-
- public TxRxSum(long txPkts, long rxPkts) {
- this.txPkts = txPkts;
- this.rxPkts = rxPkts;
- }
-
- public TxRxSum(TxRxSum sum) {
- txPkts = sum.txPkts;
- rxPkts = sum.rxPkts;
- }
-
- public void reset() {
- txPkts = -1;
- rxPkts = -1;
- }
-
- public String toString() {
- return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
- }
-
- public void updateTxRxSum() {
- boolean txUpdated = false, rxUpdated = false;
- long txSum = 0, rxSum = 0;
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.getState() == State.CONNECTED) {
- DataConnectionAc dcac = apnContext.getDataConnectionAc();
- if (dcac == null) continue;
-
- LinkProperties linkProp = dcac.getLinkPropertiesSync();
- if (linkProp == null) continue;
-
- String iface = linkProp.getInterfaceName();
-
- if (iface != null) {
- long stats = TrafficStats.getTxPackets(iface);
- if (stats > 0) {
- txUpdated = true;
- txSum += stats;
- }
- stats = TrafficStats.getRxPackets(iface);
- if (stats > 0) {
- rxUpdated = true;
- rxSum += stats;
- }
- }
- }
- }
- if (txUpdated) this.txPkts = txSum;
- if (rxUpdated) this.rxPkts = rxSum;
- }
- }
-
- protected boolean isDataSetupCompleteOk(AsyncResult ar) {
- if (ar.exception != null) {
- if (DBG) log("isDataSetupCompleteOk return false, ar.result=" + ar.result);
- return false;
- }
- if (mFailDataSetupCounter <= 0) {
- if (DBG) log("isDataSetupCompleteOk return true");
- return true;
- }
- ar.result = mFailDataSetupFailCause;
- if (DBG) {
- log("isDataSetupCompleteOk return false" +
- " mFailDataSetupCounter=" + mFailDataSetupCounter +
- " mFailDataSetupFailCause=" + mFailDataSetupFailCause);
- }
- mFailDataSetupCounter -= 1;
- return false;
- }
-
- protected void onActionIntentReconnectAlarm(Intent intent) {
- String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
- if (mState == State.FAILED) {
- Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
- msg.arg1 = 0; // tearDown is false
- msg.arg2 = 0;
- msg.obj = reason;
- sendMessage(msg);
- }
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
- }
-
- protected void onActionIntentDataStallAlarm(Intent intent) {
- if (VDBG) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
- Message msg = obtainMessage(EVENT_DATA_STALL_ALARM, intent.getAction());
- msg.arg1 = intent.getIntExtra(DATA_STALL_ALARM_TAG_EXTRA, 0);
- sendMessage(msg);
- }
-
- /**
- * Default constructor
- */
- protected DataConnectionTracker(PhoneBase phone) {
- super();
- if (DBG) log("DCT.constructor");
- mPhone = phone;
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(getActionIntentReconnectAlarm());
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
- filter.addAction(INTENT_SET_FAIL_DATA_SETUP_COUNTER);
-
- mUserDataEnabled = Settings.Secure.getInt(
- mPhone.getContext().getContentResolver(), Settings.Secure.MOBILE_DATA, 1) == 1;
-
- // TODO: Why is this registering the phone as the receiver of the intent
- // and not its own handler?
- mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
-
- // This preference tells us 1) initial condition for "dataEnabled",
- // and 2) whether the RIL will setup the baseband to auto-PS attach.
-
- dataEnabled[APN_DEFAULT_ID] = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP,
- true);
- if (dataEnabled[APN_DEFAULT_ID]) {
- enabledCount++;
- }
-
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
- mAutoAttachOnCreation = sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false);
-
- // watch for changes to Settings.Secure.DATA_ROAMING
- mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone);
- mDataRoamingSettingObserver.register(mPhone.getContext());
- }
-
- public void dispose() {
- if (DBG) log("DCT.dispose");
- for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
- dcac.disconnect();
- }
- mDataConnectionAsyncChannels.clear();
- mIsDisposed = true;
- mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
- mDataRoamingSettingObserver.unregister(mPhone.getContext());
- }
-
- protected void broadcastMessenger() {
- Intent intent = new Intent(ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
- intent.putExtra(EXTRA_MESSENGER, new Messenger(this));
- mPhone.getContext().sendBroadcast(intent);
- }
-
- public Activity getActivity() {
- return mActivity;
- }
-
- public boolean isApnTypeActive(String type) {
- // TODO: support simultaneous with List instead
- if (Phone.APN_TYPE_DUN.equals(type)) {
- ApnSetting dunApn = fetchDunApn();
- if (dunApn != null) {
- return ((mActiveApn != null) && (dunApn.toString().equals(mActiveApn.toString())));
- }
- }
- return mActiveApn != null && mActiveApn.canHandleType(type);
- }
-
- protected ApnSetting fetchDunApn() {
- if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) {
- log("fetchDunApn: net.tethering.noprovisioning=true ret: null");
- return null;
- }
- Context c = mPhone.getContext();
- String apnData = Settings.Secure.getString(c.getContentResolver(),
- Settings.Secure.TETHER_DUN_APN);
- ApnSetting dunSetting = ApnSetting.fromString(apnData);
- if (dunSetting != null) {
- if (VDBG) log("fetchDunApn: secure TETHER_DUN_APN dunSetting=" + dunSetting);
- return dunSetting;
- }
-
- apnData = c.getResources().getString(R.string.config_tether_apndata);
- dunSetting = ApnSetting.fromString(apnData);
- if (VDBG) log("fetchDunApn: config_tether_apndata dunSetting=" + dunSetting);
- return dunSetting;
- }
-
- public String[] getActiveApnTypes() {
- String[] result;
- if (mActiveApn != null) {
- result = mActiveApn.types;
- } else {
- result = new String[1];
- result[0] = Phone.APN_TYPE_DEFAULT;
- }
- return result;
- }
-
- /** TODO: See if we can remove */
- public String getActiveApnString(String apnType) {
- String result = null;
- if (mActiveApn != null) {
- result = mActiveApn.apn;
- }
- return result;
- }
-
- /**
- * Modify {@link Settings.Secure#DATA_ROAMING} value.
- */
- public void setDataOnRoamingEnabled(boolean enabled) {
- if (getDataOnRoamingEnabled() != enabled) {
- final ContentResolver resolver = mPhone.getContext().getContentResolver();
- Settings.Secure.putInt(resolver, Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
- // will trigger handleDataOnRoamingChange() through observer
- }
- }
-
- /**
- * Return current {@link Settings.Secure#DATA_ROAMING} value.
- */
- public boolean getDataOnRoamingEnabled() {
- try {
- final ContentResolver resolver = mPhone.getContext().getContentResolver();
- return Settings.Secure.getInt(resolver, Settings.Secure.DATA_ROAMING) != 0;
- } catch (SettingNotFoundException snfe) {
- return false;
- }
- }
-
- private void handleDataOnRoamingChange() {
- if (mPhone.getServiceState().getRoaming()) {
- if (getDataOnRoamingEnabled()) {
- resetAllRetryCounts();
- }
- sendMessage(obtainMessage(EVENT_ROAMING_ON));
- }
- }
-
- // abstract methods
- protected abstract String getActionIntentReconnectAlarm();
- protected abstract String getActionIntentDataStallAlarm();
- protected abstract void startNetStatPoll();
- protected abstract void stopNetStatPoll();
- protected abstract void restartDataStallAlarm();
- protected abstract void restartRadio();
- protected abstract void log(String s);
- protected abstract void loge(String s);
- protected abstract boolean isDataAllowed();
- protected abstract boolean isApnTypeAvailable(String type);
- public abstract State getState(String apnType);
- protected abstract void setState(State s);
- protected abstract void gotoIdleAndNotifyDataConnection(String reason);
-
- protected abstract boolean onTrySetupData(String reason);
- 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(int connId, AsyncResult ar);
- protected abstract void onVoiceCallStarted();
- protected abstract void onVoiceCallEnded();
- protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
- protected abstract void onCleanUpAllConnections(String cause);
- protected abstract boolean isDataPossible(String apnType);
-
- protected void onDataStallAlarm(int tag) {
- loge("onDataStallAlarm: not impleted tag=" + tag);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- log("DISCONNECTED_CONNECTED: msg=" + msg);
- DataConnectionAc dcac = (DataConnectionAc) msg.obj;
- mDataConnectionAsyncChannels.remove(dcac.dataConnection.getDataConnectionId());
- dcac.disconnected();
- break;
- }
- case EVENT_ENABLE_NEW_APN:
- onEnableApn(msg.arg1, msg.arg2);
- break;
-
- case EVENT_TRY_SETUP_DATA:
- String reason = null;
- if (msg.obj instanceof String) {
- reason = (String) msg.obj;
- }
- onTrySetupData(reason);
- break;
-
- case EVENT_DATA_STALL_ALARM:
- onDataStallAlarm(msg.arg1);
- break;
-
- case EVENT_ROAMING_OFF:
- if (getDataOnRoamingEnabled() == false) {
- resetAllRetryCounts();
- }
- 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:
- mCidActive = msg.arg1;
- onDataSetupComplete((AsyncResult) msg.obj);
- break;
-
- case EVENT_DISCONNECT_DONE:
- log("DataConnectoinTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
- onDisconnectDone(msg.arg1, (AsyncResult) msg.obj);
- break;
-
- case EVENT_VOICE_CALL_STARTED:
- onVoiceCallStarted();
- break;
-
- case EVENT_VOICE_CALL_ENDED:
- onVoiceCallEnded();
- break;
-
- case EVENT_CLEAN_UP_ALL_CONNECTIONS: {
- onCleanUpAllConnections((String) msg.obj);
- break;
- }
- case EVENT_CLEAN_UP_CONNECTION: {
- boolean tearDown = (msg.arg1 == 0) ? false : true;
- onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
- break;
- }
- case EVENT_SET_INTERNAL_DATA_ENABLE: {
- boolean enabled = (msg.arg1 == ENABLED) ? true : false;
- onSetInternalDataEnabled(enabled);
- break;
- }
- case EVENT_RESET_DONE: {
- if (DBG) log("EVENT_RESET_DONE");
- onResetDone((AsyncResult) msg.obj);
- break;
- }
- case CMD_SET_USER_DATA_ENABLE: {
- final boolean enabled = (msg.arg1 == ENABLED) ? true : false;
- if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
- onSetUserDataEnabled(enabled);
- break;
- }
- case CMD_SET_DEPENDENCY_MET: {
- boolean met = (msg.arg1 == ENABLED) ? true : false;
- if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
- Bundle bundle = msg.getData();
- if (bundle != null) {
- String apnType = (String)bundle.get(APN_TYPE_KEY);
- if (apnType != null) {
- onSetDependencyMet(apnType, met);
- }
- }
- break;
- }
- case CMD_SET_POLICY_DATA_ENABLE: {
- final boolean enabled = (msg.arg1 == ENABLED) ? true : false;
- onSetPolicyDataEnabled(enabled);
- break;
- }
- default:
- Log.e("DATA", "Unidentified event msg=" + msg);
- break;
- }
- }
-
- /**
- * Report on whether data connectivity is enabled
- *
- * @return {@code false} if data connectivity has been explicitly disabled,
- * {@code true} otherwise.
- */
- public boolean getAnyDataEnabled() {
- final boolean result;
- synchronized (mDataEnabledLock) {
- result = (mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled
- && (enabledCount != 0));
- }
- if (!result && DBG) log("getAnyDataEnabled " + result);
- return result;
- }
-
- protected boolean isEmergency() {
- final boolean result;
- synchronized (mDataEnabledLock) {
- result = mPhone.isInEcm() || mPhone.isInEmergencyCall();
- }
- log("isEmergency: result=" + result);
- return result;
- }
-
- protected int apnTypeToId(String type) {
- if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) {
- return APN_DEFAULT_ID;
- } else if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
- return APN_MMS_ID;
- } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) {
- return APN_SUPL_ID;
- } else if (TextUtils.equals(type, Phone.APN_TYPE_DUN)) {
- return APN_DUN_ID;
- } else if (TextUtils.equals(type, Phone.APN_TYPE_HIPRI)) {
- return APN_HIPRI_ID;
- } else if (TextUtils.equals(type, Phone.APN_TYPE_IMS)) {
- return APN_IMS_ID;
- } else if (TextUtils.equals(type, Phone.APN_TYPE_FOTA)) {
- return APN_FOTA_ID;
- } else if (TextUtils.equals(type, Phone.APN_TYPE_CBS)) {
- return APN_CBS_ID;
- } else {
- return APN_INVALID_ID;
- }
- }
-
- protected String apnIdToType(int id) {
- switch (id) {
- case APN_DEFAULT_ID:
- return Phone.APN_TYPE_DEFAULT;
- case APN_MMS_ID:
- return Phone.APN_TYPE_MMS;
- case APN_SUPL_ID:
- return Phone.APN_TYPE_SUPL;
- case APN_DUN_ID:
- return Phone.APN_TYPE_DUN;
- case APN_HIPRI_ID:
- return Phone.APN_TYPE_HIPRI;
- case APN_IMS_ID:
- return Phone.APN_TYPE_IMS;
- case APN_FOTA_ID:
- return Phone.APN_TYPE_FOTA;
- case APN_CBS_ID:
- return Phone.APN_TYPE_CBS;
- default:
- log("Unknown id (" + id + ") in apnIdToType");
- return Phone.APN_TYPE_DEFAULT;
- }
- }
-
- protected LinkProperties getLinkProperties(String apnType) {
- int id = apnTypeToId(apnType);
-
- if (isApnIdEnabled(id)) {
- // TODO - remove this cdma-only hack and support multiple DCs.
- DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0);
- return dcac.getLinkPropertiesSync();
- } else {
- return new LinkProperties();
- }
- }
-
- protected LinkCapabilities getLinkCapabilities(String apnType) {
- int id = apnTypeToId(apnType);
- if (isApnIdEnabled(id)) {
- // TODO - remove this cdma-only hack and support multiple DCs.
- DataConnectionAc dcac = mDataConnectionAsyncChannels.get(0);
- return dcac.getLinkCapabilitiesSync();
- } else {
- return new LinkCapabilities();
- }
- }
-
- // tell all active apns of the current condition
- protected void notifyDataConnection(String reason) {
- for (int id = 0; id < APN_NUM_TYPES; id++) {
- if (dataEnabled[id]) {
- mPhone.notifyDataConnection(reason, apnIdToType(id));
- }
- }
- notifyOffApnsOfAvailability(reason);
- }
-
- // a new APN has gone active and needs to send events to catch up with the
- // current condition
- private void notifyApnIdUpToCurrent(String reason, int apnId) {
- switch (mState) {
- case IDLE:
- case INITING:
- break;
- case CONNECTING:
- case SCANNING:
- mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
- break;
- case CONNECTED:
- case DISCONNECTING:
- mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
- mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTED);
- break;
- }
- }
-
- // since we normally don't send info to a disconnected APN, we need to do this specially
- private void notifyApnIdDisconnected(String reason, int apnId) {
- mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.DISCONNECTED);
- }
-
- // disabled apn's still need avail/unavail notificiations - send them out
- protected void notifyOffApnsOfAvailability(String reason) {
- if (DBG) log("notifyOffApnsOfAvailability - reason= " + reason);
- for (int id = 0; id < APN_NUM_TYPES; id++) {
- if (!isApnIdEnabled(id)) {
- notifyApnIdDisconnected(reason, id);
- }
- }
- }
-
- public boolean isApnTypeEnabled(String apnType) {
- if (apnType == null) {
- return false;
- } else {
- return isApnIdEnabled(apnTypeToId(apnType));
- }
- }
-
- protected synchronized boolean isApnIdEnabled(int id) {
- if (id != APN_INVALID_ID) {
- return dataEnabled[id];
- }
- return false;
- }
-
- /**
- * Ensure that we are connected to an APN of the specified type.
- *
- * @param type the APN type (currently the only valid values are
- * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
- * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
- * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
- * broadcast will be sent by the ConnectivityManager when a
- * connection to the APN has been established.
- */
- public synchronized int enableApnType(String type) {
- int id = apnTypeToId(type);
- if (id == APN_INVALID_ID) {
- return Phone.APN_REQUEST_FAILED;
- }
-
- if (DBG) {
- log("enableApnType(" + type + "), isApnTypeActive = " + isApnTypeActive(type)
- + ", isApnIdEnabled =" + isApnIdEnabled(id) + " and state = " + mState);
- }
-
- if (!isApnTypeAvailable(type)) {
- if (DBG) log("type not available");
- return Phone.APN_TYPE_NOT_AVAILABLE;
- }
-
- if (isApnIdEnabled(id)) {
- return Phone.APN_ALREADY_ACTIVE;
- } else {
- setEnabled(id, true);
- }
- return Phone.APN_REQUEST_STARTED;
- }
-
- /**
- * The APN of the specified type is no longer needed. Ensure that if use of
- * the default APN has not been explicitly disabled, we are connected to the
- * default APN.
- *
- * @param type the APN type. The only valid values are currently
- * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
- * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
- * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
- * broadcast will be sent by the ConnectivityManager when a
- * connection to the APN has been disconnected. A {@code
- * Phone.APN_REQUEST_FAILED} is returned if the type parameter is
- * invalid or if the apn wasn't enabled.
- */
- public synchronized int disableApnType(String type) {
- if (DBG) log("disableApnType(" + type + ")");
- int id = apnTypeToId(type);
- if (id == APN_INVALID_ID) {
- return Phone.APN_REQUEST_FAILED;
- }
- if (isApnIdEnabled(id)) {
- setEnabled(id, false);
- if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
- if (dataEnabled[APN_DEFAULT_ID]) {
- return Phone.APN_ALREADY_ACTIVE;
- } else {
- return Phone.APN_REQUEST_STARTED;
- }
- } else {
- return Phone.APN_REQUEST_STARTED;
- }
- } else {
- return Phone.APN_REQUEST_FAILED;
- }
- }
-
- protected void setEnabled(int id, boolean enable) {
- if (DBG) {
- log("setEnabled(" + id + ", " + enable + ") with old state = " + dataEnabled[id]
- + " and enabledCount = " + enabledCount);
- }
- Message msg = obtainMessage(EVENT_ENABLE_NEW_APN);
- msg.arg1 = id;
- msg.arg2 = (enable ? ENABLED : DISABLED);
- sendMessage(msg);
- }
-
- protected void onEnableApn(int apnId, int enabled) {
- if (DBG) {
- log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) +
- ", enabled=" + enabled + ", dataEnabled = " + dataEnabled[apnId] +
- ", enabledCount = " + enabledCount + ", isApnTypeActive = " +
- isApnTypeActive(apnIdToType(apnId)));
- }
- if (enabled == ENABLED) {
- synchronized (this) {
- if (!dataEnabled[apnId]) {
- dataEnabled[apnId] = true;
- enabledCount++;
- }
- }
- String type = apnIdToType(apnId);
- if (!isApnTypeActive(type)) {
- mRequestedApnType = type;
- onEnableNewApn();
- } else {
- notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId);
- }
- } else {
- // disable
- boolean didDisable = false;
- synchronized (this) {
- if (dataEnabled[apnId]) {
- dataEnabled[apnId] = false;
- enabledCount--;
- didDisable = true;
- }
- }
- if (didDisable) {
- if ((enabledCount == 0) || (apnId == APN_DUN_ID)) {
- mRequestedApnType = Phone.APN_TYPE_DEFAULT;
- onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
- }
-
- // send the disconnect msg manually, since the normal route wont send
- // it (it's not enabled)
- notifyApnIdDisconnected(Phone.REASON_DATA_DISABLED, apnId);
- if (dataEnabled[APN_DEFAULT_ID] == true
- && !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
- // TODO - this is an ugly way to restore the default conn - should be done
- // by a real contention manager and policy that disconnects the lower pri
- // stuff as enable requests come in and pops them back on as we disable back
- // down to the lower pri stuff
- mRequestedApnType = Phone.APN_TYPE_DEFAULT;
- onEnableNewApn();
- }
- }
- }
- }
-
- /**
- * Called when we switch APNs.
- *
- * mRequestedApnType is set prior to call
- * To be overridden.
- */
- protected void onEnableNewApn() {
- }
-
- /**
- * Called when EVENT_RESET_DONE is received so goto
- * IDLE state and send notifications to those interested.
- *
- * TODO - currently unused. Needs to be hooked into DataConnection cleanup
- * TODO - needs to pass some notion of which connection is reset..
- */
- protected void onResetDone(AsyncResult ar) {
- if (DBG) log("EVENT_RESET_DONE");
- String reason = null;
- if (ar.userObj instanceof String) {
- reason = (String) ar.userObj;
- }
- gotoIdleAndNotifyDataConnection(reason);
- }
-
- /**
- * 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 boolean setInternalDataEnabled(boolean enable) {
- if (DBG)
- log("setInternalDataEnabled(" + enable + ")");
-
- Message msg = obtainMessage(EVENT_SET_INTERNAL_DATA_ENABLE);
- msg.arg1 = (enable ? ENABLED : DISABLED);
- sendMessage(msg);
- return true;
- }
-
- protected void onSetInternalDataEnabled(boolean enabled) {
- synchronized (mDataEnabledLock) {
- mInternalDataEnabled = enabled;
- if (enabled) {
- log("onSetInternalDataEnabled: changed to enabled, try to setup data call");
- resetAllRetryCounts();
- onTrySetupData(Phone.REASON_DATA_ENABLED);
- } else {
- log("onSetInternalDataEnabled: changed to disabled, cleanUpAllConnections");
- cleanUpAllConnections(null);
- }
- }
- }
-
- public void cleanUpAllConnections(String cause) {
- Message msg = obtainMessage(EVENT_CLEAN_UP_ALL_CONNECTIONS);
- msg.obj = cause;
- sendMessage(msg);
- }
-
- public abstract boolean isDisconnected();
-
- protected void onSetUserDataEnabled(boolean enabled) {
- synchronized (mDataEnabledLock) {
- final boolean prevEnabled = getAnyDataEnabled();
- if (mUserDataEnabled != enabled) {
- mUserDataEnabled = enabled;
- Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
- Settings.Secure.MOBILE_DATA, enabled ? 1 : 0);
- if (getDataOnRoamingEnabled() == false &&
- mPhone.getServiceState().getRoaming() == true) {
- if (enabled) {
- notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
- } else {
- notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
- }
- }
- if (prevEnabled != getAnyDataEnabled()) {
- if (!prevEnabled) {
- resetAllRetryCounts();
- onTrySetupData(Phone.REASON_DATA_ENABLED);
- } else {
- onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
- }
- }
- }
- }
- }
-
- protected void onSetDependencyMet(String apnType, boolean met) {
- }
-
- protected void onSetPolicyDataEnabled(boolean enabled) {
- synchronized (mDataEnabledLock) {
- final boolean prevEnabled = getAnyDataEnabled();
- if (sPolicyDataEnabled != enabled) {
- sPolicyDataEnabled = enabled;
- if (prevEnabled != getAnyDataEnabled()) {
- if (!prevEnabled) {
- resetAllRetryCounts();
- onTrySetupData(Phone.REASON_DATA_ENABLED);
- } else {
- onCleanUpAllConnections(Phone.REASON_DATA_DISABLED);
- }
- }
- }
- }
- }
-
- protected String getReryConfig(boolean forDefault) {
- int nt = mPhone.getServiceState().getNetworkType();
-
- if ((nt == TelephonyManager.NETWORK_TYPE_CDMA) ||
- (nt == TelephonyManager.NETWORK_TYPE_1xRTT) ||
- (nt == TelephonyManager.NETWORK_TYPE_EVDO_0) ||
- (nt == TelephonyManager.NETWORK_TYPE_EVDO_A) ||
- (nt == TelephonyManager.NETWORK_TYPE_EVDO_B) ||
- (nt == TelephonyManager.NETWORK_TYPE_EHRPD)) {
- // CDMA variant
- return SystemProperties.get("ro.cdma.data_retry_config");
- } else {
- // Use GSM varient for all others.
- if (forDefault) {
- return SystemProperties.get("ro.gsm.data_retry_config");
- } else {
- return SystemProperties.get("ro.gsm.2nd_data_retry_config");
- }
- }
- }
-
- protected void resetAllRetryCounts() {
- for (ApnContext ac : mApnContexts.values()) {
- ac.setRetryCount(0);
- }
- for (DataConnection dc : mDataConnections.values()) {
- dc.resetRetryCount();
- }
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("DataConnectionTracker:");
- pw.println(" mInternalDataEnabled=" + mInternalDataEnabled);
- pw.println(" mUserDataEnabled=" + mUserDataEnabled);
- pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled);
- pw.println(" dataEnabled:");
- for(int i=0; i < dataEnabled.length; i++) {
- pw.printf(" dataEnabled[%d]=%b\n", i, dataEnabled[i]);
- }
- pw.flush();
- pw.println(" enabledCount=" + enabledCount);
- pw.println(" mRequestedApnType=" + mRequestedApnType);
- pw.println(" mPhone=" + mPhone.getPhoneName());
- pw.println(" mActivity=" + mActivity);
- pw.println(" mState=" + mState);
- pw.println(" mTxPkts=" + mTxPkts);
- pw.println(" mRxPkts=" + mRxPkts);
- pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
- pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
- pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
- pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
- pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
- pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
- pw.println(" mIsWifiConnected=" + mIsWifiConnected);
- pw.println(" mReconnectIntent=" + mReconnectIntent);
- pw.println(" mCidActive=" + mCidActive);
- pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation);
- pw.println(" mIsScreenOn=" + mIsScreenOn);
- pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
- pw.flush();
- pw.println(" ***************************************");
- Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
- pw.println(" mDataConnections: count=" + mDcSet.size());
- for (Entry<Integer, DataConnection> entry : mDcSet) {
- pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
- entry.getValue().dump(fd, pw, args);
- }
- pw.println(" ***************************************");
- pw.flush();
- Set<Entry<String, Integer>> mApnToDcIdSet = mApnToDataConnectionId.entrySet();
- pw.println(" mApnToDataConnectonId size=" + mApnToDcIdSet.size());
- for (Entry<String, Integer> entry : mApnToDcIdSet) {
- pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
- }
- pw.println(" ***************************************");
- pw.flush();
- if (mApnContexts != null) {
- Set<Entry<String, ApnContext>> mApnContextsSet = mApnContexts.entrySet();
- pw.println(" mApnContexts size=" + mApnContextsSet.size());
- for (Entry<String, ApnContext> entry : mApnContextsSet) {
- entry.getValue().dump(fd, pw, args);
- }
- pw.println(" ***************************************");
- } else {
- pw.println(" mApnContexts=null");
- }
- pw.flush();
- pw.println(" mActiveApn=" + mActiveApn);
- if (mAllApns != null) {
- pw.println(" mAllApns size=" + mAllApns.size());
- for (int i=0; i < mAllApns.size(); i++) {
- pw.printf(" mAllApns[%d]: %s\n", i, mAllApns.get(i));
- }
- pw.flush();
- } else {
- pw.println(" mAllApns=null");
- }
- pw.println(" mPreferredApn=" + mPreferredApn);
- pw.println(" mIsPsRestricted=" + mIsPsRestricted);
- pw.println(" mIsDisposed=" + mIsDisposed);
- pw.println(" mIntentReceiver=" + mIntentReceiver);
- pw.println(" mDataRoamingSettingObserver=" + mDataRoamingSettingObserver);
- pw.flush();
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
new file mode 100644
index 0000000..10ac153
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.telephony;
+
+import com.android.internal.util.Protocol;
+
+/**
+ * @hide
+ */
+public class DctConstants {
+ /**
+ * 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,
+ DORMANT
+ }
+
+ /***** Event Codes *****/
+ public static final int BASE = Protocol.BASE_DATA_CONNECTION_TRACKER;
+ public static final int EVENT_DATA_SETUP_COMPLETE = BASE + 0;
+ public static final int EVENT_RADIO_AVAILABLE = BASE + 1;
+ public static final int EVENT_RECORDS_LOADED = BASE + 2;
+ public static final int EVENT_TRY_SETUP_DATA = BASE + 3;
+ public static final int EVENT_DATA_STATE_CHANGED = BASE + 4;
+ public static final int EVENT_POLL_PDP = BASE + 5;
+ public static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6;
+ public static final int EVENT_VOICE_CALL_STARTED = BASE + 7;
+ public static final int EVENT_VOICE_CALL_ENDED = BASE + 8;
+ public static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9;
+ public static final int EVENT_LINK_STATE_CHANGED = BASE + 10;
+ public static final int EVENT_ROAMING_ON = BASE + 11;
+ public static final int EVENT_ROAMING_OFF = BASE + 12;
+ public static final int EVENT_ENABLE_NEW_APN = BASE + 13;
+ public static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14;
+ public static final int EVENT_DISCONNECT_DONE = BASE + 15;
+ public static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16;
+ public static final int EVENT_DATA_STALL_ALARM = BASE + 17;
+ public static final int EVENT_DO_RECOVERY = BASE + 18;
+ public static final int EVENT_APN_CHANGED = BASE + 19;
+ public static final int EVENT_CDMA_DATA_DETACHED = BASE + 20;
+ public static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21;
+ public static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22;
+ public static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
+ public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
+ public static final int EVENT_CDMA_OTA_PROVISION = BASE + 25;
+ public static final int EVENT_RESTART_RADIO = BASE + 26;
+ public static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27;
+ public static final int EVENT_RESET_DONE = BASE + 28;
+ public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 29;
+ public static final int CMD_SET_USER_DATA_ENABLE = BASE + 30;
+ public static final int CMD_SET_DEPENDENCY_MET = BASE + 31;
+ public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
+ public static final int EVENT_ICC_CHANGED = BASE + 33;
+
+ /***** Constants *****/
+
+ public static final int APN_INVALID_ID = -1;
+ public static final int APN_DEFAULT_ID = 0;
+ public static final int APN_MMS_ID = 1;
+ public static final int APN_SUPL_ID = 2;
+ public static final int APN_DUN_ID = 3;
+ public static final int APN_HIPRI_ID = 4;
+ public static final int APN_IMS_ID = 5;
+ public static final int APN_FOTA_ID = 6;
+ public static final int APN_CBS_ID = 7;
+ public static final int APN_NUM_TYPES = 8;
+
+ public static final int DISABLED = 0;
+ public static final int ENABLED = 1;
+
+ public static final String APN_TYPE_KEY = "apnType";
+ public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER =
+ "com.android.internal.telephony";
+ public static String EXTRA_MESSENGER = "EXTRA_MESSENGER";
+}
+
diff --git a/telephony/java/com/android/internal/telephony/DebugService.java b/telephony/java/com/android/internal/telephony/DebugService.java
deleted file mode 100644
index 29fea6e..0000000
--- a/telephony/java/com/android/internal/telephony/DebugService.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * A debug service that will dump telephony's state
- *
- * Currently this "Service" has a proxy in the phone app
- * com.android.phone.TelephonyDebugService which actually
- * invokes the dump method.
- */
-public class DebugService {
- private static String TAG = "DebugService";
-
- /** Constructor */
- public DebugService() {
- log("DebugService:");
- }
-
- /**
- * Dump the state of various objects, add calls to other objects as desired.
- */
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- log("dump: +");
- PhoneProxy phoneProxy = null;
- PhoneBase phoneBase = null;
-
- try {
- phoneProxy = (PhoneProxy) PhoneFactory.getDefaultPhone();
- } catch (Exception e) {
- pw.println("Telephony DebugService: Could not getDefaultPhone e=" + e);
- return;
- }
- try {
- phoneBase = (PhoneBase)phoneProxy.getActivePhone();
- } catch (Exception e) {
- pw.println("Telephony DebugService: Could not PhoneBase e=" + e);
- return;
- }
-
- /**
- * Surround each of the sub dump's with try/catch so even
- * if one fails we'll be able to dump the next ones.
- */
- pw.println();
- pw.println("++++++++++++++++++++++++++++++++");
- pw.flush();
- try {
- phoneBase.dump(fd, pw, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- pw.flush();
- pw.println("++++++++++++++++++++++++++++++++");
- try {
- phoneBase.mDataConnectionTracker.dump(fd, pw, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- pw.flush();
- pw.println("++++++++++++++++++++++++++++++++");
- try {
- phoneBase.getServiceStateTracker().dump(fd, pw, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- pw.flush();
- pw.println("++++++++++++++++++++++++++++++++");
- try {
- phoneBase.getCallTracker().dump(fd, pw, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- pw.flush();
- pw.println("++++++++++++++++++++++++++++++++");
- try {
- ((RIL)phoneBase.mCM).dump(fd, pw, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- pw.flush();
- pw.println("++++++++++++++++++++++++++++++++");
- log("dump: -");
- }
-
- private static void log(String s) {
- Log.d(TAG, "DebugService " + s);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
deleted file mode 100644
index eb78a53e..0000000
--- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * 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.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.CellInfo;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import com.android.internal.telephony.ITelephonyRegistry;
-
-/**
- * broadcast intents
- */
-public class DefaultPhoneNotifier implements PhoneNotifier {
-
- static final String LOG_TAG = "GSM";
- private static final boolean DBG = true;
- private ITelephonyRegistry mRegistry;
-
- /*package*/
- DefaultPhoneNotifier() {
- mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- }
-
- public void notifyPhoneState(Phone sender) {
- Call ringingCall = sender.getRingingCall();
- String incomingNumber = "";
- if (ringingCall != null && ringingCall.getEarliestConnection() != null){
- incomingNumber = ringingCall.getEarliestConnection().getAddress();
- }
- try {
- mRegistry.notifyCallState(convertCallState(sender.getState()), incomingNumber);
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifyServiceState(Phone sender) {
- ServiceState ss = sender.getServiceState();
- if (ss == null) {
- ss = new ServiceState();
- ss.setStateOutOfService();
- }
- try {
- mRegistry.notifyServiceState(ss);
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifySignalStrength(Phone sender) {
- try {
- mRegistry.notifySignalStrength(sender.getSignalStrength());
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifyMessageWaitingChanged(Phone sender) {
- try {
- mRegistry.notifyMessageWaitingChanged(sender.getMessageWaitingIndicator());
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifyCallForwardingChanged(Phone sender) {
- try {
- mRegistry.notifyCallForwardingChanged(sender.getCallForwardingIndicator());
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifyDataActivity(Phone sender) {
- try {
- mRegistry.notifyDataActivity(convertDataActivityState(sender.getDataActivityState()));
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifyDataConnection(Phone sender, String reason, String apnType,
- Phone.DataState state) {
- doNotifyDataConnection(sender, reason, apnType, state);
- }
-
- private void doNotifyDataConnection(Phone sender, String reason, String apnType,
- Phone.DataState state) {
- // TODO
- // use apnType as the key to which connection we're talking about.
- // pass apnType back up to fetch particular for this one.
- TelephonyManager telephony = TelephonyManager.getDefault();
- LinkProperties linkProperties = null;
- LinkCapabilities linkCapabilities = null;
- boolean roaming = false;
-
- if (state == Phone.DataState.CONNECTED) {
- linkProperties = sender.getLinkProperties(apnType);
- linkCapabilities = sender.getLinkCapabilities(apnType);
- }
- ServiceState ss = sender.getServiceState();
- if (ss != null) roaming = ss.getRoaming();
-
- try {
- mRegistry.notifyDataConnection(
- convertDataState(state),
- sender.isDataConnectivityPossible(apnType), reason,
- sender.getActiveApnHost(apnType),
- apnType,
- linkProperties,
- linkCapabilities,
- ((telephony!=null) ? telephony.getNetworkType() :
- TelephonyManager.NETWORK_TYPE_UNKNOWN),
- roaming);
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
- try {
- mRegistry.notifyDataConnectionFailed(reason, apnType);
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifyCellLocation(Phone sender) {
- Bundle data = new Bundle();
- sender.getCellLocation().fillInNotifierBundle(data);
- try {
- mRegistry.notifyCellLocation(data);
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
- try {
- mRegistry.notifyCellInfo(cellInfo);
- } catch (RemoteException ex) {
-
- }
- }
-
- public void notifyOtaspChanged(Phone sender, int otaspMode) {
- try {
- mRegistry.notifyOtaspChanged(otaspMode);
- } catch (RemoteException ex) {
- // system process is dead
- }
- }
-
- private void log(String s) {
- Log.d(LOG_TAG, "[PhoneNotifier] " + s);
- }
-
- /**
- * Convert the {@link State} enum into the TelephonyManager.CALL_STATE_* constants
- * for the public API.
- */
- public static int convertCallState(Phone.State state) {
- switch (state) {
- case RINGING:
- return TelephonyManager.CALL_STATE_RINGING;
- case OFFHOOK:
- return TelephonyManager.CALL_STATE_OFFHOOK;
- default:
- return TelephonyManager.CALL_STATE_IDLE;
- }
- }
-
- /**
- * Convert the TelephonyManager.CALL_STATE_* constants into the {@link State} enum
- * for the public API.
- */
- public static Phone.State convertCallState(int state) {
- switch (state) {
- case TelephonyManager.CALL_STATE_RINGING:
- return Phone.State.RINGING;
- case TelephonyManager.CALL_STATE_OFFHOOK:
- return Phone.State.OFFHOOK;
- default:
- return Phone.State.IDLE;
- }
- }
-
- /**
- * Convert the {@link DataState} enum into the TelephonyManager.DATA_* constants
- * for the public API.
- */
- public static int convertDataState(Phone.DataState state) {
- switch (state) {
- case CONNECTING:
- return TelephonyManager.DATA_CONNECTING;
- case CONNECTED:
- return TelephonyManager.DATA_CONNECTED;
- case SUSPENDED:
- return TelephonyManager.DATA_SUSPENDED;
- default:
- return TelephonyManager.DATA_DISCONNECTED;
- }
- }
-
- /**
- * Convert the TelephonyManager.DATA_* constants into {@link DataState} enum
- * for the public API.
- */
- public static Phone.DataState convertDataState(int state) {
- switch (state) {
- case TelephonyManager.DATA_CONNECTING:
- return Phone.DataState.CONNECTING;
- case TelephonyManager.DATA_CONNECTED:
- return Phone.DataState.CONNECTED;
- case TelephonyManager.DATA_SUSPENDED:
- return Phone.DataState.SUSPENDED;
- default:
- return Phone.DataState.DISCONNECTED;
- }
- }
-
- /**
- * Convert the {@link DataState} enum into the TelephonyManager.DATA_* constants
- * for the public API.
- */
- public static int convertDataActivityState(Phone.DataActivityState state) {
- switch (state) {
- case DATAIN:
- return TelephonyManager.DATA_ACTIVITY_IN;
- case DATAOUT:
- return TelephonyManager.DATA_ACTIVITY_OUT;
- case DATAINANDOUT:
- return TelephonyManager.DATA_ACTIVITY_INOUT;
- case DORMANT:
- return TelephonyManager.DATA_ACTIVITY_DORMANT;
- default:
- return TelephonyManager.DATA_ACTIVITY_NONE;
- }
- }
-
- /**
- * Convert the TelephonyManager.DATA_* constants into the {@link DataState} enum
- * for the public API.
- */
- public static Phone.DataActivityState convertDataActivityState(int state) {
- switch (state) {
- case TelephonyManager.DATA_ACTIVITY_IN:
- return Phone.DataActivityState.DATAIN;
- case TelephonyManager.DATA_ACTIVITY_OUT:
- return Phone.DataActivityState.DATAOUT;
- case TelephonyManager.DATA_ACTIVITY_INOUT:
- return Phone.DataActivityState.DATAINANDOUT;
- case TelephonyManager.DATA_ACTIVITY_DORMANT:
- return Phone.DataActivityState.DORMANT;
- default:
- return Phone.DataActivityState.NONE;
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/DriverCall.java b/telephony/java/com/android/internal/telephony/DriverCall.java
deleted file mode 100644
index 663c284..0000000
--- a/telephony/java/com/android/internal/telephony/DriverCall.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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 com.android.internal.telephony.*;
-import android.util.Log;
-import java.lang.Comparable;
-import android.telephony.PhoneNumberUtils;
-
-/**
- * {@hide}
- */
-public class DriverCall implements Comparable {
- static final String LOG_TAG = "RILB";
-
- public enum State {
- ACTIVE,
- HOLDING,
- DIALING, // MO call only
- ALERTING, // MO call only
- INCOMING, // MT call only
- WAITING; // MT call only
- // If you add a state, make sure to look for the switch()
- // statements that use this enum
- }
-
- public int index;
- public boolean isMT;
- public State state; // May be null if unavail
- public boolean isMpty;
- public String number;
- public int TOA;
- public boolean isVoice;
- public boolean isVoicePrivacy;
- public int als;
- public int numberPresentation;
- public String name;
- public int namePresentation;
- public UUSInfo uusInfo;
-
- /** returns null on error */
- static DriverCall
- fromCLCCLine(String line) {
- DriverCall ret = new DriverCall();
-
- //+CLCC: 1,0,2,0,0,\"+18005551212\",145
- // index,isMT,state,mode,isMpty(,number,TOA)?
- ATResponseParser p = new ATResponseParser(line);
-
- try {
- ret.index = p.nextInt();
- ret.isMT = p.nextBoolean();
- ret.state = stateFromCLCC(p.nextInt());
-
- 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
- ret.number = PhoneNumberUtils.extractNetworkPortionAlt(p.nextString());
-
- if (ret.number.length() == 0) {
- ret.number = null;
- }
-
- ret.TOA = p.nextInt();
-
- // Make sure there's a leading + on addresses with a TOA
- // of 145
-
- ret.number = PhoneNumberUtils.stringFromStringAndTOA(
- ret.number, ret.TOA);
-
- }
- } catch (ATParseEx ex) {
- Log.e(LOG_TAG,"Invalid CLCC line: '" + line + "'");
- return null;
- }
-
- return ret;
- }
-
- public
- DriverCall() {
- }
-
- public String
- toString() {
- return "id=" + index + ","
- + state + ","
- + "toa=" + TOA + ","
- + (isMpty ? "conf" : "norm") + ","
- + (isMT ? "mt" : "mo") + ","
- + als + ","
- + (isVoice ? "voc" : "nonvoc") + ","
- + (isVoicePrivacy ? "evp" : "noevp") + ","
- /*+ "number=" + number */ + ",cli=" + numberPresentation + ","
- /*+ "name="+ name */ + "," + namePresentation;
- }
-
- public static State
- stateFromCLCC(int state) throws ATParseEx {
- switch(state) {
- case 0: return State.ACTIVE;
- case 1: return State.HOLDING;
- case 2: return State.DIALING;
- case 3: return State.ALERTING;
- case 4: return State.INCOMING;
- case 5: return State.WAITING;
- default:
- throw new ATParseEx("illegal call state " + state);
- }
- }
-
- public static int
- presentationFromCLIP(int cli) throws ATParseEx
- {
- switch(cli) {
- case 0: return Connection.PRESENTATION_ALLOWED;
- case 1: return Connection.PRESENTATION_RESTRICTED;
- case 2: return Connection.PRESENTATION_UNKNOWN;
- case 3: return Connection.PRESENTATION_PAYPHONE;
- default:
- throw new ATParseEx("illegal presentation " + cli);
- }
- }
-
- //***** Comparable Implementation
-
- /** For sorting by index */
- public int
- compareTo (Object o) {
- DriverCall dc;
-
- dc = (DriverCall)o;
-
- if (index < dc.index) {
- return -1;
- } else if (index == dc.index) {
- return 0;
- } else { /*index > dc.index*/
- return 1;
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/EventLogTags.logtags b/telephony/java/com/android/internal/telephony/EventLogTags.logtags
deleted file mode 100644
index 427e5da..0000000
--- a/telephony/java/com/android/internal/telephony/EventLogTags.logtags
+++ /dev/null
@@ -1,73 +0,0 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
-
-option java_package com.android.internal.telephony;
-
-# PDP Context has a bad DNS address
-50100 pdp_bad_dns_address (dns_address|3)
-
-# For data connection on PDP context, reached the data-out-without-data-in
-# packet count that triggers a countdown to radio restart
-50101 pdp_radio_reset_countdown_triggered (out_packet_count|1|1)
-
-# Radio restart - timed out with no incoming packets.
-50102 pdp_radio_reset (out_packet_count|1|1)
-
-# PDP context reset - timed out with no incoming packets.
-50103 pdp_context_reset (out_packet_count|1|1)
-
-# Reregister to data network - timed out with no incoming packets.
-50104 pdp_reregister_network (out_packet_count|1|1)
-
-# PDP Setup failures
-50105 pdp_setup_fail (cause|1|5), (cid|1|5), (network_type|1|5)
-
-# Call drops
-50106 call_drop (cause|1|5), (cid|1|5), (network_type|1|5)
-
-# Data network registration failed after successful voice registration
-50107 data_network_registration_fail (op_numeric|1|5), (cid|1|5)
-
-# Suspicious status of data connection while radio poweroff
-50108 data_network_status_on_radio_off (dc_state|3), (enable|1|5)
-
-# PDP drop caused by network
-50109 pdp_network_drop (cid|1|5), (network_type|1|5)
-
-# CDMA data network setup failure
-50110 cdma_data_setup_failed (cause|1|5), (cid|1|5), (network_type|1|5)
-
-# CDMA data network drop
-50111 cdma_data_drop (cid|1|5), (network_type|1|5)
-
-# GSM radio access technology switched
-50112 gsm_rat_switched (cid|1|5), (network_from|1|5), (network_to|1|5)
-
-# GSM data connection state transition
-50113 gsm_data_state_change (oldState|3), (newState|3)
-
-# GSM service state transition
-50114 gsm_service_state_change (oldState|1|5), (oldGprsState|1|5), (newState|1|5), (newGprsState|1|5)
-
-# CDMA data connection state transition
-50115 cdma_data_state_change (oldState|3), (newState|3)
-
-# CDMA service state transition
-50116 cdma_service_state_change (oldState|1|5), (oldDataState|1|5), (newState|1|5), (newDataState|1|5)
-
-# Bad IP address
-50117 bad_ip_address (ip_address|3)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_GET_DATA_CALL_LIST
-50118 data_stall_recovery_get_data_call_list (out_packet_count|1|1)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_CLEANUP
-50119 data_stall_recovery_cleanup (out_packet_count|1|1)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_REREGISTER
-50120 data_stall_recovery_reregister (out_packet_count|1|1)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART
-50121 data_stall_recovery_radio_restart (out_packet_count|1|1)
-
-# Data Stall Recovery mode DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP
-50122 data_stall_recovery_radio_restart_with_prop (out_packet_count|1|1)
diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
index 25647ac..04b1220 100644
--- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/java/com/android/internal/telephony/GsmAlphabet.java
@@ -24,15 +24,12 @@
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
+import com.android.internal.telephony.SmsConstants;
import com.android.internal.R;
import java.util.ArrayList;
import java.util.List;
-import static android.telephony.SmsMessage.ENCODING_7BIT;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS;
-import static android.telephony.SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER;
-
/**
* This class implements the character set mapping between
* the GSM SMS 7-bit alphabet specified in TS 23.038 6.2.1
@@ -45,8 +42,6 @@
private GsmAlphabet() { }
- //***** Constants
-
/**
* This escapes extended characters, and when present indicates that the
* following character should be looked up in the "extended" table.
@@ -81,6 +76,60 @@
public static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
/**
+ * For a specific text string, this object describes protocol
+ * properties of encoding it for transmission as message user
+ * data.
+ */
+ public static class TextEncodingDetails {
+ /**
+ *The number of SMS's required to encode the text.
+ */
+ public int msgCount;
+
+ /**
+ * The number of code units consumed so far, where code units
+ * are basically characters in the encoding -- for example,
+ * septets for the standard ASCII and GSM encodings, and 16
+ * bits for Unicode.
+ */
+ public int codeUnitCount;
+
+ /**
+ * How many code units are still available without spilling
+ * into an additional message.
+ */
+ public int codeUnitsRemaining;
+
+ /**
+ * The encoding code unit size (specified using
+ * android.telephony.SmsMessage ENCODING_*).
+ */
+ public int codeUnitSize;
+
+ /**
+ * The GSM national language table to use, or 0 for the default 7-bit alphabet.
+ */
+ public int languageTable;
+
+ /**
+ * The GSM national language shift table to use, or 0 for the default 7-bit extension table.
+ */
+ public int languageShiftTable;
+
+ @Override
+ public String toString() {
+ return "TextEncodingDetails " +
+ "{ msgCount=" + msgCount +
+ ", codeUnitCount=" + codeUnitCount +
+ ", codeUnitsRemaining=" + codeUnitsRemaining +
+ ", codeUnitSize=" + codeUnitSize +
+ ", languageTable=" + languageTable +
+ ", languageShiftTable=" + languageShiftTable +
+ " }";
+ }
+ }
+
+ /**
* Converts a char to a GSM 7 bit table index.
* Returns ' ' in GSM alphabet if there's no possible match. Returns
* GSM_EXTENDED_ESCAPE if this character is in the extended table.
@@ -752,27 +801,27 @@
* character counts for the most efficient 7-bit encoding,
* or null if there are no suitable language tables to encode the string.
*/
- public static SmsMessageBase.TextEncodingDetails
+ public static TextEncodingDetails
countGsmSeptets(CharSequence s, boolean use7bitOnly) {
// fast path for common case where no national language shift tables are enabled
if (sEnabledSingleShiftTables.length + sEnabledLockingShiftTables.length == 0) {
- SmsMessageBase.TextEncodingDetails ted = new SmsMessageBase.TextEncodingDetails();
+ TextEncodingDetails ted = new TextEncodingDetails();
int septets = GsmAlphabet.countGsmSeptetsUsingTables(s, use7bitOnly, 0, 0);
if (septets == -1) {
return null;
}
- ted.codeUnitSize = ENCODING_7BIT;
+ ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
ted.codeUnitCount = septets;
- if (septets > MAX_USER_DATA_SEPTETS) {
- ted.msgCount = (septets + (MAX_USER_DATA_SEPTETS_WITH_HEADER - 1)) /
- MAX_USER_DATA_SEPTETS_WITH_HEADER;
+ if (septets > SmsConstants.MAX_USER_DATA_SEPTETS) {
+ ted.msgCount = (septets + (SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER - 1)) /
+ SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER;
ted.codeUnitsRemaining = (ted.msgCount *
- MAX_USER_DATA_SEPTETS_WITH_HEADER) - septets;
+ SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER) - septets;
} else {
ted.msgCount = 1;
- ted.codeUnitsRemaining = MAX_USER_DATA_SEPTETS - septets;
+ ted.codeUnitsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - septets;
}
- ted.codeUnitSize = ENCODING_7BIT;
+ ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
return ted;
}
@@ -832,9 +881,9 @@
}
// find the least cost encoding (lowest message count and most code units remaining)
- SmsMessageBase.TextEncodingDetails ted = new SmsMessageBase.TextEncodingDetails();
+ TextEncodingDetails ted = new TextEncodingDetails();
ted.msgCount = Integer.MAX_VALUE;
- ted.codeUnitSize = ENCODING_7BIT;
+ ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
int minUnencodableCount = Integer.MAX_VALUE;
for (LanguagePairCount lpc : lpcList) {
for (int shiftTable = 0; shiftTable <= maxSingleShiftCode; shiftTable++) {
@@ -852,17 +901,17 @@
}
int msgCount;
int septetsRemaining;
- if (septets + udhLength > MAX_USER_DATA_SEPTETS) {
+ if (septets + udhLength > SmsConstants.MAX_USER_DATA_SEPTETS) {
if (udhLength == 0) {
udhLength = UDH_SEPTET_COST_LENGTH;
}
udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
- int septetsPerMessage = MAX_USER_DATA_SEPTETS - udhLength;
+ int septetsPerMessage = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength;
msgCount = (septets + septetsPerMessage - 1) / septetsPerMessage;
septetsRemaining = (msgCount * septetsPerMessage) - septets;
} else {
msgCount = 1;
- septetsRemaining = MAX_USER_DATA_SEPTETS - udhLength - septets;
+ septetsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength - septets;
}
// for 7-bit only mode, use language pair with the least unencodable chars
int unencodableCount = lpc.unencodableCounts[shiftTable];
diff --git a/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl b/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl
deleted file mode 100644
index f700dfe..0000000
--- a/telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-** 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
-**
-** 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 com.android.internal.telephony.AdnRecord;
-
-
-
-/** Interface for applications to access the ICC phone book.
- *
- * <p>The following code snippet demonstrates a static method to
- * retrieve the IIccPhoneBook interface from Android:</p>
- * <pre>private static IIccPhoneBook getSimPhoneBookInterface()
- throws DeadObjectException {
- IServiceManager sm = ServiceManagerNative.getDefault();
- IIccPhoneBook spb;
- spb = IIccPhoneBook.Stub.asInterface(sm.getService("iccphonebook"));
- return spb;
-}
- * </pre>
- */
-
-interface IIccPhoneBook {
-
- /**
- * Loads the AdnRecords in efid and returns them as a
- * List of AdnRecords
- *
- * @param efid the EF id of a ADN-like SIM
- * @return List of AdnRecord
- */
- List<AdnRecord> getAdnRecordsInEf(int efid);
-
- /**
- * 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
- *
- * @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
- */
- boolean updateAdnRecordsInEfBySearch(int efid,
- String oldTag, String oldPhoneNumber,
- String newTag, String newPhoneNumber,
- String pin2);
-
- /**
- * 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
- *
- * @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
- */
- boolean updateAdnRecordsInEfByIndex(int efid, String newTag,
- String newPhoneNumber, int index,
- String pin2);
-
- /**
- * Get the max munber of records in efid
- *
- * @param efid the EF id of a ADN-like SIM
- * @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
- */
- int[] getAdnRecordsSize(int efid);
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
old mode 100755
new mode 100644
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
deleted file mode 100644
index 735f986..0000000
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-** 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
-**
-** 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 com.android.internal.telephony.SmsRawData;
-
-/** Interface for applications to access the ICC phone book.
- *
- * <p>The following code snippet demonstrates a static method to
- * retrieve the ISms interface from Android:</p>
- * <pre>private static ISms getSmsInterface()
- throws DeadObjectException {
- IServiceManager sm = ServiceManagerNative.getDefault();
- ISms ss;
- ss = ISms.Stub.asInterface(sm.getService("isms"));
- return ss;
-}
- * </pre>
- */
-
-interface ISms {
- /**
- * Retrieves all messages currently stored on ICC.
- *
- * @return list of SmsRawData of all sms on ICC
- */
- List<SmsRawData> getAllMessagesFromIccEf();
-
- /**
- * 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 success or not
- *
- */
- boolean updateMessageOnIccEf(int messageIndex, int newStatus,
- in byte[] pdu);
-
- /**
- * Copy a raw SMS PDU to the ICC.
- *
- * @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 success or not
- *
- */
- boolean copyMessageToIccEf(int status, in byte[] pdu, in byte[] smsc);
-
- /**
- * Send a data SMS.
- *
- * @param smsc the SMSC to send the message through, or NULL for the
- * default SMSC
- * @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:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown 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").
- */
- void sendData(in String destAddr, in String scAddr, in int destPort,
- in byte[] data, in PendingIntent sentIntent, in PendingIntent deliveryIntent);
-
- /**
- * Send an SMS.
- *
- * @param smsc the SMSC to send the message through, or NULL for the
- * 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:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- */
- void sendText(in String destAddr, in String scAddr, in String text,
- in PendingIntent sentIntent, in PendingIntent 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").
- */
- void sendMultipartText(in String destinationAddress, in String scAddress,
- in List<String> parts, in List<PendingIntent> sentIntents,
- in List<PendingIntent> deliveryIntents);
-
- /**
- * Enable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages.
- *
- * @param messageIdentifier Message identifier as specified in TS 23.041
- * @return true if successful, false otherwise
- *
- * @see #disableCellBroadcast(int)
- */
- boolean enableCellBroadcast(int messageIdentifier);
-
- /**
- * Disable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages.
- *
- * @param messageIdentifier Message identifier as specified in TS 23.041
- * @return true if successful, false otherwise
- *
- * @see #enableCellBroadcast(int)
- */
- boolean disableCellBroadcast(int messageIdentifier);
-
- /**
- * Enable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier range. Note that if two different clients enable
- * a message identifier range, they must both disable it for the device
- * to stop receiving those messages.
- *
- * @param startMessageId first message identifier as specified in TS 23.041
- * @param endMessageId last message identifier as specified in TS 23.041
- * @return true if successful, false otherwise
- *
- * @see #disableCellBroadcastRange(int, int)
- */
- boolean enableCellBroadcastRange(int startMessageId, int endMessageId);
-
- /**
- * Disable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier range. Note that if two different clients enable
- * a message identifier range, they must both disable it for the device
- * to stop receiving those messages.
- *
- * @param startMessageId first message identifier as specified in TS 23.041
- * @param endMessageId last message identifier as specified in TS 23.041
- * @return true if successful, false otherwise
- *
- * @see #enableCellBroadcastRange(int, int)
- */
- boolean disableCellBroadcastRange(int startMessageId, int endMessageId);
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
deleted file mode 100644
index fcf2f92..0000000
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ /dev/null
@@ -1,1002 +0,0 @@
-/*
- * 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 static android.Manifest.permission.READ_PHONE_STATE;
-import android.app.ActivityManagerNative;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.util.Log;
-import android.view.WindowManager;
-
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.CommandsInterface.RadioState;
-import com.android.internal.telephony.gsm.SIMFileHandler;
-import com.android.internal.telephony.gsm.SIMRecords;
-import com.android.internal.telephony.cat.CatService;
-import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler;
-import com.android.internal.telephony.cdma.CdmaLteUiccRecords;
-import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
-import com.android.internal.telephony.cdma.RuimFileHandler;
-import com.android.internal.telephony.cdma.RuimRecords;
-
-import android.os.SystemProperties;
-
-import com.android.internal.R;
-
-/**
- * {@hide}
- */
-public class IccCard {
- protected String mLogTag;
- protected boolean mDbg;
-
- protected IccCardStatus mIccCardStatus = null;
- protected State mState = null;
- private final Object mStateMonitor = new Object();
-
- protected boolean is3gpp = true;
- protected boolean isSubscriptionFromIccCard = true;
- protected CdmaSubscriptionSourceManager mCdmaSSM = null;
- protected PhoneBase mPhone;
- private IccRecords mIccRecords;
- private IccFileHandler mIccFileHandler;
- private CatService mCatService;
-
- private RegistrantList mAbsentRegistrants = new RegistrantList();
- private RegistrantList mPinLockedRegistrants = new RegistrantList();
- private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
- protected RegistrantList mReadyRegistrants = new RegistrantList();
- protected RegistrantList mRuimReadyRegistrants = new RegistrantList();
-
- private boolean mDesiredPinLocked;
- private boolean mDesiredFdnEnabled;
- private boolean mIccPinLocked = true; // Default to locked
- private boolean mIccFdnEnabled = false; // Default to disabled.
- // Will be updated when SIM_READY.
-
- /* Parameter is3gpp's values to be passed to constructor */
- public final static boolean CARD_IS_3GPP = true;
- public final static boolean CARD_IS_NOT_3GPP = false;
-
-
- /* 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 ICC is locked on PIN1 */
- static public final String INTENT_VALUE_LOCKED_ON_PIN = "PIN";
- /* PUK means ICC is locked on PUK1 */
- static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK";
- /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
- static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
- /* PERM_DISABLED means ICC is permanently disabled due to puk fails */
- static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
-
-
- protected static final int EVENT_ICC_LOCKED = 1;
- private static final int EVENT_GET_ICC_STATUS_DONE = 2;
- protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3;
- private static final int EVENT_PINPUK_DONE = 4;
- private static final int EVENT_REPOLL_STATUS_DONE = 5;
- protected static final int EVENT_ICC_READY = 6;
- private static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7;
- private static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8;
- private static final int EVENT_CHANGE_ICC_PASSWORD_DONE = 9;
- private static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
- private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
- private static final int EVENT_ICC_STATUS_CHANGED = 12;
- private static final int EVENT_CARD_REMOVED = 13;
- private static final int EVENT_CARD_ADDED = 14;
- protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 15;
- protected static final int EVENT_RADIO_ON = 16;
-
- /*
- 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 {
- UNKNOWN,
- ABSENT,
- PIN_REQUIRED,
- PUK_REQUIRED,
- NETWORK_LOCKED,
- READY,
- NOT_READY,
- PERM_DISABLED;
-
- public boolean isPinLocked() {
- return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
- }
-
- public boolean iccCardExist() {
- return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)
- || (this == NETWORK_LOCKED) || (this == READY)
- || (this == PERM_DISABLED));
- }
- }
-
- public State getState() {
- if (mState == null) {
- switch(mPhone.mCM.getRadioState()) {
- /* This switch block must not return anything in
- * State.isLocked() or State.ABSENT.
- * If it does, handleSimStatus() may break
- */
- case RADIO_OFF:
- case RADIO_UNAVAILABLE:
- return State.UNKNOWN;
- default:
- if (!is3gpp && !isSubscriptionFromIccCard) {
- // CDMA can get subscription from NV. In that case,
- // subscription is ready as soon as Radio is ON.
- return State.READY;
- }
- }
- } else {
- return mState;
- }
-
- return State.UNKNOWN;
- }
-
- public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) {
- mLogTag = logTag;
- mDbg = dbg;
- if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2"));
- mPhone = phone;
- this.is3gpp = is3gpp;
- mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(),
- mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
- if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE
- && phone instanceof CDMALTEPhone) {
- mIccFileHandler = new CdmaLteUiccFileHandler(this, "", mPhone.mCM);
- mIccRecords = new CdmaLteUiccRecords(this, mPhone.mContext, mPhone.mCM);
- } else {
- // Correct aid will be set later (when GET_SIM_STATUS returns)
- mIccFileHandler = is3gpp ? new SIMFileHandler(this, "", mPhone.mCM) :
- new RuimFileHandler(this, "", mPhone.mCM);
- mIccRecords = is3gpp ? new SIMRecords(this, mPhone.mContext, mPhone.mCM) :
- new RuimRecords(this, mPhone.mContext, mPhone.mCM);
- }
- mCatService = CatService.getInstance(mPhone.mCM, mIccRecords,
- mPhone.mContext, mIccFileHandler, this);
- mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mPhone.mCM.registerForOn(mHandler, EVENT_RADIO_ON, null);
- mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null);
- }
-
- public void dispose() {
- if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
- mPhone.mCM.unregisterForIccStatusChanged(mHandler);
- mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
- mPhone.mCM.unregisterForOn(mHandler);
- mCatService.dispose();
- mCdmaSSM.dispose(mHandler);
- mIccRecords.dispose();
- mIccFileHandler.dispose();
- }
-
- protected void finalize() {
- if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2"));
- }
-
- public IccRecords getIccRecords() {
- return mIccRecords;
- }
-
- public IccFileHandler getIccFileHandler() {
- return mIccFileHandler;
- }
-
- /**
- * Notifies handler of any transition into State.ABSENT
- */
- public void registerForAbsent(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- mAbsentRegistrants.add(r);
-
- if (getState() == State.ABSENT) {
- r.notifyRegistrant();
- }
- }
-
- public void unregisterForAbsent(Handler h) {
- mAbsentRegistrants.remove(h);
- }
-
- /**
- * Notifies handler of any transition into State.NETWORK_LOCKED
- */
- public void registerForNetworkLocked(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- mNetworkLockedRegistrants.add(r);
-
- if (getState() == State.NETWORK_LOCKED) {
- r.notifyRegistrant();
- }
- }
-
- public void unregisterForNetworkLocked(Handler h) {
- mNetworkLockedRegistrants.remove(h);
- }
-
- /**
- * Notifies handler of any transition into State.isPinLocked()
- */
- public void registerForLocked(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- mPinLockedRegistrants.add(r);
-
- if (getState().isPinLocked()) {
- r.notifyRegistrant();
- }
- }
-
- public void unregisterForLocked(Handler h) {
- mPinLockedRegistrants.remove(h);
- }
-
- public void registerForReady(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- synchronized (mStateMonitor) {
- mReadyRegistrants.add(r);
-
- if (getState() == State.READY) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
- }
-
- public void unregisterForReady(Handler h) {
- synchronized (mStateMonitor) {
- mReadyRegistrants.remove(h);
- }
- }
-
- public State getRuimState() {
- if(mIccCardStatus != null) {
- return getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
- } else {
- return State.UNKNOWN;
- }
- }
-
- public void registerForRuimReady(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
-
- synchronized (mStateMonitor) {
- mRuimReadyRegistrants.add(r);
-
- if (getState() == State.READY && getRuimState() == State.READY ) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
- }
-
- public void unregisterForRuimReady(Handler h) {
- synchronized (mStateMonitor) {
- mRuimReadyRegistrants.remove(h);
- }
- }
-
- /**
- * Supply the ICC PIN to the ICC
- *
- * When the operation is complete, onComplete will be sent to its
- * Handler.
- *
- * onComplete.obj will be an AsyncResult
- *
- * ((AsyncResult)onComplete.obj).exception == null on success
- * ((AsyncResult)onComplete.obj).exception != null on fail
- *
- * If the supplied PIN is incorrect:
- * ((AsyncResult)onComplete.obj).exception != null
- * && ((AsyncResult)onComplete.obj).exception
- * instanceof com.android.internal.telephony.gsm.CommandException)
- * && ((CommandException)(((AsyncResult)onComplete.obj).exception))
- * .getCommandError() == CommandException.Error.PASSWORD_INCORRECT
- *
- *
- */
-
- public void supplyPin (String pin, Message onComplete) {
- mPhone.mCM.supplyIccPin(pin, mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
- }
-
- public void supplyPuk (String puk, String newPin, Message onComplete) {
- mPhone.mCM.supplyIccPuk(puk, newPin,
- mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
- }
-
- public void supplyPin2 (String pin2, Message onComplete) {
- mPhone.mCM.supplyIccPin2(pin2,
- mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
- }
-
- public void supplyPuk2 (String puk2, String newPin2, Message onComplete) {
- mPhone.mCM.supplyIccPuk2(puk2, newPin2,
- mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
- }
-
- public void supplyNetworkDepersonalization (String pin, Message onComplete) {
- mPhone.mCM.supplyNetworkDepersonalization(pin,
- mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
- }
-
- /**
- * Check whether ICC pin lock is enabled
- * This is a sync call which returns the cached pin enabled state
- *
- * @return true for ICC locked enabled
- * false for ICC locked disabled
- */
- public boolean getIccLockEnabled() {
- return mIccPinLocked;
- }
-
- /**
- * Check whether ICC fdn (fixed dialing number) is enabled
- * This is a sync call which returns the cached pin enabled state
- *
- * @return true for ICC fdn enabled
- * false for ICC fdn disabled
- */
- public boolean getIccFdnEnabled() {
- return mIccFdnEnabled;
- }
-
- /**
- * 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 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
- */
- public void setIccLockEnabled (boolean enabled,
- String password, Message onComplete) {
- int serviceClassX;
- serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
- CommandsInterface.SERVICE_CLASS_DATA +
- CommandsInterface.SERVICE_CLASS_FAX;
-
- mDesiredPinLocked = enabled;
-
- mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM,
- enabled, password, serviceClassX,
- mHandler.obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete));
- }
-
- /**
- * 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 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
- */
- public void setIccFdnEnabled (boolean enabled,
- String password, Message onComplete) {
- int serviceClassX;
- serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
- CommandsInterface.SERVICE_CLASS_DATA +
- CommandsInterface.SERVICE_CLASS_FAX +
- CommandsInterface.SERVICE_CLASS_SMS;
-
- mDesiredFdnEnabled = enabled;
-
- mPhone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD,
- enabled, password, serviceClassX,
- mHandler.obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete));
- }
-
- /**
- * 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
- * @param newPassword is the new password
- * @param onComplete
- * onComplete.obj will be an AsyncResult
- * ((AsyncResult)onComplete.obj).exception == null on success
- * ((AsyncResult)onComplete.obj).exception != null on fail
- */
- public void changeIccLockPassword(String oldPassword, String newPassword,
- Message onComplete) {
- mPhone.mCM.changeIccPin(oldPassword, newPassword,
- mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
-
- }
-
- /**
- * 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
- * @param newPassword is the new password
- * @param onComplete
- * onComplete.obj will be an AsyncResult
- * ((AsyncResult)onComplete.obj).exception == null on success
- * ((AsyncResult)onComplete.obj).exception != null on fail
- */
- public void changeIccFdnPassword(String oldPassword, String newPassword,
- Message onComplete) {
- mPhone.mCM.changeIccPin2(oldPassword, newPassword,
- mHandler.obtainMessage(EVENT_CHANGE_ICC_PASSWORD_DONE, onComplete));
-
- }
-
-
- /**
- * 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>
- *
- * Please use this value when display Service Provider Name in idle mode <p>
- *
- * Usage of this provider name in the UI is a common carrier requirement.
- *
- * Also available via Android property "gsm.sim.operator.alpha"
- *
- * @return Service Provider Name stored in ICC card
- * null if no service provider name associated or the record is not
- * yet available
- *
- */
- public String getServiceProviderName () {
- return mPhone.mIccRecords.getServiceProviderName();
- }
-
- protected void updateStateProperty() {
- mPhone.setSystemProperty(TelephonyProperties.PROPERTY_SIM_STATE, getState().toString());
- }
-
- private void getIccCardStatusDone(AsyncResult ar) {
- if (ar.exception != null) {
- Log.e(mLogTag,"Error getting ICC status. "
- + "RIL_REQUEST_GET_ICC_STATUS should "
- + "never return an error", ar.exception);
- return;
- }
- handleIccCardStatus((IccCardStatus) ar.result);
- }
-
- private void handleIccCardStatus(IccCardStatus newCardStatus) {
- boolean transitionedIntoPinLocked;
- boolean transitionedIntoAbsent;
- boolean transitionedIntoNetworkLocked;
- boolean transitionedIntoPermBlocked;
- boolean isIccCardRemoved;
- boolean isIccCardAdded;
-
- State oldState, newState;
- State oldRuimState = getRuimState();
-
- oldState = mState;
- mIccCardStatus = newCardStatus;
- newState = getIccCardState();
-
- synchronized (mStateMonitor) {
- mState = newState;
- updateStateProperty();
- if (oldState != State.READY && newState == State.READY) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_READY));
- mReadyRegistrants.notifyRegistrants();
- } else if (newState.isPinLocked()) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_ICC_LOCKED));
- }
- if (oldRuimState != State.READY && getRuimState() == State.READY) {
- mRuimReadyRegistrants.notifyRegistrants();
- }
- }
-
- transitionedIntoPinLocked = (
- (oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED)
- || (oldState != State.PUK_REQUIRED && newState == State.PUK_REQUIRED));
- transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT);
- transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED
- && newState == State.NETWORK_LOCKED);
- transitionedIntoPermBlocked = (oldState != State.PERM_DISABLED
- && newState == State.PERM_DISABLED);
- isIccCardRemoved = (oldState != null &&
- oldState.iccCardExist() && newState == State.ABSENT);
- isIccCardAdded = (oldState == State.ABSENT &&
- newState != null && newState.iccCardExist());
-
- if (transitionedIntoPinLocked) {
- if (mDbg) log("Notify SIM pin or puk locked.");
- mPinLockedRegistrants.notifyRegistrants();
- broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
- (newState == State.PIN_REQUIRED) ?
- INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK);
- } else if (transitionedIntoAbsent) {
- if (mDbg) log("Notify SIM missing.");
- mAbsentRegistrants.notifyRegistrants();
- broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT, null);
- } else if (transitionedIntoNetworkLocked) {
- if (mDbg) log("Notify SIM network locked.");
- mNetworkLockedRegistrants.notifyRegistrants();
- broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
- INTENT_VALUE_LOCKED_NETWORK);
- } else if (transitionedIntoPermBlocked) {
- if (mDbg) log("Notify SIM permanently disabled.");
- broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT,
- INTENT_VALUE_ABSENT_ON_PERM_DISABLED);
- }
-
- if (isIccCardRemoved) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null));
- } else if (isIccCardAdded) {
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null));
- }
-
- // Call onReady Record(s) on the IccCard becomes ready (not NV)
- if (oldState != State.READY && newState == State.READY &&
- (is3gpp || isSubscriptionFromIccCard)) {
- if (!(mIccFileHandler instanceof CdmaLteUiccFileHandler)) {
- // CdmaLteUicc File Handler deals with both USIM and CSIM.
- // Do not lock onto one AID for now.
- mIccFileHandler.setAid(getAid());
- }
- mIccRecords.onReady();
- }
- }
-
- private void onIccSwap(boolean isAdded) {
- // TODO: Here we assume the device can't handle SIM hot-swap
- // and has to reboot. We may want to add a property,
- // e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support
- // hot-swap.
- DialogInterface.OnClickListener listener = null;
-
-
- // TODO: SimRecords is not reset while SIM ABSENT (only reset while
- // Radio_off_or_not_available). Have to reset in both both
- // added or removed situation.
- listener = new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (which == DialogInterface.BUTTON_POSITIVE) {
- if (mDbg) log("Reboot due to SIM swap");
- PowerManager pm = (PowerManager) mPhone.getContext()
- .getSystemService(Context.POWER_SERVICE);
- pm.reboot("SIM is added.");
- }
- }
-
- };
-
- Resources r = Resources.getSystem();
-
- String title = (isAdded) ? r.getString(R.string.sim_added_title) :
- r.getString(R.string.sim_removed_title);
- String message = (isAdded) ? r.getString(R.string.sim_added_message) :
- r.getString(R.string.sim_removed_message);
- String buttonTxt = r.getString(R.string.sim_restart_button);
-
- AlertDialog dialog = new AlertDialog.Builder(mPhone.getContext())
- .setTitle(title)
- .setMessage(message)
- .setPositiveButton(buttonTxt, listener)
- .create();
- dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- dialog.show();
- }
-
- /**
- * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
- * @param ar is asyncResult of Query_Facility_Locked
- */
- private void onQueryFdnEnabled(AsyncResult ar) {
- if(ar.exception != null) {
- if(mDbg) log("Error in querying facility lock:" + ar.exception);
- return;
- }
-
- int[] ints = (int[])ar.result;
- if(ints.length != 0) {
- mIccFdnEnabled = (0!=ints[0]);
- if(mDbg) log("Query facility lock : " + mIccFdnEnabled);
- } else {
- Log.e(mLogTag, "[IccCard] Bogus facility lock response");
- }
- }
-
- /**
- * Interperate EVENT_QUERY_FACILITY_LOCK_DONE
- * @param ar is asyncResult of Query_Facility_Locked
- */
- private void onQueryFacilityLock(AsyncResult ar) {
- if(ar.exception != null) {
- if (mDbg) log("Error in querying facility lock:" + ar.exception);
- return;
- }
-
- int[] ints = (int[])ar.result;
- if(ints.length != 0) {
- mIccPinLocked = (0!=ints[0]);
- if(mDbg) log("Query facility lock : " + mIccPinLocked);
- } else {
- Log.e(mLogTag, "[IccCard] Bogus facility lock response");
- }
- }
-
- public void broadcastIccStateChangedIntent(String value, String reason) {
- Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra(Phone.PHONE_NAME_KEY, mPhone.getPhoneName());
- intent.putExtra(INTENT_KEY_ICC_STATE, value);
- intent.putExtra(INTENT_KEY_LOCKED_REASON, reason);
- if(mDbg) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " + value
- + " reason " + reason);
- ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE);
- }
-
- protected Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg){
- AsyncResult ar;
- int serviceClassX;
-
- serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE +
- CommandsInterface.SERVICE_CLASS_DATA +
- CommandsInterface.SERVICE_CLASS_FAX;
-
- if (!mPhone.mIsTheCurrentActivePhone) {
- Log.e(mLogTag, "Received message " + msg + "[" + msg.what
- + "] while being destroyed. Ignoring.");
- return;
- }
-
- switch (msg.what) {
- case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
- mState = null;
- updateStateProperty();
- broadcastIccStateChangedIntent(INTENT_VALUE_ICC_NOT_READY, null);
- break;
- case EVENT_RADIO_ON:
- if (!is3gpp) {
- handleCdmaSubscriptionSource();
- }
- mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
- break;
- case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
- handleCdmaSubscriptionSource();
- break;
- case EVENT_ICC_READY:
- if(isSubscriptionFromIccCard) {
- mPhone.mCM.queryFacilityLock (
- CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
- obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
- mPhone.mCM.queryFacilityLock (
- CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX,
- obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE));
- }
- break;
- case EVENT_ICC_LOCKED:
- mPhone.mCM.queryFacilityLock (
- CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX,
- obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE));
- break;
- case EVENT_GET_ICC_STATUS_DONE:
- ar = (AsyncResult)msg.obj;
-
- getIccCardStatusDone(ar);
- break;
- case EVENT_PINPUK_DONE:
- // a PIN/PUK/PIN2/PUK2/Network Personalization
- // request has completed. ar.userObj is the response Message
- // Repoll before returning
- ar = (AsyncResult)msg.obj;
- // TODO should abstract these exceptions
- AsyncResult.forMessage(((Message)ar.userObj)).exception
- = ar.exception;
- mPhone.mCM.getIccCardStatus(
- obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));
- break;
- case EVENT_REPOLL_STATUS_DONE:
- // Finished repolling status after PIN operation
- // ar.userObj is the response messaeg
- // ar.userObj.obj is already an AsyncResult with an
- // appropriate exception filled in if applicable
-
- ar = (AsyncResult)msg.obj;
- getIccCardStatusDone(ar);
- ((Message)ar.userObj).sendToTarget();
- break;
- case EVENT_QUERY_FACILITY_LOCK_DONE:
- ar = (AsyncResult)msg.obj;
- onQueryFacilityLock(ar);
- break;
- case EVENT_QUERY_FACILITY_FDN_DONE:
- ar = (AsyncResult)msg.obj;
- onQueryFdnEnabled(ar);
- break;
- case EVENT_CHANGE_FACILITY_LOCK_DONE:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- mIccPinLocked = mDesiredPinLocked;
- if (mDbg) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " +
- "mIccPinLocked= " + mIccPinLocked);
- } else {
- Log.e(mLogTag, "Error change facility lock with exception "
- + ar.exception);
- }
- AsyncResult.forMessage(((Message)ar.userObj)).exception
- = ar.exception;
- ((Message)ar.userObj).sendToTarget();
- break;
- case EVENT_CHANGE_FACILITY_FDN_DONE:
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception == null) {
- mIccFdnEnabled = mDesiredFdnEnabled;
- if (mDbg) log("EVENT_CHANGE_FACILITY_FDN_DONE: " +
- "mIccFdnEnabled=" + mIccFdnEnabled);
- } else {
- Log.e(mLogTag, "Error change facility fdn with exception "
- + ar.exception);
- }
- AsyncResult.forMessage(((Message)ar.userObj)).exception
- = ar.exception;
- ((Message)ar.userObj).sendToTarget();
- break;
- case EVENT_CHANGE_ICC_PASSWORD_DONE:
- ar = (AsyncResult)msg.obj;
- if(ar.exception != null) {
- Log.e(mLogTag, "Error in change sim password with exception"
- + ar.exception);
- }
- AsyncResult.forMessage(((Message)ar.userObj)).exception
- = ar.exception;
- ((Message)ar.userObj).sendToTarget();
- break;
- case EVENT_ICC_STATUS_CHANGED:
- Log.d(mLogTag, "Received Event EVENT_ICC_STATUS_CHANGED");
- mPhone.mCM.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
- break;
- case EVENT_CARD_REMOVED:
- onIccSwap(false);
- break;
- case EVENT_CARD_ADDED:
- onIccSwap(true);
- break;
- default:
- Log.e(mLogTag, "[IccCard] Unknown Event " + msg.what);
- }
- }
- };
-
- private void handleCdmaSubscriptionSource() {
- if(mCdmaSSM != null) {
- int newSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource();
-
- Log.d(mLogTag, "Received Cdma subscription source: " + newSubscriptionSource);
-
- boolean isNewSubFromRuim =
- (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
-
- if (isNewSubFromRuim != isSubscriptionFromIccCard) {
- isSubscriptionFromIccCard = isNewSubFromRuim;
- // Parse the Stored IccCardStatus Message to set mState correctly.
- handleIccCardStatus(mIccCardStatus);
- }
- }
- }
-
- public State getIccCardState() {
- if(!is3gpp && !isSubscriptionFromIccCard) {
- // CDMA can get subscription from NV. In that case,
- // subscription is ready as soon as Radio is ON.
- return State.READY;
- }
-
- if (mIccCardStatus == null) {
- Log.e(mLogTag, "[IccCard] IccCardStatus is null");
- return IccCard.State.ABSENT;
- }
-
- // this is common for all radio technologies
- if (!mIccCardStatus.getCardState().isCardPresent()) {
- return IccCard.State.ABSENT;
- }
-
- RadioState currentRadioState = mPhone.mCM.getRadioState();
- // check radio technology
- if( currentRadioState == RadioState.RADIO_OFF ||
- currentRadioState == RadioState.RADIO_UNAVAILABLE) {
- return IccCard.State.NOT_READY;
- }
-
- if( currentRadioState == RadioState.RADIO_ON ) {
- State csimState =
- getAppState(mIccCardStatus.getCdmaSubscriptionAppIndex());
- State usimState =
- getAppState(mIccCardStatus.getGsmUmtsSubscriptionAppIndex());
-
- if(mDbg) log("USIM=" + usimState + " CSIM=" + csimState);
-
- if (mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
- // UICC card contains both USIM and CSIM
- // Return consolidated status
- return getConsolidatedState(csimState, usimState, csimState);
- }
-
- // check for CDMA radio technology
- if (!is3gpp) {
- return csimState;
- }
- return usimState;
- }
-
- return IccCard.State.ABSENT;
- }
-
- private State getAppState(int appIndex) {
- IccCardApplication app;
- if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) {
- app = mIccCardStatus.getApplication(appIndex);
- } else {
- Log.e(mLogTag, "[IccCard] Invalid Subscription Application index:" + appIndex);
- return IccCard.State.ABSENT;
- }
-
- if (app == null) {
- Log.e(mLogTag, "[IccCard] Subscription Application in not present");
- return IccCard.State.ABSENT;
- }
-
- // check if PIN required
- if (app.pin1.isPermBlocked()) {
- return IccCard.State.PERM_DISABLED;
- }
- if (app.app_state.isPinRequired()) {
- return IccCard.State.PIN_REQUIRED;
- }
- if (app.app_state.isPukRequired()) {
- return IccCard.State.PUK_REQUIRED;
- }
- if (app.app_state.isSubscriptionPersoEnabled()) {
- return IccCard.State.NETWORK_LOCKED;
- }
- if (app.app_state.isAppReady()) {
- return IccCard.State.READY;
- }
- if (app.app_state.isAppNotReady()) {
- return IccCard.State.NOT_READY;
- }
- return IccCard.State.NOT_READY;
- }
-
- private State getConsolidatedState(State left, State right, State preferredState) {
- // Check if either is absent.
- if (right == IccCard.State.ABSENT) return left;
- if (left == IccCard.State.ABSENT) return right;
-
- // Only if both are ready, return ready
- if ((left == IccCard.State.READY) && (right == IccCard.State.READY)) {
- return State.READY;
- }
-
- // Case one is ready, but the other is not.
- if (((right == IccCard.State.NOT_READY) && (left == IccCard.State.READY)) ||
- ((left == IccCard.State.NOT_READY) && (right == IccCard.State.READY))) {
- return IccCard.State.NOT_READY;
- }
-
- // At this point, the other state is assumed to be one of locked state
- if (right == IccCard.State.NOT_READY) return left;
- if (left == IccCard.State.NOT_READY) return right;
-
- // At this point, FW currently just assumes the status will be
- // consistent across the applications...
- return preferredState;
- }
-
- public boolean isApplicationOnIcc(IccCardApplication.AppType type) {
- if (mIccCardStatus == null) return false;
-
- for (int i = 0 ; i < mIccCardStatus.getNumApplications(); i++) {
- IccCardApplication app = mIccCardStatus.getApplication(i);
- if (app != null && app.app_type == type) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * @return true if a ICC card is present
- */
- public boolean hasIccCard() {
- if (mIccCardStatus == null) {
- return false;
- } else {
- // Returns ICC card status for both GSM and CDMA mode
- return mIccCardStatus.getCardState().isCardPresent();
- }
- }
-
- private void log(String msg) {
- Log.d(mLogTag, "[IccCard] " + msg);
- }
-
- protected int getCurrentApplicationIndex() {
- if (is3gpp) {
- return mIccCardStatus.getGsmUmtsSubscriptionAppIndex();
- } else {
- return mIccCardStatus.getCdmaSubscriptionAppIndex();
- }
- }
-
- public String getAid() {
- String aid = "";
- if (mIccCardStatus == null) {
- return aid;
- }
-
- int appIndex = getCurrentApplicationIndex();
-
- if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) {
- IccCardApplication app = mIccCardStatus.getApplication(appIndex);
- if (app != null) {
- aid = app.aid;
- } else {
- Log.e(mLogTag, "[IccCard] getAid: no current application index=" + appIndex);
- }
- } else {
- Log.e(mLogTag, "[IccCard] getAid: Invalid Subscription Application index=" + appIndex);
- }
-
- return aid;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java
deleted file mode 100644
index abb740e..0000000
--- a/telephony/java/com/android/internal/telephony/IccCardApplication.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * 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 com.android.internal.telephony.IccCardStatus.PinState;
-
-
-/**
- * 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,
- APPTYPE_ISIM
- };
-
- 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 PinState pin1;
- public PinState 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;
- case 5: newType = AppType.APPTYPE_ISIM; 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;
- }
-
- PinState PinStateFromRILInt(int state) {
- PinState newPinState;
- switch(state) {
- case 0:
- newPinState = PinState.PINSTATE_UNKNOWN;
- break;
- case 1:
- newPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED;
- break;
- case 2:
- newPinState = PinState.PINSTATE_ENABLED_VERIFIED;
- break;
- case 3:
- newPinState = PinState.PINSTATE_DISABLED;
- break;
- case 4:
- newPinState = PinState.PINSTATE_ENABLED_BLOCKED;
- break;
- case 5:
- newPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED;
- break;
- default:
- throw new RuntimeException("Unrecognized RIL_PinState: " + state);
- }
- return newPinState;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
-
- sb.append("{").append(app_type).append(",").append(app_state);
- if (app_state == AppState.APPSTATE_SUBSCRIPTION_PERSO) {
- sb.append(",").append(perso_substate);
- }
- if (app_type == AppType.APPTYPE_CSIM ||
- app_type == AppType.APPTYPE_USIM ||
- app_type == AppType.APPTYPE_ISIM) {
- sb.append(",pin1=").append(pin1);
- sb.append(",pin2=").append(pin2);
- }
- sb.append("}");
- return sb.toString();
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccCardConstants.java b/telephony/java/com/android/internal/telephony/IccCardConstants.java
new file mode 100644
index 0000000..236bb2f
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IccCardConstants.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.telephony;
+
+/**
+ * {@hide}
+ */
+public class IccCardConstants {
+
+ /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
+ public static final String INTENT_KEY_ICC_STATE = "ss";
+ /* UNKNOWN means the ICC state is unknown */
+ public static final String INTENT_VALUE_ICC_UNKNOWN = "UNKNOWN";
+ /* NOT_READY means the ICC interface is not ready (eg, radio is off or powering on) */
+ public static final String INTENT_VALUE_ICC_NOT_READY = "NOT_READY";
+ /* ABSENT means ICC is missing */
+ public static final String INTENT_VALUE_ICC_ABSENT = "ABSENT";
+ /* LOCKED means ICC is locked by pin or by network */
+ public static final String INTENT_VALUE_ICC_LOCKED = "LOCKED";
+ /* READY means ICC is ready to access */
+ public static final String INTENT_VALUE_ICC_READY = "READY";
+ /* IMSI means ICC IMSI is ready in property */
+ public static final String INTENT_VALUE_ICC_IMSI = "IMSI";
+ /* LOADED means all ICC records, including IMSI, are loaded */
+ public static final String INTENT_VALUE_ICC_LOADED = "LOADED";
+ /* The extra data for broacasting intent INTENT_ICC_STATE_CHANGE */
+ public static final String INTENT_KEY_LOCKED_REASON = "reason";
+ /* PIN means ICC is locked on PIN1 */
+ public static final String INTENT_VALUE_LOCKED_ON_PIN = "PIN";
+ /* PUK means ICC is locked on PUK1 */
+ public static final String INTENT_VALUE_LOCKED_ON_PUK = "PUK";
+ /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
+ public static final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
+ /* PERM_DISABLED means ICC is permanently disabled due to puk fails */
+ public static final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
+
+ /**
+ * This is combination of IccCardStatus.CardState and IccCardApplicationStatus.AppState
+ * for external apps (like PhoneApp) to use
+ *
+ * UNKNOWN is a transient state, for example, after user inputs ICC pin under
+ * PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it
+ * turns to READY
+ */
+ public enum State {
+ UNKNOWN,
+ ABSENT,
+ PIN_REQUIRED,
+ PUK_REQUIRED,
+ NETWORK_LOCKED,
+ READY,
+ NOT_READY,
+ PERM_DISABLED;
+
+ public boolean isPinLocked() {
+ return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
+ }
+
+ public boolean iccCardExist() {
+ return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)
+ || (this == NETWORK_LOCKED) || (this == READY)
+ || (this == PERM_DISABLED));
+ }
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java
deleted file mode 100644
index a3bdd76..0000000
--- a/telephony/java/com/android/internal/telephony/IccCardStatus.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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 {
- public 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;
-
- boolean isPermBlocked() {
- return this == PINSTATE_ENABLED_PERM_BLOCKED;
- }
-
- boolean isPinRequired() {
- return this == PINSTATE_ENABLED_NOT_VERIFIED;
- }
-
- boolean isPukRequired() {
- return this == PINSTATE_ENABLED_BLOCKED;
- }
- }
-
- private CardState mCardState;
- private PinState mUniversalPinState;
- private int mGsmUmtsSubscriptionAppIndex;
- private int mCdmaSubscriptionAppIndex;
- private int mImsSubscriptionAppIndex;
- private int mNumApplications;
-
- private ArrayList<IccCardApplication> mApplications =
- new ArrayList<IccCardApplication>(CARD_MAX_APPS);
-
- public CardState getCardState() {
- return mCardState;
- }
-
- public void setCardState(int state) {
- switch(state) {
- case 0:
- mCardState = CardState.CARDSTATE_ABSENT;
- break;
- case 1:
- mCardState = CardState.CARDSTATE_PRESENT;
- break;
- case 2:
- mCardState = CardState.CARDSTATE_ERROR;
- break;
- default:
- throw new RuntimeException("Unrecognized RIL_CardState: " + state);
- }
- }
-
- public PinState getUniversalPinState() {
- return mUniversalPinState;
- }
-
- public void setUniversalPinState(int state) {
- switch(state) {
- case 0:
- mUniversalPinState = PinState.PINSTATE_UNKNOWN;
- break;
- case 1:
- mUniversalPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED;
- break;
- case 2:
- mUniversalPinState = PinState.PINSTATE_ENABLED_VERIFIED;
- break;
- case 3:
- mUniversalPinState = PinState.PINSTATE_DISABLED;
- break;
- case 4:
- mUniversalPinState = PinState.PINSTATE_ENABLED_BLOCKED;
- break;
- case 5:
- mUniversalPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED;
- break;
- default:
- throw new RuntimeException("Unrecognized RIL_PinState: " + state);
- }
- }
-
- public int getGsmUmtsSubscriptionAppIndex() {
- return mGsmUmtsSubscriptionAppIndex;
- }
-
- public void setGsmUmtsSubscriptionAppIndex(int gsmUmtsSubscriptionAppIndex) {
- mGsmUmtsSubscriptionAppIndex = gsmUmtsSubscriptionAppIndex;
- }
-
- public int getCdmaSubscriptionAppIndex() {
- return mCdmaSubscriptionAppIndex;
- }
-
- public void setCdmaSubscriptionAppIndex(int cdmaSubscriptionAppIndex) {
- mCdmaSubscriptionAppIndex = cdmaSubscriptionAppIndex;
- }
-
- public int getImsSubscriptionAppIndex() {
- return mImsSubscriptionAppIndex;
- }
-
- public void setImsSubscriptionAppIndex(int imsSubscriptionAppIndex) {
- mImsSubscriptionAppIndex = imsSubscriptionAppIndex;
- }
-
- public int getNumApplications() {
- return mNumApplications;
- }
-
- public void setNumApplications(int numApplications) {
- mNumApplications = numApplications;
- }
-
- public void addApplication(IccCardApplication application) {
- mApplications.add(application);
- }
-
- public IccCardApplication getApplication(int index) {
- return mApplications.get(index);
- }
-
- @Override
- public String toString() {
- IccCardApplication app;
-
- StringBuilder sb = new StringBuilder();
- sb.append("IccCardState {").append(mCardState).append(",")
- .append(mUniversalPinState)
- .append(",num_apps=").append(mNumApplications)
- .append(",gsm_id=").append(mGsmUmtsSubscriptionAppIndex);
- if (mGsmUmtsSubscriptionAppIndex >=0
- && mGsmUmtsSubscriptionAppIndex <CARD_MAX_APPS) {
- app = getApplication(mGsmUmtsSubscriptionAppIndex);
- sb.append(app == null ? "null" : app);
- }
-
- sb.append(",cmda_id=").append(mCdmaSubscriptionAppIndex);
- if (mCdmaSubscriptionAppIndex >=0
- && mCdmaSubscriptionAppIndex <CARD_MAX_APPS) {
- app = getApplication(mCdmaSubscriptionAppIndex);
- sb.append(app == null ? "null" : app);
- }
-
- sb.append(",ism_id=").append(mImsSubscriptionAppIndex);
-
- sb.append("}");
-
- return sb.toString();
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
deleted file mode 100644
index 1ba6dfe..0000000
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public interface IccConstants {
- // GSM SIM file ids from TS 51.011
- static final int EF_ADN = 0x6F3A;
- static final int EF_FDN = 0x6F3B;
- static final int EF_SDN = 0x6F49;
- static final int EF_EXT1 = 0x6F4A;
- static final int EF_EXT2 = 0x6F4B;
- static final int EF_EXT3 = 0x6F4C;
- static final int EF_EXT6 = 0x6fc8; // Ext record for EF[MBDN]
- static final int EF_MWIS = 0x6FCA;
- static final int EF_MBDN = 0x6fc7;
- static final int EF_PNN = 0x6fc5;
- static final int EF_SPN = 0x6F46;
- static final int EF_SMS = 0x6F3C;
- static final int EF_ICCID = 0x2fe2;
- static final int EF_AD = 0x6FAD;
- static final int EF_MBI = 0x6fc9;
- static final int EF_MSISDN = 0x6f40;
- static final int EF_SPDI = 0x6fcd;
- static final int EF_SST = 0x6f38;
- static final int EF_CFIS = 0x6FCB;
- static final int EF_IMG = 0x4f20;
-
- // USIM SIM file ids from TS 31.102
- public static final int EF_PBR = 0x4F30;
-
- // GSM SIM file ids from CPHS (phase 2, version 4.2) CPHS4_2.WW6
- static final int EF_MAILBOX_CPHS = 0x6F17;
- static final int EF_VOICE_MAIL_INDICATOR_CPHS = 0x6F11;
- static final int EF_CFF_CPHS = 0x6F13;
- static final int EF_SPN_CPHS = 0x6f14;
- static final int EF_SPN_SHORT_CPHS = 0x6f18;
- static final int EF_INFO_CPHS = 0x6f16;
- static final int EF_CSP_CPHS = 0x6f15;
-
- // CDMA RUIM file ids from 3GPP2 C.S0023-0
- static final int EF_CST = 0x6f32;
- static final int EF_RUIM_SPN =0x6F41;
-
- // ETSI TS.102.221
- static final int EF_PL = 0x2F05;
- // 3GPP2 C.S0065
- static final int EF_CSIM_LI = 0x6F3A;
- static final int EF_CSIM_SPN =0x6F41;
- static final int EF_CSIM_MDN = 0x6F44;
- static final int EF_CSIM_IMSIM = 0x6F22;
- static final int EF_CSIM_CDMAHOME = 0x6F28;
- static final int EF_CSIM_EPRL = 0x6F5A;
-
- //ISIM access
- static final int EF_IMPU = 0x6f04;
- static final int EF_IMPI = 0x6f02;
- static final int EF_DOMAIN = 0x6f03;
- static final int EF_IST = 0x6f07;
- static final int EF_PCSCF = 0x6f09;
-
- // SMS record length from TS 51.011 10.5.3
- static public final int SMS_RECORD_LENGTH = 176;
-
- static final String MF_SIM = "3F00";
- static final String DF_TELECOM = "7F10";
- static final String DF_PHONEBOOK = "5F3A";
- static final String DF_GRAPHICS = "5F50";
- static final String DF_GSM = "7F20";
- static final String DF_CDMA = "7F25";
-
- //ISIM access
- static final String DF_ADFISIM = "7FFF";
-}
diff --git a/telephony/java/com/android/internal/telephony/IccFileHandler.java b/telephony/java/com/android/internal/telephony/IccFileHandler.java
deleted file mode 100644
index 70d8f7a..0000000
--- a/telephony/java/com/android/internal/telephony/IccFileHandler.java
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.*;
-import android.util.Log;
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public abstract class IccFileHandler extends Handler implements IccConstants {
-
- //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 final CommandsInterface mCi;
- protected final IccCard mParentCard;
- protected String mAid;
-
- 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(IccCard card, String aid, CommandsInterface ci) {
- mParentCard = card;
- mAid = aid;
- mCi = ci;
- }
-
- 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));
-
- mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, 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));
-
- // TODO(): Verify when path changes are done.
- mCi.iccIOForApp(COMMAND_GET_RESPONSE, IccConstants.EF_IMG, "img",
- recordNum, READ_RECORD_MODE_ABSOLUTE,
- GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null, mAid, 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));
- mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, 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));
-
- mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, 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);
-
- mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
- 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, 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);
-
- mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, "img", highOffset, lowOffset,
- length, null, null, mAid, 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) {
- mCi.iccIOForApp(COMMAND_UPDATE_RECORD, fileid, getEFPath(fileid),
- recordNum, READ_RECORD_MODE_ABSOLUTE, data.length,
- IccUtils.bytesToHexString(data), pin2, mAid, 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) {
- mCi.iccIOForApp(COMMAND_UPDATE_BINARY, fileid, getEFPath(fileid),
- 0, 0, data.length,
- IccUtils.bytesToHexString(data), null, mAid, 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);
- }
-
- mCi.iccIOForApp(COMMAND_READ_RECORD, lc.efid, getEFPath(lc.efid),
- lc.recordNum,
- READ_RECORD_MODE_ABSOLUTE,
- lc.recordSize, null, null, mAid,
- 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);
-
- mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
- 0, 0, size, null, null, mAid,
- 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 {
- mCi.iccIOForApp(COMMAND_READ_RECORD, lc.efid, getEFPath(lc.efid),
- lc.recordNum,
- READ_RECORD_MODE_ABSOLUTE,
- lc.recordSize, null, null, mAid,
- 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);
- }
- }
- }
-
- /**
- * Returns the root path of the EF file.
- * i.e returns MasterFile + DFfile as a string.
- * Ex: For EF_ADN on a SIM, it will return "3F007F10"
- * This function handles only EFids that are common to
- * RUIM, SIM, USIM and other types of Icc cards.
- *
- * @param efId
- * @return root path of the file.
- */
- protected String getCommonIccEFPath(int efid) {
- switch(efid) {
- case EF_ADN:
- case EF_FDN:
- case EF_MSISDN:
- case EF_SDN:
- case EF_EXT1:
- case EF_EXT2:
- case EF_EXT3:
- return MF_SIM + DF_TELECOM;
-
- case EF_ICCID:
- case EF_PL:
- return MF_SIM;
- case EF_IMG:
- return MF_SIM + DF_TELECOM + DF_GRAPHICS;
- }
- return null;
- }
-
- protected abstract String getEFPath(int efid);
- protected abstract void logd(String s);
-
- protected abstract void loge(String s);
- protected void setAid(String aid) {
- mAid = aid;
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccFileNotFound.java b/telephony/java/com/android/internal/telephony/IccFileNotFound.java
deleted file mode 100644
index 915cea6..0000000
--- a/telephony/java/com/android/internal/telephony/IccFileNotFound.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public class IccFileNotFound extends IccException {
- IccFileNotFound() {
-
- }
-
- IccFileNotFound(String s) {
- super(s);
- }
-
- IccFileNotFound(int ef) {
- super("ICC EF Not Found 0x" + Integer.toHexString(ef));
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java b/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java
deleted file mode 100644
index 66fcfa9..0000000
--- a/telephony/java/com/android/internal/telephony/IccFileTypeMismatch.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public class IccFileTypeMismatch extends IccException {
- public IccFileTypeMismatch() {
-
- }
-
- public IccFileTypeMismatch(String s) {
- super(s);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccIoResult.java b/telephony/java/com/android/internal/telephony/IccIoResult.java
deleted file mode 100644
index 7043da5..0000000
--- a/telephony/java/com/android/internal/telephony/IccIoResult.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public class
-IccIoResult {
- public int sw1;
- public int sw2;
-
- public byte[] payload;
-
- public IccIoResult(int sw1, int sw2, byte[] payload) {
- this.sw1 = sw1;
- this.sw2 = sw2;
- this.payload = payload;
- }
-
- public IccIoResult(int sw1, int sw2, String hexString) {
- this(sw1, sw2, IccUtils.hexStringToBytes(hexString));
- }
-
- public String toString() {
- return "IccIoResponse sw1:0x" + Integer.toHexString(sw1) + " sw2:0x"
- + Integer.toHexString(sw2);
- }
-
- /**
- * true if this operation was successful
- * See GSM 11.11 Section 9.4
- * (the fun stuff is absent in 51.011)
- */
- public boolean success() {
- return sw1 == 0x90 || sw1 == 0x91 || sw1 == 0x9e || sw1 == 0x9f;
- }
-
- /**
- * Returns exception on error or null if success
- */
- public IccException getException() {
- if (success()) return null;
-
- switch (sw1) {
- case 0x94:
- if (sw2 == 0x08) {
- return new IccFileTypeMismatch();
- } else {
- return new IccFileNotFound();
- }
- default:
- return new IccException("sw1:" + sw1 + " sw2:" + sw2);
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
deleted file mode 100644
index 45562ca..0000000
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * 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 java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * 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 final 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]);
- }
- notifyPending(ar);
- }
- break;
- case EVENT_UPDATE_DONE:
- ar = (AsyncResult) msg.obj;
- synchronized (mLock) {
- success = (ar.exception == null);
- notifyPending(ar);
- }
- break;
- case EVENT_LOAD_DONE:
- ar = (AsyncResult)msg.obj;
- synchronized (mLock) {
- if (ar.exception == null) {
- records = (List<AdnRecord>) ar.result;
- } else {
- if(DBG) logd("Cannot load ADN records");
- if (records != null) {
- records.clear();
- }
- }
- notifyPending(ar);
- }
- break;
- }
- }
-
- private void notifyPending(AsyncResult ar) {
- if (ar.userObj == null) {
- return;
- }
- AtomicBoolean status = (AtomicBoolean) ar.userObj;
- status.set(true);
- mLock.notifyAll();
- }
- };
-
- 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. Currently the email field
- * if set in the ADN record is ignored.
- * 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);
-
- efid = updateEfForIccType(efid);
-
- synchronized(mLock) {
- checkThread();
- success = false;
- AtomicBoolean status = new AtomicBoolean(false);
- Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
- AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
- AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
- adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
- waitForResult(status);
- }
- 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. Currently the email field
- * if set in the ADN record is ignored.
- * 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;
- AtomicBoolean status = new AtomicBoolean(false);
- Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
- AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
- adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
- waitForResult(status);
- }
- 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");
- }
-
- efid = updateEfForIccType(efid);
- if (DBG) logd("getAdnRecordsInEF: efid=" + efid);
-
- synchronized(mLock) {
- checkThread();
- AtomicBoolean status = new AtomicBoolean(false);
- Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status);
- adnCache.requestLoadAllAdnLike(efid, adnCache.extensionEfForEf(efid), response);
- waitForResult(status);
- }
- 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.");
- }
- }
- }
-
- protected void waitForResult(AtomicBoolean status) {
- while (!status.get()) {
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- logd("interrupted while trying to update by search");
- }
- }
- }
-
- private int updateEfForIccType(int efid) {
- // Check if we are trying to read ADN records
- if (efid == IccConstants.EF_ADN) {
- if (phone.getIccCard().isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) {
- return IccConstants.EF_PBR;
- }
- }
- return efid;
- }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java
deleted file mode 100644
index 1c0fc52..0000000
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManagerProxy.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package 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);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccProvider.java b/telephony/java/com/android/internal/telephony/IccProvider.java
deleted file mode 100644
index a66e19d..0000000
--- a/telephony/java/com/android/internal/telephony/IccProvider.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * 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.ContentProvider;
-import android.content.UriMatcher;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-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 IccProvider extends ContentProvider {
- private static final String TAG = "IccProvider";
- private static final boolean DBG = false;
-
-
- private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] {
- "name",
- "number",
- "emails",
- "_id"
- };
-
- private static final int ADN = 1;
- private static final int FDN = 2;
- private static final int SDN = 3;
-
- private static final String STR_TAG = "tag";
- private static final String STR_NUMBER = "number";
- private static final String STR_EMAILS = "emails";
- private static final String STR_PIN2 = "pin2";
-
- private static final UriMatcher URL_MATCHER =
- new UriMatcher(UriMatcher.NO_MATCH);
-
- static {
- URL_MATCHER.addURI("icc", "adn", ADN);
- URL_MATCHER.addURI("icc", "fdn", FDN);
- URL_MATCHER.addURI("icc", "sdn", SDN);
- }
-
-
- @Override
- public boolean onCreate() {
- return true;
- }
-
- @Override
- public Cursor query(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sort) {
- switch (URL_MATCHER.match(url)) {
- case ADN:
- return loadFromEf(IccConstants.EF_ADN);
-
- case FDN:
- return loadFromEf(IccConstants.EF_FDN);
-
- case SDN:
- return loadFromEf(IccConstants.EF_SDN);
-
- default:
- throw new IllegalArgumentException("Unknown URL " + url);
- }
- }
-
- @Override
- public String getType(Uri url) {
- switch (URL_MATCHER.match(url)) {
- case ADN:
- case FDN:
- case SDN:
- return "vnd.android.cursor.dir/sim-contact";
-
- default:
- throw new IllegalArgumentException("Unknown URL " + url);
- }
- }
-
- @Override
- public Uri insert(Uri url, ContentValues initialValues) {
- Uri resultUri;
- int efType;
- String pin2 = null;
-
- if (DBG) log("insert");
-
- int match = URL_MATCHER.match(url);
- switch (match) {
- case ADN:
- efType = IccConstants.EF_ADN;
- break;
-
- case FDN:
- efType = IccConstants.EF_FDN;
- pin2 = initialValues.getAsString("pin2");
- break;
-
- default:
- throw new UnsupportedOperationException(
- "Cannot insert into URL: " + url);
- }
-
- String tag = initialValues.getAsString("tag");
- String number = initialValues.getAsString("number");
- // TODO(): Read email instead of sending null.
- boolean success = addIccRecordToEf(efType, tag, number, null, pin2);
-
- if (!success) {
- return null;
- }
-
- StringBuilder buf = new StringBuilder("content://icc/");
- switch (match) {
- case ADN:
- buf.append("adn/");
- break;
-
- case FDN:
- buf.append("fdn/");
- break;
- }
-
- // TODO: we need to find out the rowId for the newly added record
- buf.append(0);
-
- resultUri = Uri.parse(buf.toString());
-
- /*
- // notify interested parties that an insertion happened
- getContext().getContentResolver().notifyInsert(
- resultUri, rowID, null);
- */
-
- return resultUri;
- }
-
- private String normalizeValue(String inVal) {
- int len = inVal.length();
- String retVal = inVal;
-
- if (inVal.charAt(0) == '\'' && inVal.charAt(len-1) == '\'') {
- retVal = inVal.substring(1, len-1);
- }
-
- return retVal;
- }
-
- @Override
- public int delete(Uri url, String where, String[] whereArgs) {
- int efType;
-
- if (DBG) log("delete");
-
- int match = URL_MATCHER.match(url);
- switch (match) {
- case ADN:
- efType = IccConstants.EF_ADN;
- break;
-
- case FDN:
- efType = IccConstants.EF_FDN;
- break;
-
- default:
- throw new UnsupportedOperationException(
- "Cannot insert into URL: " + url);
- }
-
- // parse where clause
- String tag = null;
- String number = null;
- String[] emails = null;
- String pin2 = null;
-
- String[] tokens = where.split("AND");
- int n = tokens.length;
-
- while (--n >= 0) {
- String param = tokens[n];
- if (DBG) log("parsing '" + param + "'");
-
- String[] pair = param.split("=");
-
- if (pair.length != 2) {
- Log.e(TAG, "resolve: bad whereClause parameter: " + param);
- continue;
- }
-
- String key = pair[0].trim();
- String val = pair[1].trim();
-
- if (STR_TAG.equals(key)) {
- tag = normalizeValue(val);
- } else if (STR_NUMBER.equals(key)) {
- number = normalizeValue(val);
- } else if (STR_EMAILS.equals(key)) {
- //TODO(): Email is null.
- emails = null;
- } else if (STR_PIN2.equals(key)) {
- pin2 = normalizeValue(val);
- }
- }
-
- if (TextUtils.isEmpty(number)) {
- return 0;
- }
-
- if (efType == IccConstants.EF_FDN && TextUtils.isEmpty(pin2)) {
- return 0;
- }
-
- boolean success = deleteIccRecordFromEf(efType, tag, number, emails, pin2);
- if (!success) {
- return 0;
- }
-
- return 1;
- }
-
- @Override
- public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
- int efType;
- String pin2 = null;
-
- if (DBG) log("update");
-
- int match = URL_MATCHER.match(url);
- switch (match) {
- case ADN:
- efType = IccConstants.EF_ADN;
- break;
-
- case FDN:
- efType = IccConstants.EF_FDN;
- pin2 = values.getAsString("pin2");
- break;
-
- default:
- throw new UnsupportedOperationException(
- "Cannot insert into URL: " + url);
- }
-
- String tag = values.getAsString("tag");
- String number = values.getAsString("number");
- String[] emails = null;
- String newTag = values.getAsString("newTag");
- String newNumber = values.getAsString("newNumber");
- String[] newEmails = null;
- // TODO(): Update for email.
- boolean success = updateIccRecordInEf(efType, tag, number,
- newTag, newNumber, pin2);
-
- if (!success) {
- return 0;
- }
-
- return 1;
- }
-
- private MatrixCursor loadFromEf(int efType) {
- if (DBG) log("loadFromEf: efType=" + efType);
-
- List<AdnRecord> adnRecords = null;
- try {
- IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
- ServiceManager.getService("simphonebook"));
- 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
- final int N = adnRecords.size();
- final MatrixCursor cursor = new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES, N);
- if (DBG) log("adnRecords.size=" + N);
- for (int i = 0; i < N ; i++) {
- loadRecord(adnRecords.get(i), cursor, i);
- }
- return cursor;
- } else {
- // No results to load
- Log.w(TAG, "Cannot load ADN records");
- return new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES);
- }
- }
-
- private boolean
- addIccRecordToEf(int efType, String name, String number, String[] emails, String pin2) {
- if (DBG) log("addIccRecordToEf: efType=" + efType + ", name=" + name +
- ", number=" + number + ", emails=" + emails);
-
- boolean success = false;
-
- // TODO: do we need to call getAdnRecordsInEf() before calling
- // 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 {
- IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
- ServiceManager.getService("simphonebook"));
- 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("addIccRecordToEf: " + success);
- return success;
- }
-
- private boolean
- updateIccRecordInEf(int efType, String oldName, String oldNumber,
- String newName, String newNumber, String pin2) {
- if (DBG) log("updateIccRecordInEf: efType=" + efType +
- ", oldname=" + oldName + ", oldnumber=" + oldNumber +
- ", newname=" + newName + ", newnumber=" + newNumber);
- boolean success = false;
-
- try {
- IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
- ServiceManager.getService("simphonebook"));
- if (iccIpb != null) {
- success = iccIpb.updateAdnRecordsInEfBySearch(efType,
- oldName, oldNumber, newName, newNumber, pin2);
- }
- } catch (RemoteException ex) {
- // ignore it
- } catch (SecurityException ex) {
- if (DBG) log(ex.toString());
- }
- if (DBG) log("updateIccRecordInEf: " + success);
- return success;
- }
-
-
- private boolean deleteIccRecordFromEf(int efType, String name, String number, String[] emails,
- String pin2) {
- if (DBG) log("deleteIccRecordFromEf: efType=" + efType +
- ", name=" + name + ", number=" + number + ", emails=" + emails + ", pin2=" + pin2);
-
- boolean success = false;
-
- try {
- IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(
- ServiceManager.getService("simphonebook"));
- 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("deleteIccRecordFromEf: " + success);
- return success;
- }
-
- /**
- * Loads an AdnRecord into a MatrixCursor. Must be called with mLock held.
- *
- * @param record the ADN record to load from
- * @param cursor the cursor to receive the results
- */
- private void loadRecord(AdnRecord record, MatrixCursor cursor, int id) {
- if (!record.isEmpty()) {
- Object[] contact = new Object[4];
- String alphaTag = record.getAlphaTag();
- String number = record.getNumber();
-
- if (DBG) log("loadRecord: " + alphaTag + ", " + number + ",");
- contact[0] = alphaTag;
- contact[1] = number;
-
- String[] emails = record.getEmails();
- if (emails != null) {
- StringBuilder emailString = new StringBuilder();
- for (String email: emails) {
- if (DBG) log("Adding email:" + email);
- emailString.append(email);
- emailString.append(",");
- }
- contact[2] = emailString.toString();
- }
- contact[3] = id;
- cursor.addRow(contact);
- }
- }
-
- private void log(String msg) {
- Log.d(TAG, "[IccProvider] " + msg);
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
deleted file mode 100644
index 41c9d5a..0000000
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * 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.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
-
-/**
- * {@hide}
- */
-public abstract class IccRecords extends Handler implements IccConstants {
-
- protected static final boolean DBG = true;
- // ***** Instance Variables
- protected boolean mDestroyed = false; // set to true once this object needs to be disposed of
- protected Context mContext;
- protected CommandsInterface mCi;
- protected IccFileHandler mFh;
- protected IccCard mParentCard;
-
- protected RegistrantList recordsLoadedRegistrants = new RegistrantList();
- protected RegistrantList mRecordsEventsRegistrants = new RegistrantList();
- protected RegistrantList mNewSmsRegistrants = new RegistrantList();
- protected RegistrantList mNetworkSelectionModeAutomaticRegistrants = 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 = UNINITIALIZED;
- protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
-
- protected String spn;
-
- // ***** Constants
-
- // Markers for mncLength
- protected static final int UNINITIALIZED = -1;
- protected static final int UNKNOWN = 0;
-
- // 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;
- public static final int EVENT_MWI = 0;
- public static final int EVENT_CFI = 1;
- public static final int EVENT_SPN = 2;
-
- public static final int EVENT_GET_ICC_RECORD_DONE = 100;
-
- /**
- * Generic ICC record loaded callback. Subclasses can call EF load methods on
- * {@link IccFileHandler} passing a Message for onLoaded with the what field set to
- * {@link #EVENT_GET_ICC_RECORD_DONE} and the obj field set to an instance
- * of this interface. The {@link #handleMessage} method in this class will print a
- * log message using {@link #getEfName()} and decrement {@link #recordsToLoad}.
- *
- * If the record load was successful, {@link #onRecordLoaded} will be called with the result.
- * Otherwise, an error log message will be output by {@link #handleMessage} and
- * {@link #onRecordLoaded} will not be called.
- */
- public interface IccRecordLoaded {
- String getEfName();
- void onRecordLoaded(AsyncResult ar);
- }
-
- // ***** Constructor
- public IccRecords(IccCard card, Context c, CommandsInterface ci) {
- mContext = c;
- mCi = ci;
- mFh = card.getIccFileHandler();
- mParentCard = card;
- }
-
- /**
- * Call when the IccRecords object is no longer going to be used.
- */
- public void dispose() {
- mDestroyed = true;
- mParentCard = null;
- mFh = null;
- mCi = null;
- mContext = null;
- }
-
- protected abstract void onRadioOffOrNotAvailable();
- public abstract void onReady();
-
- //***** Public Methods
- public AdnRecordCache getAdnCache() {
- return adnCache;
- }
-
- public IccCard getIccCard() {
- return mParentCard;
- }
-
- public void registerForRecordsLoaded(Handler h, int what, Object obj) {
- if (mDestroyed) {
- return;
- }
-
- 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 void registerForRecordsEvents(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mRecordsEventsRegistrants.add(r);
- }
- public void unregisterForRecordsEvents(Handler h) {
- mRecordsEventsRegistrants.remove(h);
- }
-
- public void registerForNewSms(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mNewSmsRegistrants.add(r);
- }
- public void unregisterForNewSms(Handler h) {
- mNewSmsRegistrants.remove(h);
- }
-
- public void registerForNetworkSelectionModeAutomatic(
- Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mNetworkSelectionModeAutomaticRegistrants.add(r);
- }
- public void unregisterForNetworkSelectionModeAutomatic(Handler h) {
- mNetworkSelectionModeAutomaticRegistrants.remove(h);
- }
-
- /**
- * Get the International Mobile Subscriber ID (IMSI) on a SIM
- * for GSM, UMTS and like networks. Default is null if IMSI is
- * not supported or unavailable.
- *
- * @return null if SIM is not yet ready or unavailable
- */
- public String getIMSI() {
- return null;
- }
-
- 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(mFh).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 getVoiceMessageCount() {
- 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
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_GET_ICC_RECORD_DONE:
- try {
- AsyncResult ar = (AsyncResult) msg.obj;
- IccRecordLoaded recordLoaded = (IccRecordLoaded) ar.userObj;
- if (DBG) log(recordLoaded.getEfName() + " LOADED");
-
- if (ar.exception != null) {
- loge("Record Load Exception: " + ar.exception);
- } else {
- recordLoaded.onRecordLoaded(ar);
- }
- }catch (RuntimeException exc) {
- // I don't want these exceptions to be fatal
- loge("Exception parsing SIM record: " + exc);
- } finally {
- // Count up record load responses even if they are fails
- onRecordLoaded();
- }
- break;
-
- default:
- super.handleMessage(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.
- * Generally used for GSM/UMTS and the like SIMs.
- */
- public abstract int getDisplayRule(String plmn);
-
- /**
- * Return true if "Restriction of menu options for manual PLMN selection"
- * bit is set or EF_CSP data is unavailable, return false otherwise.
- * Generally used for GSM/UMTS and the like SIMs.
- */
- public boolean isCspPlmnEnabled() {
- return false;
- }
-
- /**
- * Returns the 5 or 6 digit MCC/MNC of the operator that
- * provided the SIM card. Returns null of SIM is not yet ready
- * or is not valid for the type of IccCard. Generally used for
- * GSM/UMTS and the like SIMS
- */
- public String getOperatorNumeric() {
- return null;
- }
-
- /**
- * Get the current Voice call forwarding flag for GSM/UMTS and the like SIMs
- *
- * @return true if enabled
- */
- public boolean getVoiceCallForwardingFlag() {
- return false;
- }
-
- /**
- * Set the voice call forwarding flag for GSM/UMTS and the like SIMs
- *
- * @param line to enable/disable
- * @param enable
- */
- public void setVoiceCallForwardingFlag(int line, boolean enable) {
- }
-
- /**
- * Indicates wether SIM is in provisioned state or not.
- * Overridden only if SIM can be dynamically provisioned via OTA.
- *
- * @return true if provisioned
- */
- public boolean isProvisioned () {
- return true;
- }
-
- /**
- * Write string to log file
- *
- * @param s is the string to write
- */
- protected abstract void log(String s);
-
- /**
- * Write error string to log file.
- *
- * @param s is the string to write
- */
- protected abstract void loge(String s);
-
- /**
- * Return an interface to retrieve the ISIM records for IMS, if available.
- * @return the interface to retrieve the ISIM records, or null if not supported
- */
- public IsimRecords getIsimRecords() {
- return null;
- }
-
- public UsimServiceTable getUsimServiceTable() {
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccRefreshResponse.java b/telephony/java/com/android/internal/telephony/IccRefreshResponse.java
deleted file mode 100644
index 6806703..0000000
--- a/telephony/java/com/android/internal/telephony/IccRefreshResponse.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 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_SimRefresh in include/telephony/ril.h
- *
- * {@hide}
- */
-
-public class IccRefreshResponse {
-
- public static final int REFRESH_RESULT_FILE_UPDATE = 0; /* Single file was updated */
- public static final int REFRESH_RESULT_INIT = 1; /* The Icc has been initialized */
- public static final int REFRESH_RESULT_RESET = 2; /* The Icc was reset */
-
- public int refreshResult; /* Sim Refresh result */
- public int efId; /* EFID */
- public String aid; /* null terminated string, e.g.,
- from 0xA0, 0x00 -> 0x41,
- 0x30, 0x30, 0x30 */
- /* Example: a0000000871002f310ffff89080000ff */
-
- @Override
- public String toString() {
- return "{" + refreshResult + ", " + aid +", " + efId + "}";
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccServiceTable.java b/telephony/java/com/android/internal/telephony/IccServiceTable.java
deleted file mode 100644
index ed74a11..0000000
--- a/telephony/java/com/android/internal/telephony/IccServiceTable.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2011 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.util.Log;
-
-/**
- * Wrapper class for an ICC EF containing a bit field of enabled services.
- */
-public abstract class IccServiceTable {
- protected final byte[] mServiceTable;
-
- protected IccServiceTable(byte[] table) {
- mServiceTable = table;
- }
-
- // Get the class name to use for log strings
- protected abstract String getTag();
-
- // Get the array of enums to use for toString
- protected abstract Object[] getValues();
-
- /**
- * Returns if the specified service is available.
- * @param service the service number as a zero-based offset (the enum ordinal)
- * @return true if the service is available; false otherwise
- */
- protected boolean isAvailable(int service) {
- int offset = service / 8;
- if (offset >= mServiceTable.length) {
- // Note: Enums are zero-based, but the TS service numbering is one-based
- Log.e(getTag(), "isAvailable for service " + (service + 1) + " fails, max service is " +
- (mServiceTable.length * 8));
- return false;
- }
- int bit = service % 8;
- return (mServiceTable[offset] & (1 << bit)) != 0;
- }
-
- public String toString() {
- Object[] values = getValues();
- int numBytes = mServiceTable.length;
- StringBuilder builder = new StringBuilder(getTag()).append('[')
- .append(numBytes * 8).append("]={ ");
-
- boolean addComma = false;
- for (int i = 0; i < numBytes; i++) {
- byte currentByte = mServiceTable[i];
- for (int bit = 0; bit < 8; bit++) {
- if ((currentByte & (1 << bit)) != 0) {
- if (addComma) {
- builder.append(", ");
- } else {
- addComma = true;
- }
- int ordinal = (i * 8) + bit;
- if (ordinal < values.length) {
- builder.append(values[ordinal]);
- } else {
- builder.append('#').append(ordinal + 1); // service number (one-based)
- }
- }
- }
- }
- return builder.append(" }").toString();
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
deleted file mode 100644
index 5fef6de..0000000
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-
-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 {
- 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 data based SMS to a specific application port.
- *
- * @param destAddr the address to send the message to
- * @param scAddr is the service center address or null to use
- * the current default SMSC
- * @param destPort 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 successfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- */
- public void sendData(String destAddr, String scAddr, int destPort,
- byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- mPhone.getContext().enforceCallingPermission(
- "android.permission.SEND_SMS",
- "Sending SMS message");
- if (Log.isLoggable("SMS", Log.VERBOSE)) {
- log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
- destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" +
- sentIntent + " deliveryIntent=" + deliveryIntent);
- }
- mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
- }
-
- /**
- * Send a text based SMS.
- *
- * @param destAddr the address to send the message to
- * @param scAddr is the service center address or null to use
- * the current default SMSC
- * @param text the body of the message to send
- * @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is successfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- */
- public void sendText(String destAddr, String scAddr,
- String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- mPhone.getContext().enforceCallingPermission(
- "android.permission.SEND_SMS",
- "Sending SMS message");
- if (Log.isLoggable("SMS", Log.VERBOSE)) {
- log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +
- " text='"+ text + "' sentIntent=" +
- sentIntent + " deliveryIntent=" + deliveryIntent);
- }
- mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
- }
-
- /**
- * Send a multi-part text based SMS.
- *
- * @param destAddr the address to send the message to
- * @param scAddr 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 applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntents if not null, an <code>ArrayList</code> of
- * <code>PendingIntent</code>s (one for each message part) that is
- * broadcast when the corresponding message part has been delivered
- * to the recipient. The raw pdu of the status report is in the
- * extended data ("pdu").
- */
- public void sendMultipartText(String destAddr, String scAddr, List<String> parts,
- List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
- mPhone.getContext().enforceCallingPermission(
- "android.permission.SEND_SMS",
- "Sending SMS message");
- if (Log.isLoggable("SMS", Log.VERBOSE)) {
- int i = 0;
- for (String part : parts) {
- log("sendMultipartText: destAddr=" + destAddr + ", srAddr=" + scAddr +
- ", part[" + (i++) + "]=" + part);
- }
- }
- mDispatcher.sendMultipartText(destAddr, scAddr, (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);
-
-}
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
deleted file mode 100644
index 54de508..0000000
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package 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 sendData(String destAddr, String scAddr, int destPort,
- byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- mIccSmsInterfaceManager.sendData(destAddr, scAddr, destPort, data,
- sentIntent, deliveryIntent);
- }
-
- public void sendText(String destAddr, String scAddr,
- String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- mIccSmsInterfaceManager.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
- }
-
- public void sendMultipartText(String destAddr, String scAddr,
- List<String> parts, List<PendingIntent> sentIntents,
- List<PendingIntent> deliveryIntents) throws android.os.RemoteException {
- mIccSmsInterfaceManager.sendMultipartText(destAddr, scAddr,
- parts, sentIntents, deliveryIntents);
- }
-
- public boolean enableCellBroadcast(int messageIdentifier) throws android.os.RemoteException {
- return mIccSmsInterfaceManager.enableCellBroadcast(messageIdentifier);
- }
-
- public boolean disableCellBroadcast(int messageIdentifier) throws android.os.RemoteException {
- return mIccSmsInterfaceManager.disableCellBroadcast(messageIdentifier);
- }
-
- public boolean enableCellBroadcastRange(int startMessageId, int endMessageId)
- throws android.os.RemoteException {
- return mIccSmsInterfaceManager.enableCellBroadcastRange(startMessageId, endMessageId);
- }
-
- public boolean disableCellBroadcastRange(int startMessageId, int endMessageId)
- throws android.os.RemoteException {
- return mIccSmsInterfaceManager.disableCellBroadcastRange(startMessageId, endMessageId);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
deleted file mode 100644
index a966f76..0000000
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * 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.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.util.Log;
-
-import com.android.internal.telephony.GsmAlphabet;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Various methods, useful for dealing with SIM data.
- */
-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
- * values.
- *
- * Stops on invalid BCD value, returning string so far
- */
- public static String
- 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;
- // Some PLMNs have 'f' as high nibble, ignore it
- if (v == 0xf) continue;
- if (v > 9) break;
- ret.append((char)('0' + v));
- }
-
- return ret.toString();
- }
-
- /**
- * Decode cdma byte into String.
- */
- public static String
- cdmaBcdToString(byte[] data, int offset, int length) {
- StringBuilder ret = new StringBuilder(length);
-
- int count = 0;
- for (int i = offset; count < length; i++) {
- int v;
- v = data[i] & 0xf;
- if (v > 9) v = 0;
- ret.append((char)('0' + v));
-
- if (++count == length) break;
-
- v = (data[i] >> 4) & 0xf;
- if (v > 9) v = 0;
- ret.append((char)('0' + v));
- ++count;
- }
- return ret.toString();
- }
-
- /**
- * Decodes a GSM-style BCD byte, returning an int ranging from 0-99.
- *
- * In GSM land, the least significant BCD digit is stored in the most
- * significant nibble.
- *
- * Out-of-range digits are treated as 0 for the sake of the time stamp,
- * because of this:
- *
- * TS 23.040 section 9.2.3.11
- * "if the MS receives a non-integer value in the SCTS, it shall
- * assume the digit is set to 0 but shall store the entire field
- * exactly as received"
- */
- public static int
- gsmBcdByteToInt(byte b) {
- int ret = 0;
-
- // treat out-of-range BCD values as 0
- if ((b & 0xf0) <= 0x90) {
- ret = (b >> 4) & 0xf;
- }
-
- if ((b & 0x0f) <= 0x09) {
- ret += (b & 0xf) * 10;
- }
-
- return ret;
- }
-
- /**
- * Decodes a CDMA style BCD byte like {@link gsmBcdByteToInt}, but
- * opposite nibble format. The least significant BCD digit
- * is in the least significant nibble and the most significant
- * is in the most significant nibble.
- */
- public static int
- cdmaBcdByteToInt(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
- * identifier
- *
- * 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
- * shall be left justified. Unused bytes shall be set to 'FF'; or
- * - 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
- * remaining octets are 16 bit UCS2 characters ...
- * 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
- * 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
- * used with some or all of the remaining octets in the string.
- * The fourth and subsequent octets contain codings as follows:
- * If bit 8 of the octet is set to zero, the remaining 7 bits
- * of the octet contain a GSM Default Alphabet character,
- * whereas if bit 8 of the octet is set to one, then the
- * remaining seven bits are an offset value added to the
- * 16 bit base pointer defined earlier...
- * 3) If the first octet of the alpha string is set to '82', then
- * the second octet contains a value indicating the number of
- * characters in the string, and the third and fourth octets
- * contain a 16 bit number which defines the complete 16 bit
- * base pointer to a "half page" in the UCS2 code space...
- */
- public static String
- adnStringFieldToString(byte[] data, int offset, int length) {
- if (length == 0) {
- return "";
- }
- if (length >= 1) {
- if (data[offset] == (byte) 0x80) {
- int ucslen = (length - 1) / 2;
- String ret = null;
-
- try {
- ret = new String(data, offset + 1, ucslen * 2, "utf-16be");
- } catch (UnsupportedEncodingException ex) {
- Log.e(LOG_TAG, "implausible UnsupportedEncodingException",
- ex);
- }
-
- if (ret != null) {
- // trim off trailing FFFF characters
-
- ucslen = ret.length();
- while (ucslen > 0 && ret.charAt(ucslen - 1) == '\uFFFF')
- ucslen--;
-
- return ret.substring(0, ucslen);
- }
- }
- }
-
- boolean isucs2 = false;
- char base = '\0';
- int len = 0;
-
- if (length >= 3 && data[offset] == (byte) 0x81) {
- len = data[offset + 1] & 0xFF;
- if (len > length - 3)
- len = length - 3;
-
- base = (char) ((data[offset + 2] & 0xFF) << 7);
- offset += 3;
- isucs2 = true;
- } else if (length >= 4 && data[offset] == (byte) 0x82) {
- len = data[offset + 1] & 0xFF;
- if (len > length - 4)
- len = length - 4;
-
- base = (char) (((data[offset + 2] & 0xFF) << 8) |
- (data[offset + 3] & 0xFF));
- offset += 4;
- isucs2 = true;
- }
-
- if (isucs2) {
- StringBuilder ret = new StringBuilder();
-
- while (len > 0) {
- // UCS2 subset case
-
- if (data[offset] < 0) {
- ret.append((char) (base + (data[offset] & 0x7F)));
- offset++;
- len--;
- }
-
- // GSM character set case
-
- int count = 0;
- while (count < len && data[offset + count] >= 0)
- count++;
-
- ret.append(GsmAlphabet.gsm8BitUnpackedToString(data,
- offset, count));
-
- offset += count;
- len -= count;
- }
-
- return ret.toString();
- }
-
- Resources resource = Resources.getSystem();
- String defaultCharset = "";
- try {
- defaultCharset =
- resource.getString(com.android.internal.R.string.gsm_alphabet_default_charset);
- } catch (NotFoundException e) {
- // Ignore Exception and defaultCharset is set to a empty string.
- }
- return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length, defaultCharset.trim());
- }
-
- static int
- 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);
-
- throw new RuntimeException ("invalid hex char '" + c + "'");
- }
-
- /**
- * 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) {
- byte[] ret;
-
- if (s == null) return null;
-
- int sz = s.length();
-
- ret = new byte[sz/2];
-
- for (int i=0 ; i <sz ; i+=2) {
- ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4)
- | hexCharToInt(s.charAt(i+1)));
- }
-
- return ret;
- }
-
-
- /**
- * Converts a byte array into a String of hexadecimal characters.
- *
- * @param bytes an array of bytes
- *
- * @return hex string representation of bytes array
- */
- public static String
- bytesToHexString(byte[] bytes) {
- if (bytes == null) return null;
-
- StringBuilder ret = new StringBuilder(2*bytes.length);
-
- for (int i = 0 ; i < bytes.length ; i++) {
- int b;
-
- b = 0x0f & (bytes[i] >> 4);
-
- ret.append("0123456789abcdef".charAt(b));
-
- b = 0x0f & bytes[i];
-
- ret.append("0123456789abcdef".charAt(b));
- }
-
- return ret.toString();
- }
-
-
- /**
- * Convert a TS 24.008 Section 10.5.3.5a Network Name field to a string
- * "offset" points to "octet 3", the coding scheme byte
- * empty string returned on decode error
- */
- public static String
- networkNameToString(byte[] data, int offset, int length) {
- String ret;
-
- if ((data[offset] & 0x80) != 0x80 || length < 1) {
- return "";
- }
-
- switch ((data[offset] >>> 4) & 0x7) {
- case 0:
- // SMS character set
- int countSeptets;
- int unusedBits = data[offset] & 7;
- countSeptets = (((length - 1) * 8) - unusedBits) / 7 ;
- ret = GsmAlphabet.gsm7BitPackedToString(data, offset + 1, countSeptets);
- break;
- case 1:
- // UCS2
- try {
- ret = new String(data,
- offset + 1, length - 1, "utf-16");
- } catch (UnsupportedEncodingException ex) {
- ret = "";
- Log.e(LOG_TAG,"implausible UnsupportedEncodingException", ex);
- }
- break;
-
- // unsupported encoding
- default:
- ret = "";
- break;
- }
-
- // "Add CI"
- // "The MS should add the letters for the Country's Initials and
- // a separator (e.g. a space) to the text string"
-
- if ((data[offset] & 0x40) != 0) {
- // FIXME(mkf) add country initials here
-
- }
-
- return ret;
- }
-
- /**
- * Convert a TS 131.102 image instance of code scheme '11' into Bitmap
- * @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;
- int height = data[valueIndex++] & 0xFF;
- int numOfPixels = width*height;
-
- int[] pixels = new int[numOfPixels];
-
- int pixelIndex = 0;
- int bitIndex = 7;
- byte currentByte = 0x00;
- while (pixelIndex < numOfPixels) {
- // reassign data and index for every byte (8 bits).
- if (pixelIndex % 8 == 0) {
- currentByte = data[valueIndex++];
- bitIndex = 7;
- }
- pixels[pixelIndex++] = bitToRGB((currentByte >> bitIndex-- ) & 0x01);
- };
-
- if (pixelIndex != numOfPixels) {
- Log.e(LOG_TAG, "parse end and size error");
- }
- return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
- }
-
- private static int bitToRGB(int bit){
- if(bit == 1){
- return Color.WHITE;
- } else {
- return Color.BLACK;
- }
- }
-
- /**
- * 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
- * @return The color bitmap
- */
- public static Bitmap parseToRGB(byte[] data, int length,
- boolean transparency) {
- int valueIndex = 0;
- int width = data[valueIndex++] & 0xFF;
- int height = data[valueIndex++] & 0xFF;
- int bits = data[valueIndex++] & 0xFF;
- int colorNumber = data[valueIndex++] & 0xFF;
- int clutOffset = ((data[valueIndex++] & 0xFF) << 8)
- | (data[valueIndex++] & 0xFF);
-
- int[] colorIndexArray = getCLUT(data, clutOffset, colorNumber);
- if (true == transparency) {
- colorIndexArray[colorNumber - 1] = Color.TRANSPARENT;
- }
-
- int[] resultArray = null;
- if (0 == (8 % bits)) {
- resultArray = mapTo2OrderBitColor(data, valueIndex,
- (width * height), colorIndexArray, bits);
- } else {
- resultArray = mapToNon2OrderBitColor(data, valueIndex,
- (width * height), colorIndexArray, bits);
- }
-
- return Bitmap.createBitmap(resultArray, width, height,
- Bitmap.Config.RGB_565);
- }
-
- private static int[] mapTo2OrderBitColor(byte[] data, int valueIndex,
- int length, int[] colorArray, int bits) {
- if (0 != (8 % bits)) {
- Log.e(LOG_TAG, "not event number of color");
- return mapToNon2OrderBitColor(data, valueIndex, length, colorArray,
- bits);
- }
-
- int mask = 0x01;
- switch (bits) {
- case 1:
- mask = 0x01;
- break;
- case 2:
- mask = 0x03;
- break;
- case 4:
- mask = 0x0F;
- break;
- case 8:
- mask = 0xFF;
- break;
- }
-
- int[] resultArray = new int[length];
- int resultIndex = 0;
- int run = 8 / bits;
- while (resultIndex < length) {
- byte tempByte = data[valueIndex++];
- for (int runIndex = 0; runIndex < run; ++runIndex) {
- int offset = run - runIndex - 1;
- resultArray[resultIndex++] = colorArray[(tempByte >> (offset * bits))
- & mask];
- }
- }
- return resultArray;
- }
-
- private static int[] mapToNon2OrderBitColor(byte[] data, int valueIndex,
- int length, int[] colorArray, int bits) {
- if (0 == (8 % bits)) {
- Log.e(LOG_TAG, "not odd number of color");
- return mapTo2OrderBitColor(data, valueIndex, length, colorArray,
- bits);
- }
-
- int[] resultArray = new int[length];
- // TODO fix me:
- return resultArray;
- }
-
- private static int[] getCLUT(byte[] rawData, int offset, int number) {
- if (null == rawData) {
- return null;
- }
-
- int[] result = new int[number];
- int endIndex = offset + (number * 3); // 1 color use 3 bytes
- int valueIndex = offset;
- int colorIndex = 0;
- int alpha = 0xff << 24;
- do {
- result[colorIndex++] = alpha
- | ((rawData[valueIndex++] & 0xFF) << 16)
- | ((rawData[valueIndex++] & 0xFF) << 8)
- | ((rawData[valueIndex++] & 0xFF));
- } while (valueIndex < endIndex);
- return result;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IccVmFixedException.java b/telephony/java/com/android/internal/telephony/IccVmFixedException.java
deleted file mode 100644
index a75496f..0000000
--- a/telephony/java/com/android/internal/telephony/IccVmFixedException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-/**
- * {@hide}
- */
-public final class IccVmFixedException extends IccException {
- IccVmFixedException()
- {
-
- }
-
- public IccVmFixedException(String s)
- {
- super(s);
- }
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java b/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
deleted file mode 100644
index 3c9d126..0000000
--- a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-/**
- * {@hide}
- */
-public final class IccVmNotSupportedException extends IccException {
- IccVmNotSupportedException()
- {
-
- }
-
- public IccVmNotSupportedException(String s)
- {
- super(s);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/IntRangeManager.java b/telephony/java/com/android/internal/telephony/IntRangeManager.java
deleted file mode 100644
index cc7774d..0000000
--- a/telephony/java/com/android/internal/telephony/IntRangeManager.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2011 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 java.util.Iterator;
-
-/**
- * Clients can enable reception of SMS-CB messages for specific ranges of
- * message identifiers (channels). This class keeps track of the currently
- * enabled message identifiers and calls abstract methods to update the
- * radio when the range of enabled message identifiers changes.
- *
- * An update is a call to {@link #startUpdate} followed by zero or more
- * calls to {@link #addRange} followed by a call to {@link #finishUpdate}.
- * Calls to {@link #enableRange} and {@link #disableRange} will perform
- * an incremental update operation if the enabled ranges have changed.
- * A full update operation (i.e. after a radio reset) can be performed
- * by a call to {@link #updateRanges}.
- *
- * Clients are identified by String (the name associated with the User ID
- * of the caller) so that a call to remove a range can be mapped to the
- * client that enabled that range (or else rejected).
- */
-public abstract class IntRangeManager {
-
- /**
- * Initial capacity for IntRange clients array list. There will be
- * few cell broadcast listeners on a typical device, so this can be small.
- */
- private static final int INITIAL_CLIENTS_ARRAY_SIZE = 4;
-
- /**
- * One or more clients forming the continuous range [startId, endId].
- * <p>When a client is added, the IntRange may merge with one or more
- * adjacent IntRanges to form a single combined IntRange.
- * <p>When a client is removed, the IntRange may divide into several
- * non-contiguous IntRanges.
- */
- private class IntRange {
- int startId;
- int endId;
- // sorted by earliest start id
- final ArrayList<ClientRange> clients;
-
- /**
- * Create a new IntRange with a single client.
- * @param startId the first id included in the range
- * @param endId the last id included in the range
- * @param client the client requesting the enabled range
- */
- IntRange(int startId, int endId, String client) {
- this.startId = startId;
- this.endId = endId;
- clients = new ArrayList<ClientRange>(INITIAL_CLIENTS_ARRAY_SIZE);
- clients.add(new ClientRange(startId, endId, client));
- }
-
- /**
- * Create a new IntRange for an existing ClientRange.
- * @param clientRange the initial ClientRange to add
- */
- IntRange(ClientRange clientRange) {
- startId = clientRange.startId;
- endId = clientRange.endId;
- clients = new ArrayList<ClientRange>(INITIAL_CLIENTS_ARRAY_SIZE);
- clients.add(clientRange);
- }
-
- /**
- * Create a new IntRange from an existing IntRange. This is used for
- * removing a ClientRange, because new IntRanges may need to be created
- * for any gaps that open up after the ClientRange is removed. A copy
- * is made of the elements of the original IntRange preceding the element
- * that is being removed. The following elements will be added to this
- * IntRange or to a new IntRange when a gap is found.
- * @param intRange the original IntRange to copy elements from
- * @param numElements the number of elements to copy from the original
- */
- IntRange(IntRange intRange, int numElements) {
- this.startId = intRange.startId;
- this.endId = intRange.endId;
- this.clients = new ArrayList<ClientRange>(intRange.clients.size());
- for (int i=0; i < numElements; i++) {
- this.clients.add(intRange.clients.get(i));
- }
- }
-
- /**
- * Insert new ClientRange in order by start id.
- * <p>If the new ClientRange is known to be sorted before or after the
- * existing ClientRanges, or at a particular index, it can be added
- * to the clients array list directly, instead of via this method.
- * <p>Note that this can be changed from linear to binary search if the
- * number of clients grows large enough that it would make a difference.
- * @param range the new ClientRange to insert
- */
- void insert(ClientRange range) {
- int len = clients.size();
- for (int i=0; i < len; i++) {
- ClientRange nextRange = clients.get(i);
- if (range.startId <= nextRange.startId) {
- // ignore duplicate ranges from the same client
- if (!range.equals(nextRange)) {
- clients.add(i, range);
- }
- return;
- }
- }
- clients.add(range); // append to end of list
- }
- }
-
- /**
- * The message id range for a single client.
- */
- private class ClientRange {
- final int startId;
- final int endId;
- final String client;
-
- ClientRange(int startId, int endId, String client) {
- this.startId = startId;
- this.endId = endId;
- this.client = client;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o != null && o instanceof ClientRange) {
- ClientRange other = (ClientRange) o;
- return startId == other.startId &&
- endId == other.endId &&
- client.equals(other.client);
- } else {
- return false;
- }
- }
-
- @Override
- public int hashCode() {
- return (startId * 31 + endId) * 31 + client.hashCode();
- }
- }
-
- /**
- * List of integer ranges, one per client, sorted by start id.
- */
- private ArrayList<IntRange> mRanges = new ArrayList<IntRange>();
-
- protected IntRangeManager() {}
-
- /**
- * Enable a range for the specified client and update ranges
- * if necessary. If {@link #finishUpdate} returns failure,
- * false is returned and the range is not added.
- *
- * @param startId the first id included in the range
- * @param endId the last id included in the range
- * @param client the client requesting the enabled range
- * @return true if successful, false otherwise
- */
- public synchronized boolean enableRange(int startId, int endId, String client) {
- int len = mRanges.size();
-
- // empty range list: add the initial IntRange
- if (len == 0) {
- if (tryAddSingleRange(startId, endId, true)) {
- mRanges.add(new IntRange(startId, endId, client));
- return true;
- } else {
- return false; // failed to update radio
- }
- }
-
- for (int startIndex = 0; startIndex < len; startIndex++) {
- IntRange range = mRanges.get(startIndex);
- if (startId < range.startId) {
- // test if new range completely precedes this range
- // note that [1, 4] and [5, 6] coalesce to [1, 6]
- if ((endId + 1) < range.startId) {
- // insert new int range before previous first range
- if (tryAddSingleRange(startId, endId, true)) {
- mRanges.add(startIndex, new IntRange(startId, endId, client));
- return true;
- } else {
- return false; // failed to update radio
- }
- } else if (endId <= range.endId) {
- // extend the start of this range
- if (tryAddSingleRange(startId, range.startId - 1, true)) {
- range.startId = startId;
- range.clients.add(0, new ClientRange(startId, endId, client));
- return true;
- } else {
- return false; // failed to update radio
- }
- } else {
- // find last range that can coalesce into the new combined range
- for (int endIndex = startIndex+1; endIndex < len; endIndex++) {
- IntRange endRange = mRanges.get(endIndex);
- if ((endId + 1) < endRange.startId) {
- // try to add entire new range
- if (tryAddSingleRange(startId, endId, true)) {
- range.startId = startId;
- range.endId = endId;
- // insert new ClientRange before existing ranges
- range.clients.add(0, new ClientRange(startId, endId, client));
- // coalesce range with following ranges up to endIndex-1
- // remove each range after adding its elements, so the index
- // of the next range to join is always startIndex+1.
- // i is the index if no elements were removed: we only care
- // about the number of loop iterations, not the value of i.
- int joinIndex = startIndex + 1;
- for (int i = joinIndex; i < endIndex; i++) {
- IntRange joinRange = mRanges.get(joinIndex);
- range.clients.addAll(joinRange.clients);
- mRanges.remove(joinRange);
- }
- return true;
- } else {
- return false; // failed to update radio
- }
- } else if (endId <= endRange.endId) {
- // add range from start id to start of last overlapping range,
- // values from endRange.startId to endId are already enabled
- if (tryAddSingleRange(startId, endRange.startId - 1, true)) {
- range.startId = startId;
- range.endId = endRange.endId;
- // insert new ClientRange before existing ranges
- range.clients.add(0, new ClientRange(startId, endId, client));
- // coalesce range with following ranges up to endIndex
- // remove each range after adding its elements, so the index
- // of the next range to join is always startIndex+1.
- // i is the index if no elements were removed: we only care
- // about the number of loop iterations, not the value of i.
- int joinIndex = startIndex + 1;
- for (int i = joinIndex; i <= endIndex; i++) {
- IntRange joinRange = mRanges.get(joinIndex);
- range.clients.addAll(joinRange.clients);
- mRanges.remove(joinRange);
- }
- return true;
- } else {
- return false; // failed to update radio
- }
- }
- }
-
- // endId extends past all existing IntRanges: combine them all together
- if (tryAddSingleRange(startId, endId, true)) {
- range.startId = startId;
- range.endId = endId;
- // insert new ClientRange before existing ranges
- range.clients.add(0, new ClientRange(startId, endId, client));
- // coalesce range with following ranges up to len-1
- // remove each range after adding its elements, so the index
- // of the next range to join is always startIndex+1.
- // i is the index if no elements were removed: we only care
- // about the number of loop iterations, not the value of i.
- int joinIndex = startIndex + 1;
- for (int i = joinIndex; i < len; i++) {
- IntRange joinRange = mRanges.get(joinIndex);
- range.clients.addAll(joinRange.clients);
- mRanges.remove(joinRange);
- }
- return true;
- } else {
- return false; // failed to update radio
- }
- }
- } else if ((startId + 1) <= range.endId) {
- if (endId <= range.endId) {
- // completely contained in existing range; no radio changes
- range.insert(new ClientRange(startId, endId, client));
- return true;
- } else {
- // find last range that can coalesce into the new combined range
- int endIndex = startIndex;
- for (int testIndex = startIndex+1; testIndex < len; testIndex++) {
- IntRange testRange = mRanges.get(testIndex);
- if ((endId + 1) < testRange.startId) {
- break;
- } else {
- endIndex = testIndex;
- }
- }
- // no adjacent IntRanges to combine
- if (endIndex == startIndex) {
- // add range from range.endId+1 to endId,
- // values from startId to range.endId are already enabled
- if (tryAddSingleRange(range.endId + 1, endId, true)) {
- range.endId = endId;
- range.insert(new ClientRange(startId, endId, client));
- return true;
- } else {
- return false; // failed to update radio
- }
- }
- // get last range to coalesce into start range
- IntRange endRange = mRanges.get(endIndex);
- // Values from startId to range.endId have already been enabled.
- // if endId > endRange.endId, then enable range from range.endId+1 to endId,
- // else enable range from range.endId+1 to endRange.startId-1, because
- // values from endRange.startId to endId have already been added.
- int newRangeEndId = (endId <= endRange.endId) ? endRange.startId - 1 : endId;
- if (tryAddSingleRange(range.endId + 1, newRangeEndId, true)) {
- range.endId = endId;
- // insert new ClientRange in place
- range.insert(new ClientRange(startId, endId, client));
- // coalesce range with following ranges up to endIndex-1
- // remove each range after adding its elements, so the index
- // of the next range to join is always startIndex+1 (joinIndex).
- // i is the index if no elements had been removed: we only care
- // about the number of loop iterations, not the value of i.
- int joinIndex = startIndex + 1;
- for (int i = joinIndex; i < endIndex; i++) {
- IntRange joinRange = mRanges.get(joinIndex);
- range.clients.addAll(joinRange.clients);
- mRanges.remove(joinRange);
- }
- return true;
- } else {
- return false; // failed to update radio
- }
- }
- }
- }
-
- // append new range after existing IntRanges
- if (tryAddSingleRange(startId, endId, true)) {
- mRanges.add(new IntRange(startId, endId, client));
- return true;
- } else {
- return false; // failed to update radio
- }
- }
-
- /**
- * Disable a range for the specified client and update ranges
- * if necessary. If {@link #finishUpdate} returns failure,
- * false is returned and the range is not removed.
- *
- * @param startId the first id included in the range
- * @param endId the last id included in the range
- * @param client the client requesting to disable the range
- * @return true if successful, false otherwise
- */
- public synchronized boolean disableRange(int startId, int endId, String client) {
- int len = mRanges.size();
-
- for (int i=0; i < len; i++) {
- IntRange range = mRanges.get(i);
- if (startId < range.startId) {
- return false; // not found
- } else if (endId <= range.endId) {
- // found the IntRange that encloses the client range, if any
- // search for it in the clients list
- ArrayList<ClientRange> clients = range.clients;
-
- // handle common case of IntRange containing one ClientRange
- int crLength = clients.size();
- if (crLength == 1) {
- ClientRange cr = clients.get(0);
- if (cr.startId == startId && cr.endId == endId && cr.client.equals(client)) {
- // disable range in radio then remove the entire IntRange
- if (tryAddSingleRange(startId, endId, false)) {
- mRanges.remove(i);
- return true;
- } else {
- return false; // failed to update radio
- }
- } else {
- return false; // not found
- }
- }
-
- // several ClientRanges: remove one, potentially splitting into many IntRanges.
- // Save the original start and end id for the original IntRange
- // in case the radio update fails and we have to revert it. If the
- // update succeeds, we remove the client range and insert the new IntRanges.
- int largestEndId = Integer.MIN_VALUE; // largest end identifier found
- boolean updateStarted = false;
-
- for (int crIndex=0; crIndex < crLength; crIndex++) {
- ClientRange cr = clients.get(crIndex);
- if (cr.startId == startId && cr.endId == endId && cr.client.equals(client)) {
- // found the ClientRange to remove, check if it's the last in the list
- if (crIndex == crLength - 1) {
- if (range.endId == largestEndId) {
- // no channels to remove from radio; return success
- clients.remove(crIndex);
- return true;
- } else {
- // disable the channels at the end and lower the end id
- if (tryAddSingleRange(largestEndId + 1, range.endId, false)) {
- clients.remove(crIndex);
- range.endId = largestEndId;
- return true;
- } else {
- return false;
- }
- }
- }
-
- // copy the IntRange so that we can remove elements and modify the
- // start and end id's in the copy, leaving the original unmodified
- // until after the radio update succeeds
- IntRange rangeCopy = new IntRange(range, crIndex);
-
- if (crIndex == 0) {
- // removing the first ClientRange, so we may need to increase
- // the start id of the IntRange.
- // We know there are at least two ClientRanges in the list,
- // so clients.get(1) should always succeed.
- int nextStartId = clients.get(1).startId;
- if (nextStartId != range.startId) {
- startUpdate();
- updateStarted = true;
- addRange(range.startId, nextStartId - 1, false);
- rangeCopy.startId = nextStartId;
- }
- // init largestEndId
- largestEndId = clients.get(1).endId;
- }
-
- // go through remaining ClientRanges, creating new IntRanges when
- // there is a gap in the sequence. After radio update succeeds,
- // remove the original IntRange and append newRanges to mRanges.
- // Otherwise, leave the original IntRange in mRanges and return false.
- ArrayList<IntRange> newRanges = new ArrayList<IntRange>();
-
- IntRange currentRange = rangeCopy;
- for (int nextIndex = crIndex + 1; nextIndex < crLength; nextIndex++) {
- ClientRange nextCr = clients.get(nextIndex);
- if (nextCr.startId > largestEndId + 1) {
- if (!updateStarted) {
- startUpdate();
- updateStarted = true;
- }
- addRange(largestEndId + 1, nextCr.startId - 1, false);
- currentRange.endId = largestEndId;
- newRanges.add(currentRange);
- currentRange = new IntRange(nextCr);
- } else {
- currentRange.clients.add(nextCr);
- }
- if (nextCr.endId > largestEndId) {
- largestEndId = nextCr.endId;
- }
- }
-
- // remove any channels between largestEndId and endId
- if (largestEndId < endId) {
- if (!updateStarted) {
- startUpdate();
- updateStarted = true;
- }
- addRange(largestEndId + 1, endId, false);
- currentRange.endId = largestEndId;
- }
- newRanges.add(currentRange);
-
- if (updateStarted && !finishUpdate()) {
- return false; // failed to update radio
- }
-
- // replace the original IntRange with newRanges
- mRanges.remove(i);
- mRanges.addAll(i, newRanges);
- return true;
- } else {
- // not the ClientRange to remove; save highest end ID seen so far
- if (cr.endId > largestEndId) {
- largestEndId = cr.endId;
- }
- }
- }
- }
- }
-
- return false; // not found
- }
-
- /**
- * Perform a complete update operation (enable all ranges). Useful
- * after a radio reset. Calls {@link #startUpdate}, followed by zero or
- * more calls to {@link #addRange}, followed by {@link #finishUpdate}.
- * @return true if successful, false otherwise
- */
- public boolean updateRanges() {
- startUpdate();
- Iterator<IntRange> iterator = mRanges.iterator();
- if (iterator.hasNext()) {
- IntRange range = iterator.next();
- int start = range.startId;
- int end = range.endId;
- // accumulate ranges of [startId, endId]
- while (iterator.hasNext()) {
- IntRange nextNode = iterator.next();
- // [startIdA, endIdA], [endIdA + 1, endIdB] -> [startIdA, endIdB]
- if (nextNode.startId <= (end + 1)) {
- if (nextNode.endId > end) {
- end = nextNode.endId;
- }
- } else {
- addRange(start, end, true);
- start = nextNode.startId;
- end = nextNode.endId;
- }
- }
- // add final range
- addRange(start, end, true);
- }
- return finishUpdate();
- }
-
- /**
- * Enable or disable a single range of message identifiers.
- * @param startId the first id included in the range
- * @param endId the last id included in the range
- * @param selected true to enable range, false to disable range
- * @return true if successful, false otherwise
- */
- private boolean tryAddSingleRange(int startId, int endId, boolean selected) {
- startUpdate();
- addRange(startId, endId, selected);
- return finishUpdate();
- }
-
- /**
- * Returns whether the list of ranges is completely empty.
- * @return true if there are no enabled ranges
- */
- public boolean isEmpty() {
- return mRanges.isEmpty();
- }
-
- /**
- * Called when the list of enabled ranges has changed. This will be
- * followed by zero or more calls to {@link #addRange} followed by
- * a call to {@link #finishUpdate}.
- */
- protected abstract void startUpdate();
-
- /**
- * Called after {@link #startUpdate} to indicate a range of enabled
- * or disabled values.
- *
- * @param startId the first id included in the range
- * @param endId the last id included in the range
- * @param selected true to enable range, false to disable range
- */
- protected abstract void addRange(int startId, int endId, boolean selected);
-
- /**
- * Called to indicate the end of a range update started by the
- * previous call to {@link #startUpdate}.
- * @return true if successful, false otherwise
- */
- protected abstract boolean finishUpdate();
-}
diff --git a/telephony/java/com/android/internal/telephony/MccTable.java b/telephony/java/com/android/internal/telephony/MccTable.java
deleted file mode 100644
index b6711bc..0000000
--- a/telephony/java/com/android/internal/telephony/MccTable.java
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * 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.ActivityManagerNative;
-import android.app.AlarmManager;
-import android.app.IActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.net.wifi.WifiManager;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Locale;
-import libcore.icu.TimeZones;
-
-/**
- * Mobile Country Code
- *
- * {@hide}
- */
-public final class MccTable
-{
- static final String LOG_TAG = "MccTable";
-
- static ArrayList<MccEntry> table;
-
- static class MccEntry implements Comparable<MccEntry>
- {
- int mcc;
- String iso;
- int smallestDigitsMnc;
- String language;
-
- MccEntry(int mnc, String iso, int smallestDigitsMCC) {
- this(mnc, iso, smallestDigitsMCC, null);
- }
-
- MccEntry(int mnc, String iso, int smallestDigitsMCC, String language) {
- this.mcc = mnc;
- this.iso = iso;
- this.smallestDigitsMnc = smallestDigitsMCC;
- this.language = language;
- }
-
-
- public int compareTo(MccEntry o)
- {
- return mcc - o.mcc;
- }
- }
-
- private static MccEntry
- entryForMcc(int mcc)
- {
- int index;
-
- MccEntry m;
-
- m = new MccEntry(mcc, null, 0);
-
- index = Collections.binarySearch(table, m);
-
- if (index < 0) {
- return null;
- } else {
- return table.get(index);
- }
- }
-
- /**
- * Returns a default time zone ID for the given MCC.
- * @param mcc Mobile Country Code
- * @return default TimeZone ID, or null if not specified
- */
- public static String defaultTimeZoneForMcc(int mcc) {
- MccEntry entry;
-
- entry = entryForMcc(mcc);
- if (entry == null || entry.iso == null) {
- return null;
- } else {
- Locale locale;
- if (entry.language == null) {
- locale = new Locale(entry.iso);
- } else {
- locale = new Locale(entry.language, entry.iso);
- }
- String[] tz = TimeZones.forLocale(locale);
- if (tz.length == 0) return null;
- return tz[0];
- }
- }
-
- /**
- * Given a GSM Mobile Country Code, returns
- * an ISO two-character country code if available.
- * Returns "" if unavailable.
- */
- public static String
- countryCodeForMcc(int mcc)
- {
- MccEntry entry;
-
- entry = entryForMcc(mcc);
-
- if (entry == null) {
- return "";
- } else {
- return entry.iso;
- }
- }
-
- /**
- * Given a GSM Mobile Country Code, returns
- * an ISO 2-3 character language code if available.
- * Returns null if unavailable.
- */
- public static String defaultLanguageForMcc(int mcc) {
- MccEntry entry;
-
- entry = entryForMcc(mcc);
-
- if (entry == null) {
- return null;
- } else {
- return entry.language;
- }
- }
-
- /**
- * Given a GSM Mobile Country Code, returns
- * the smallest number of digits that M if available.
- * Returns 2 if unavailable.
- */
- public static int
- smallestDigitsMccForMnc(int mcc)
- {
- MccEntry entry;
-
- entry = entryForMcc(mcc);
-
- if (entry == null) {
- return 2;
- } else {
- return entry.smallestDigitsMnc;
- }
- }
-
- /**
- * Updates MCC and MNC device configuration information for application retrieving
- * correct version of resources. If either MCC or MNC is 0, they will be ignored (not set).
- * @param context Context to act on.
- * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
- */
- public static void updateMccMncConfiguration(Context context, String mccmnc) {
- if (!TextUtils.isEmpty(mccmnc)) {
- int mcc, mnc;
-
- try {
- mcc = Integer.parseInt(mccmnc.substring(0,3));
- mnc = Integer.parseInt(mccmnc.substring(3));
- } catch (NumberFormatException e) {
- Log.e(LOG_TAG, "Error parsing IMSI");
- return;
- }
-
- Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
-
- if (mcc != 0) {
- setTimezoneFromMccIfNeeded(context, mcc);
- setLocaleFromMccIfNeeded(context, mcc);
- setWifiCountryCodeFromMcc(context, mcc);
- }
- try {
- Configuration config = ActivityManagerNative.getDefault().getConfiguration();
- if (mcc != 0) {
- config.mcc = mcc;
- }
- if (mnc != 0) {
- config.mnc = mnc;
- }
- ActivityManagerNative.getDefault().updateConfiguration(config);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Can't update configuration", e);
- }
- }
- }
-
- /**
- * Utility code to set the system locale if it's not set already
- * @param context Context to act on.
- * @param language Two character language code desired
- * @param country Two character country code desired
- *
- * {@hide}
- */
- public static void setSystemLocale(Context context, String language, String country) {
- String l = SystemProperties.get("persist.sys.language");
- String c = SystemProperties.get("persist.sys.country");
-
- if (null == language) {
- return; // no match possible
- }
- language = language.toLowerCase();
- if (null == country) {
- country = "";
- }
- country = country.toUpperCase();
-
- if((null == l || 0 == l.length()) && (null == c || 0 == c.length())) {
- try {
- // try to find a good match
- String[] locales = context.getAssets().getLocales();
- final int N = locales.length;
- String bestMatch = null;
- for(int i = 0; i < N; i++) {
- // only match full (lang + country) locales
- if (locales[i]!=null && locales[i].length() >= 5 &&
- locales[i].substring(0,2).equals(language)) {
- if (locales[i].substring(3,5).equals(country)) {
- bestMatch = locales[i];
- break;
- } else if (null == bestMatch) {
- bestMatch = locales[i];
- }
- }
- }
- if (null != bestMatch) {
- IActivityManager am = ActivityManagerNative.getDefault();
- Configuration config = am.getConfiguration();
- config.locale = new Locale(bestMatch.substring(0,2),
- bestMatch.substring(3,5));
- config.userSetLocale = true;
- am.updateConfiguration(config);
- }
- } catch (Exception e) {
- // Intentionally left blank
- }
- }
- }
-
- /**
- * If the timezone is not already set, set it based on the MCC of the SIM.
- * @param context Context to act on.
- * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
- */
- private static void setTimezoneFromMccIfNeeded(Context context, int mcc) {
- String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY);
- if (timezone == null || timezone.length() == 0) {
- String zoneId = defaultTimeZoneForMcc(mcc);
- if (zoneId != null && zoneId.length() > 0) {
- // Set time zone based on MCC
- AlarmManager alarm =
- (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- alarm.setTimeZone(zoneId);
- Log.d(LOG_TAG, "timezone set to "+zoneId);
- }
- }
- }
-
- /**
- * If the locale is not already set, set it based on the MCC of the SIM.
- * @param context Context to act on.
- * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
- */
- private static void setLocaleFromMccIfNeeded(Context context, int mcc) {
- if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
- // Avoid system locale is set from MCC table if CDMALTEPhone is used.
- // The locale will be picked up based on EFpl/EFli once CSIM records are loaded.
- return;
- }
- String language = MccTable.defaultLanguageForMcc(mcc);
- String country = MccTable.countryCodeForMcc(mcc);
-
- Log.d(LOG_TAG, "locale set to "+language+"_"+country);
- setSystemLocale(context, language, country);
- }
-
- /**
- * If the number of allowed wifi channels has not been set, set it based on
- * the MCC of the SIM.
- * @param context Context to act on.
- * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
- */
- private static void setWifiCountryCodeFromMcc(Context context, int mcc) {
- String country = MccTable.countryCodeForMcc(mcc);
- if (!country.isEmpty()) {
- Log.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country);
- WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- //persist
- wM.setCountryCode(country, true);
- }
- }
-
- static {
- table = new ArrayList<MccEntry>(240);
-
-
- /*
- * The table below is built from two resources:
- *
- * 1) ITU "Mobile Network Code (MNC) for the international
- * identification plan for mobile terminals and mobile users"
- * which is available as an annex to the ITU operational bulletin
- * available here: http://www.itu.int/itu-t/bulletin/annex.html
- *
- * 2) The ISO 3166 country codes list, available here:
- * http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
- *
- * This table has not been verified.
- *
- */
-
- table.add(new MccEntry(202,"gr",2)); //Greece
- table.add(new MccEntry(204,"nl",2,"nl")); //Netherlands (Kingdom of the)
- table.add(new MccEntry(206,"be",2)); //Belgium
- table.add(new MccEntry(208,"fr",2,"fr")); //France
- table.add(new MccEntry(212,"mc",2)); //Monaco (Principality of)
- table.add(new MccEntry(213,"ad",2)); //Andorra (Principality of)
- table.add(new MccEntry(214,"es",2,"es")); //Spain
- table.add(new MccEntry(216,"hu",2)); //Hungary (Republic of)
- table.add(new MccEntry(218,"ba",2)); //Bosnia and Herzegovina
- table.add(new MccEntry(219,"hr",2)); //Croatia (Republic of)
- table.add(new MccEntry(220,"rs",2)); //Serbia and Montenegro
- table.add(new MccEntry(222,"it",2,"it")); //Italy
- table.add(new MccEntry(225,"va",2,"it")); //Vatican City State
- table.add(new MccEntry(226,"ro",2)); //Romania
- table.add(new MccEntry(228,"ch",2,"de")); //Switzerland (Confederation of)
- table.add(new MccEntry(230,"cz",2,"cs")); //Czech Republic
- table.add(new MccEntry(231,"sk",2)); //Slovak Republic
- table.add(new MccEntry(232,"at",2,"de")); //Austria
- table.add(new MccEntry(234,"gb",2,"en")); //United Kingdom of Great Britain and Northern Ireland
- table.add(new MccEntry(235,"gb",2,"en")); //United Kingdom of Great Britain and Northern Ireland
- table.add(new MccEntry(238,"dk",2)); //Denmark
- table.add(new MccEntry(240,"se",2)); //Sweden
- table.add(new MccEntry(242,"no",2)); //Norway
- table.add(new MccEntry(244,"fi",2)); //Finland
- table.add(new MccEntry(246,"lt",2)); //Lithuania (Republic of)
- table.add(new MccEntry(247,"lv",2)); //Latvia (Republic of)
- table.add(new MccEntry(248,"ee",2)); //Estonia (Republic of)
- table.add(new MccEntry(250,"ru",2)); //Russian Federation
- table.add(new MccEntry(255,"ua",2)); //Ukraine
- table.add(new MccEntry(257,"by",2)); //Belarus (Republic of)
- table.add(new MccEntry(259,"md",2)); //Moldova (Republic of)
- table.add(new MccEntry(260,"pl",2)); //Poland (Republic of)
- table.add(new MccEntry(262,"de",2,"de")); //Germany (Federal Republic of)
- table.add(new MccEntry(266,"gi",2)); //Gibraltar
- table.add(new MccEntry(268,"pt",2)); //Portugal
- table.add(new MccEntry(270,"lu",2)); //Luxembourg
- table.add(new MccEntry(272,"ie",2,"en")); //Ireland
- table.add(new MccEntry(274,"is",2)); //Iceland
- table.add(new MccEntry(276,"al",2)); //Albania (Republic of)
- table.add(new MccEntry(278,"mt",2)); //Malta
- table.add(new MccEntry(280,"cy",2)); //Cyprus (Republic of)
- table.add(new MccEntry(282,"ge",2)); //Georgia
- table.add(new MccEntry(283,"am",2)); //Armenia (Republic of)
- table.add(new MccEntry(284,"bg",2)); //Bulgaria (Republic of)
- table.add(new MccEntry(286,"tr",2)); //Turkey
- table.add(new MccEntry(288,"fo",2)); //Faroe Islands
- table.add(new MccEntry(289,"ge",2)); //Abkhazia (Georgia)
- table.add(new MccEntry(290,"gl",2)); //Greenland (Denmark)
- table.add(new MccEntry(292,"sm",2)); //San Marino (Republic of)
- table.add(new MccEntry(293,"si",2)); //Slovenia (Republic of)
- table.add(new MccEntry(294,"mk",2)); //The Former Yugoslav Republic of Macedonia
- table.add(new MccEntry(295,"li",2)); //Liechtenstein (Principality of)
- table.add(new MccEntry(297,"me",2)); //Montenegro (Republic of)
- table.add(new MccEntry(302,"ca",3,"")); //Canada
- table.add(new MccEntry(308,"pm",2)); //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
- table.add(new MccEntry(310,"us",3,"en")); //United States of America
- table.add(new MccEntry(311,"us",3,"en")); //United States of America
- table.add(new MccEntry(312,"us",3,"en")); //United States of America
- table.add(new MccEntry(313,"us",3,"en")); //United States of America
- table.add(new MccEntry(314,"us",3,"en")); //United States of America
- table.add(new MccEntry(315,"us",3,"en")); //United States of America
- table.add(new MccEntry(316,"us",3,"en")); //United States of America
- table.add(new MccEntry(330,"pr",2)); //Puerto Rico
- table.add(new MccEntry(332,"vi",2)); //United States Virgin Islands
- table.add(new MccEntry(334,"mx",3)); //Mexico
- table.add(new MccEntry(338,"jm",3)); //Jamaica
- table.add(new MccEntry(340,"gp",2)); //Guadeloupe (French Department of)
- table.add(new MccEntry(342,"bb",3)); //Barbados
- table.add(new MccEntry(344,"ag",3)); //Antigua and Barbuda
- table.add(new MccEntry(346,"ky",3)); //Cayman Islands
- table.add(new MccEntry(348,"vg",3)); //British Virgin Islands
- table.add(new MccEntry(350,"bm",2)); //Bermuda
- table.add(new MccEntry(352,"gd",2)); //Grenada
- table.add(new MccEntry(354,"ms",2)); //Montserrat
- table.add(new MccEntry(356,"kn",2)); //Saint Kitts and Nevis
- table.add(new MccEntry(358,"lc",2)); //Saint Lucia
- table.add(new MccEntry(360,"vc",2)); //Saint Vincent and the Grenadines
- table.add(new MccEntry(362,"ai",2)); //Netherlands Antilles
- table.add(new MccEntry(363,"aw",2)); //Aruba
- table.add(new MccEntry(364,"bs",2)); //Bahamas (Commonwealth of the)
- table.add(new MccEntry(365,"ai",3)); //Anguilla
- table.add(new MccEntry(366,"dm",2)); //Dominica (Commonwealth of)
- table.add(new MccEntry(368,"cu",2)); //Cuba
- table.add(new MccEntry(370,"do",2)); //Dominican Republic
- table.add(new MccEntry(372,"ht",2)); //Haiti (Republic of)
- table.add(new MccEntry(374,"tt",2)); //Trinidad and Tobago
- table.add(new MccEntry(376,"tc",2)); //Turks and Caicos Islands
- table.add(new MccEntry(400,"az",2)); //Azerbaijani Republic
- table.add(new MccEntry(401,"kz",2)); //Kazakhstan (Republic of)
- table.add(new MccEntry(402,"bt",2)); //Bhutan (Kingdom of)
- table.add(new MccEntry(404,"in",2)); //India (Republic of)
- table.add(new MccEntry(405,"in",2)); //India (Republic of)
- table.add(new MccEntry(410,"pk",2)); //Pakistan (Islamic Republic of)
- table.add(new MccEntry(412,"af",2)); //Afghanistan
- table.add(new MccEntry(413,"lk",2)); //Sri Lanka (Democratic Socialist Republic of)
- table.add(new MccEntry(414,"mm",2)); //Myanmar (Union of)
- table.add(new MccEntry(415,"lb",2)); //Lebanon
- table.add(new MccEntry(416,"jo",2)); //Jordan (Hashemite Kingdom of)
- table.add(new MccEntry(417,"sy",2)); //Syrian Arab Republic
- table.add(new MccEntry(418,"iq",2)); //Iraq (Republic of)
- table.add(new MccEntry(419,"kw",2)); //Kuwait (State of)
- table.add(new MccEntry(420,"sa",2)); //Saudi Arabia (Kingdom of)
- table.add(new MccEntry(421,"ye",2)); //Yemen (Republic of)
- table.add(new MccEntry(422,"om",2)); //Oman (Sultanate of)
- table.add(new MccEntry(423,"ps",2)); //Palestine
- table.add(new MccEntry(424,"ae",2)); //United Arab Emirates
- table.add(new MccEntry(425,"il",2)); //Israel (State of)
- table.add(new MccEntry(426,"bh",2)); //Bahrain (Kingdom of)
- table.add(new MccEntry(427,"qa",2)); //Qatar (State of)
- table.add(new MccEntry(428,"mn",2)); //Mongolia
- table.add(new MccEntry(429,"np",2)); //Nepal
- table.add(new MccEntry(430,"ae",2)); //United Arab Emirates
- table.add(new MccEntry(431,"ae",2)); //United Arab Emirates
- table.add(new MccEntry(432,"ir",2)); //Iran (Islamic Republic of)
- table.add(new MccEntry(434,"uz",2)); //Uzbekistan (Republic of)
- table.add(new MccEntry(436,"tj",2)); //Tajikistan (Republic of)
- table.add(new MccEntry(437,"kg",2)); //Kyrgyz Republic
- table.add(new MccEntry(438,"tm",2)); //Turkmenistan
- table.add(new MccEntry(440,"jp",2,"ja")); //Japan
- table.add(new MccEntry(441,"jp",2,"ja")); //Japan
- table.add(new MccEntry(450,"kr",2,"ko")); //Korea (Republic of)
- table.add(new MccEntry(452,"vn",2)); //Viet Nam (Socialist Republic of)
- table.add(new MccEntry(454,"hk",2)); //"Hong Kong, China"
- table.add(new MccEntry(455,"mo",2)); //"Macao, China"
- table.add(new MccEntry(456,"kh",2)); //Cambodia (Kingdom of)
- table.add(new MccEntry(457,"la",2)); //Lao People's Democratic Republic
- table.add(new MccEntry(460,"cn",2,"zh")); //China (People's Republic of)
- table.add(new MccEntry(461,"cn",2,"zh")); //China (People's Republic of)
- table.add(new MccEntry(466,"tw",2)); //"Taiwan, China"
- table.add(new MccEntry(467,"kp",2)); //Democratic People's Republic of Korea
- table.add(new MccEntry(470,"bd",2)); //Bangladesh (People's Republic of)
- table.add(new MccEntry(472,"mv",2)); //Maldives (Republic of)
- table.add(new MccEntry(502,"my",2)); //Malaysia
- table.add(new MccEntry(505,"au",2,"en")); //Australia
- table.add(new MccEntry(510,"id",2)); //Indonesia (Republic of)
- table.add(new MccEntry(514,"tl",2)); //Democratic Republic of Timor-Leste
- table.add(new MccEntry(515,"ph",2)); //Philippines (Republic of the)
- table.add(new MccEntry(520,"th",2)); //Thailand
- table.add(new MccEntry(525,"sg",2,"en")); //Singapore (Republic of)
- table.add(new MccEntry(528,"bn",2)); //Brunei Darussalam
- table.add(new MccEntry(530,"nz",2, "en")); //New Zealand
- table.add(new MccEntry(534,"mp",2)); //Northern Mariana Islands (Commonwealth of the)
- table.add(new MccEntry(535,"gu",2)); //Guam
- table.add(new MccEntry(536,"nr",2)); //Nauru (Republic of)
- table.add(new MccEntry(537,"pg",2)); //Papua New Guinea
- table.add(new MccEntry(539,"to",2)); //Tonga (Kingdom of)
- table.add(new MccEntry(540,"sb",2)); //Solomon Islands
- table.add(new MccEntry(541,"vu",2)); //Vanuatu (Republic of)
- table.add(new MccEntry(542,"fj",2)); //Fiji (Republic of)
- table.add(new MccEntry(543,"wf",2)); //Wallis and Futuna (Territoire franais d'outre-mer)
- table.add(new MccEntry(544,"as",2)); //American Samoa
- table.add(new MccEntry(545,"ki",2)); //Kiribati (Republic of)
- table.add(new MccEntry(546,"nc",2)); //New Caledonia (Territoire franais d'outre-mer)
- table.add(new MccEntry(547,"pf",2)); //French Polynesia (Territoire franais d'outre-mer)
- table.add(new MccEntry(548,"ck",2)); //Cook Islands
- table.add(new MccEntry(549,"ws",2)); //Samoa (Independent State of)
- table.add(new MccEntry(550,"fm",2)); //Micronesia (Federated States of)
- table.add(new MccEntry(551,"mh",2)); //Marshall Islands (Republic of the)
- table.add(new MccEntry(552,"pw",2)); //Palau (Republic of)
- table.add(new MccEntry(602,"eg",2)); //Egypt (Arab Republic of)
- table.add(new MccEntry(603,"dz",2)); //Algeria (People's Democratic Republic of)
- table.add(new MccEntry(604,"ma",2)); //Morocco (Kingdom of)
- table.add(new MccEntry(605,"tn",2)); //Tunisia
- table.add(new MccEntry(606,"ly",2)); //Libya (Socialist People's Libyan Arab Jamahiriya)
- table.add(new MccEntry(607,"gm",2)); //Gambia (Republic of the)
- table.add(new MccEntry(608,"sn",2)); //Senegal (Republic of)
- table.add(new MccEntry(609,"mr",2)); //Mauritania (Islamic Republic of)
- table.add(new MccEntry(610,"ml",2)); //Mali (Republic of)
- table.add(new MccEntry(611,"gn",2)); //Guinea (Republic of)
- table.add(new MccEntry(612,"ci",2)); //Cte d'Ivoire (Republic of)
- table.add(new MccEntry(613,"bf",2)); //Burkina Faso
- table.add(new MccEntry(614,"ne",2)); //Niger (Republic of the)
- table.add(new MccEntry(615,"tg",2)); //Togolese Republic
- table.add(new MccEntry(616,"bj",2)); //Benin (Republic of)
- table.add(new MccEntry(617,"mu",2)); //Mauritius (Republic of)
- table.add(new MccEntry(618,"lr",2)); //Liberia (Republic of)
- table.add(new MccEntry(619,"sl",2)); //Sierra Leone
- table.add(new MccEntry(620,"gh",2)); //Ghana
- table.add(new MccEntry(621,"ng",2)); //Nigeria (Federal Republic of)
- table.add(new MccEntry(622,"td",2)); //Chad (Republic of)
- table.add(new MccEntry(623,"cf",2)); //Central African Republic
- table.add(new MccEntry(624,"cm",2)); //Cameroon (Republic of)
- table.add(new MccEntry(625,"cv",2)); //Cape Verde (Republic of)
- table.add(new MccEntry(626,"st",2)); //Sao Tome and Principe (Democratic Republic of)
- table.add(new MccEntry(627,"gq",2)); //Equatorial Guinea (Republic of)
- table.add(new MccEntry(628,"ga",2)); //Gabonese Republic
- table.add(new MccEntry(629,"cg",2)); //Congo (Republic of the)
- table.add(new MccEntry(630,"cg",2)); //Democratic Republic of the Congo
- table.add(new MccEntry(631,"ao",2)); //Angola (Republic of)
- table.add(new MccEntry(632,"gw",2)); //Guinea-Bissau (Republic of)
- table.add(new MccEntry(633,"sc",2)); //Seychelles (Republic of)
- table.add(new MccEntry(634,"sd",2)); //Sudan (Republic of the)
- table.add(new MccEntry(635,"rw",2)); //Rwanda (Republic of)
- table.add(new MccEntry(636,"et",2)); //Ethiopia (Federal Democratic Republic of)
- table.add(new MccEntry(637,"so",2)); //Somali Democratic Republic
- table.add(new MccEntry(638,"dj",2)); //Djibouti (Republic of)
- table.add(new MccEntry(639,"ke",2)); //Kenya (Republic of)
- table.add(new MccEntry(640,"tz",2)); //Tanzania (United Republic of)
- table.add(new MccEntry(641,"ug",2)); //Uganda (Republic of)
- table.add(new MccEntry(642,"bi",2)); //Burundi (Republic of)
- table.add(new MccEntry(643,"mz",2)); //Mozambique (Republic of)
- table.add(new MccEntry(645,"zm",2)); //Zambia (Republic of)
- table.add(new MccEntry(646,"mg",2)); //Madagascar (Republic of)
- table.add(new MccEntry(647,"re",2)); //Reunion (French Department of)
- table.add(new MccEntry(648,"zw",2)); //Zimbabwe (Republic of)
- table.add(new MccEntry(649,"na",2)); //Namibia (Republic of)
- table.add(new MccEntry(650,"mw",2)); //Malawi
- table.add(new MccEntry(651,"ls",2)); //Lesotho (Kingdom of)
- table.add(new MccEntry(652,"bw",2)); //Botswana (Republic of)
- table.add(new MccEntry(653,"sz",2)); //Swaziland (Kingdom of)
- table.add(new MccEntry(654,"km",2)); //Comoros (Union of the)
- table.add(new MccEntry(655,"za",2,"en")); //South Africa (Republic of)
- table.add(new MccEntry(657,"er",2)); //Eritrea
- table.add(new MccEntry(702,"bz",2)); //Belize
- table.add(new MccEntry(704,"gt",2)); //Guatemala (Republic of)
- table.add(new MccEntry(706,"sv",2)); //El Salvador (Republic of)
- table.add(new MccEntry(708,"hn",3)); //Honduras (Republic of)
- table.add(new MccEntry(710,"ni",2)); //Nicaragua
- table.add(new MccEntry(712,"cr",2)); //Costa Rica
- table.add(new MccEntry(714,"pa",2)); //Panama (Republic of)
- table.add(new MccEntry(716,"pe",2)); //Peru
- table.add(new MccEntry(722,"ar",3)); //Argentine Republic
- table.add(new MccEntry(724,"br",2)); //Brazil (Federative Republic of)
- table.add(new MccEntry(730,"cl",2)); //Chile
- table.add(new MccEntry(732,"co",3)); //Colombia (Republic of)
- table.add(new MccEntry(734,"ve",2)); //Venezuela (Bolivarian Republic of)
- table.add(new MccEntry(736,"bo",2)); //Bolivia (Republic of)
- table.add(new MccEntry(738,"gy",2)); //Guyana
- table.add(new MccEntry(740,"ec",2)); //Ecuador
- table.add(new MccEntry(742,"gf",2)); //French Guiana (French Department of)
- table.add(new MccEntry(744,"py",2)); //Paraguay (Republic of)
- table.add(new MccEntry(746,"sr",2)); //Suriname (Republic of)
- table.add(new MccEntry(748,"uy",2)); //Uruguay (Eastern Republic of)
- table.add(new MccEntry(750,"fk",2)); //Falkland Islands (Malvinas)
- //table.add(new MccEntry(901,"",2)); //"International Mobile, shared code"
-
- Collections.sort(table);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/MmiCode.java b/telephony/java/com/android/internal/telephony/MmiCode.java
deleted file mode 100644
index c71ff77..0000000
--- a/telephony/java/com/android/internal/telephony/MmiCode.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public interface MmiCode
-{
- /**
- * {@hide}
- */
- public enum State {
- PENDING,
- CANCELLED,
- COMPLETE,
- FAILED
- }
-
-
- /**
- * @return Current state of MmiCode request
- */
- public State getState();
-
- /**
- * @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();
-
- /**
- * @return true if the network response is a REQUEST for more user input.
- */
- public boolean isUssdRequest();
-
- /**
- * @return true if an outstanding request can be canceled.
- */
- public boolean isCancelable();
-}
diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java
deleted file mode 100644
index 1999cb3..0000000
--- a/telephony/java/com/android/internal/telephony/OperatorInfo.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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;
-
-/**
- * {@hide}
- */
-public class OperatorInfo implements Parcelable {
- public enum State {
- UNKNOWN,
- AVAILABLE,
- CURRENT,
- FORBIDDEN;
- }
-
- private String operatorAlphaLong;
- private String operatorAlphaShort;
- private String operatorNumeric;
-
- private State state = State.UNKNOWN;
-
-
- public String
- getOperatorAlphaLong() {
- return operatorAlphaLong;
- }
-
- public String
- getOperatorAlphaShort() {
- return operatorAlphaShort;
- }
-
- public String
- getOperatorNumeric() {
- return operatorNumeric;
- }
-
- public State
- getState() {
- return state;
- }
-
- OperatorInfo(String operatorAlphaLong,
- String operatorAlphaShort,
- String operatorNumeric,
- State state) {
-
- this.operatorAlphaLong = operatorAlphaLong;
- this.operatorAlphaShort = operatorAlphaShort;
- this.operatorNumeric = operatorNumeric;
-
- this.state = state;
- }
-
-
- public OperatorInfo(String operatorAlphaLong,
- String operatorAlphaShort,
- String operatorNumeric,
- String stateString) {
- this (operatorAlphaLong, operatorAlphaShort,
- operatorNumeric, rilStateToState(stateString));
- }
-
- /**
- * See state strings defined in ril.h RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
- */
- private static State rilStateToState(String s) {
- if (s.equals("unknown")) {
- return State.UNKNOWN;
- } else if (s.equals("available")) {
- return State.AVAILABLE;
- } else if (s.equals("current")) {
- return State.CURRENT;
- } else if (s.equals("forbidden")) {
- return State.FORBIDDEN;
- } else {
- throw new RuntimeException(
- "RIL impl error: Invalid network state '" + s + "'");
- }
- }
-
-
- public String toString() {
- return "OperatorInfo " + operatorAlphaLong
- + "/" + operatorAlphaShort
- + "/" + operatorNumeric
- + "/" + state;
- }
-
- /**
- * Parcelable interface implemented below.
- * This is a simple effort to make OperatorInfo parcelable rather than
- * trying to make the conventional containing object (AsyncResult),
- * implement parcelable. This functionality is needed for the
- * NetworkQueryService to fix 1128695.
- */
-
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface.
- * Method to serialize a OperatorInfo object.
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(operatorAlphaLong);
- dest.writeString(operatorAlphaShort);
- dest.writeString(operatorNumeric);
- dest.writeSerializable(state);
- }
-
- /**
- * Implement the Parcelable interface
- * Method to deserialize a OperatorInfo object, or an array thereof.
- */
- public static final Creator<OperatorInfo> CREATOR =
- new Creator<OperatorInfo>() {
- public OperatorInfo createFromParcel(Parcel in) {
- OperatorInfo opInfo = new OperatorInfo(
- in.readString(), /*operatorAlphaLong*/
- in.readString(), /*operatorAlphaShort*/
- in.readString(), /*operatorNumeric*/
- (State) in.readSerializable()); /*state*/
- return opInfo;
- }
-
- public OperatorInfo[] newArray(int size) {
- return new OperatorInfo[size];
- }
- };
-}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
deleted file mode 100644
index d41ce4d..0000000
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ /dev/null
@@ -1,1786 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.content.Context;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.telephony.CellLocation;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-
-import java.util.List;
-
-/**
- * Internal interface used to control the phone; SDK developers cannot
- * obtain this interface.
- *
- * {@hide}
- *
- */
-public interface Phone {
-
- /** used to enable additional debug messages */
- static final boolean DEBUG_PHONE = true;
-
-
- /**
- * The phone state. One of the following:<p>
- * <ul>
- * <li>IDLE = no phone activity</li>
- * <li>RINGING = a phone call is ringing or call waiting.
- * In the latter case, another call is active as well</li>
- * <li>OFFHOOK = The phone is off hook. At least one call
- * exists that is dialing, active or holding and no calls are
- * ringing or waiting.</li>
- * </ul>
- */
- enum State {
- IDLE, RINGING, OFFHOOK;
- };
-
- /**
- * The state of a data connection.
- * <ul>
- * <li>CONNECTED = IP traffic should be available</li>
- * <li>CONNECTING = Currently setting up data connection</li>
- * <li>DISCONNECTED = IP not available</li>
- * <li>SUSPENDED = connection is created but IP traffic is
- * temperately not available. i.e. voice call is in place
- * in 2G network</li>
- * </ul>
- */
- enum DataState {
- CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED;
- };
-
- public enum DataActivityState {
- /**
- * The state of a data activity.
- * <ul>
- * <li>NONE = No traffic</li>
- * <li>DATAIN = Receiving IP ppp traffic</li>
- * <li>DATAOUT = Sending IP ppp traffic</li>
- * <li>DATAINANDOUT = Both receiving and sending IP ppp traffic</li>
- * <li>DORMANT = The data connection is still active,
- but physical link is down</li>
- * </ul>
- */
- NONE, DATAIN, DATAOUT, DATAINANDOUT, DORMANT;
- };
-
- enum SuppService {
- UNKNOWN, SWITCH, SEPARATE, TRANSFER, CONFERENCE, REJECT, HANGUP;
- };
-
- static final String STATE_KEY = "state";
- static final String PHONE_NAME_KEY = "phoneName";
- static final String FAILURE_REASON_KEY = "reason";
- static final String STATE_CHANGE_REASON_KEY = "reason";
- static final String DATA_APN_TYPE_KEY = "apnType";
- static final String DATA_APN_KEY = "apn";
- static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
- static final String DATA_LINK_CAPABILITIES_KEY = "linkCapabilities";
-
- static final String DATA_IFACE_NAME_KEY = "iface";
- static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
- static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming";
- static final String PHONE_IN_ECM_STATE = "phoneinECMState";
-
- /**
- * APN types for data connections. These are usage categories for an APN
- * entry. One APN entry may support multiple APN types, eg, a single APN
- * may service regular internet traffic ("default") as well as MMS-specific
- * connections.<br/>
- * APN_TYPE_ALL is a special type to indicate that this APN entry can
- * service all data connections.
- */
- static final String APN_TYPE_ALL = "*";
- /** APN type for default data traffic */
- static final String APN_TYPE_DEFAULT = "default";
- /** APN type for MMS traffic */
- static final String APN_TYPE_MMS = "mms";
- /** APN type for SUPL assisted GPS */
- static final String APN_TYPE_SUPL = "supl";
- /** APN type for DUN traffic */
- static final String APN_TYPE_DUN = "dun";
- /** APN type for HiPri traffic */
- static final String APN_TYPE_HIPRI = "hipri";
- /** APN type for FOTA */
- static final String APN_TYPE_FOTA = "fota";
- /** APN type for IMS */
- static final String APN_TYPE_IMS = "ims";
- /** APN type for CBS */
- static final String APN_TYPE_CBS = "cbs";
-
- // "Features" accessible through the connectivity manager
- static final String FEATURE_ENABLE_MMS = "enableMMS";
- static final String FEATURE_ENABLE_SUPL = "enableSUPL";
- static final String FEATURE_ENABLE_DUN = "enableDUN";
- static final String FEATURE_ENABLE_HIPRI = "enableHIPRI";
- static final String FEATURE_ENABLE_DUN_ALWAYS = "enableDUNAlways";
- static final String FEATURE_ENABLE_FOTA = "enableFOTA";
- static final String FEATURE_ENABLE_IMS = "enableIMS";
- static final String FEATURE_ENABLE_CBS = "enableCBS";
-
- /**
- * Return codes for <code>enableApnType()</code>
- */
- static final int APN_ALREADY_ACTIVE = 0;
- static final int APN_REQUEST_STARTED = 1;
- static final int APN_TYPE_NOT_AVAILABLE = 2;
- static final int APN_REQUEST_FAILED = 3;
- static final int APN_ALREADY_INACTIVE = 4;
-
-
- /**
- * Optional reasons for disconnect and connect
- */
- static final String REASON_ROAMING_ON = "roamingOn";
- static final String REASON_ROAMING_OFF = "roamingOff";
- static final String REASON_DATA_DISABLED = "dataDisabled";
- static final String REASON_DATA_ENABLED = "dataEnabled";
- static final String REASON_DATA_ATTACHED = "dataAttached";
- static final String REASON_DATA_DETACHED = "dataDetached";
- static final String REASON_CDMA_DATA_ATTACHED = "cdmaDataAttached";
- static final String REASON_CDMA_DATA_DETACHED = "cdmaDataDetached";
- static final String REASON_APN_CHANGED = "apnChanged";
- static final String REASON_APN_SWITCHED = "apnSwitched";
- static final String REASON_APN_FAILED = "apnFailed";
- static final String REASON_RESTORE_DEFAULT_APN = "restoreDefaultApn";
- static final String REASON_RADIO_TURNED_OFF = "radioTurnedOff";
- static final String REASON_PDP_RESET = "pdpReset";
- static final String REASON_VOICE_CALL_ENDED = "2GVoiceCallEnded";
- static final String REASON_VOICE_CALL_STARTED = "2GVoiceCallStarted";
- static final String REASON_PS_RESTRICT_ENABLED = "psRestrictEnabled";
- static final String REASON_PS_RESTRICT_DISABLED = "psRestrictDisabled";
- static final String REASON_SIM_LOADED = "simLoaded";
- static final String REASON_NW_TYPE_CHANGED = "nwTypeChanged";
- static final String REASON_DATA_DEPENDENCY_MET = "dependencyMet";
- static final String REASON_DATA_DEPENDENCY_UNMET = "dependencyUnmet";
- static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
-
- // Used for band mode selection methods
- static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
- static final int BM_EURO_BAND = 1; // GSM-900 / DCS-1800 / WCDMA-IMT-2000
- static final int BM_US_BAND = 2; // GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900
- static final int BM_JPN_BAND = 3; // WCDMA-800 / WCDMA-IMT-2000
- static final int BM_AUS_BAND = 4; // GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000
- static final int BM_AUS2_BAND = 5; // GSM-900 / DCS-1800 / WCDMA-850
- static final int BM_BOUNDARY = 6; // upper band boundary
-
- // Radio Type
- static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE;
- static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE;
- static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE;
- static final int PHONE_TYPE_SIP = RILConstants.SIP_PHONE;
-
- // Modes for LTE_ON_CDMA
- static final int LTE_ON_CDMA_UNKNOWN = RILConstants.LTE_ON_CDMA_UNKNOWN;
- static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE;
- static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE;
-
- // Used for preferred network type
- // Note NT_* substitute RILConstants.NETWORK_MODE_* above the Phone
- int NT_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF;
- int NT_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY;
- int NT_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY;
- int NT_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS;
-
- int NT_MODE_CDMA = RILConstants.NETWORK_MODE_CDMA;
-
- int NT_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
- int NT_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
- int NT_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL;
-
- int NT_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY;
- int PREFERRED_NT_MODE = RILConstants.PREFERRED_NETWORK_MODE;
-
-
- // Used for CDMA roaming mode
- static final int CDMA_RM_HOME = 0; // Home Networks only, as defined in PRL
- static final int CDMA_RM_AFFILIATED = 1; // Roaming an Affiliated networks, as defined in PRL
- static final int CDMA_RM_ANY = 2; // Roaming on Any Network, as defined in PRL
-
- // Used for CDMA subscription mode
- static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // RUIM/SIM (default)
- static final int CDMA_SUBSCRIPTION_NV = 1; // NV -> non-volatile memory
-
- static final int PREFERRED_CDMA_SUBSCRIPTION = CDMA_SUBSCRIPTION_NV;
-
- static final int TTY_MODE_OFF = 0;
- static final int TTY_MODE_FULL = 1;
- static final int TTY_MODE_HCO = 2;
- static final int TTY_MODE_VCO = 3;
-
- /**
- * CDMA OTA PROVISION STATUS, the same as RIL_CDMA_OTA_Status in ril.h
- */
-
- public static final int CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED = 0;
- public static final int CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED = 1;
- public static final int CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED = 2;
- public static final int CDMA_OTA_PROVISION_STATUS_SSD_UPDATED = 3;
- public static final int CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED = 4;
- public static final int CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED = 5;
- public static final int CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED = 6;
- public static final int CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED = 7;
- public static final int CDMA_OTA_PROVISION_STATUS_COMMITTED = 8;
- public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED = 9;
- public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED = 10;
- public static final int CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED = 11;
-
-
- /**
- * Get the current ServiceState. Use
- * <code>registerForServiceStateChanged</code> to be informed of
- * updates.
- */
- ServiceState getServiceState();
-
- /**
- * Get the current CellLocation.
- */
- CellLocation getCellLocation();
-
- /**
- * Get the current for the default apn DataState. No change notification
- * exists at this interface -- use
- * {@link android.telephony.PhoneStateListener} instead.
- */
- DataState getDataConnectionState();
-
- /**
- * Get the current DataState. No change notification exists at this
- * interface -- use
- * {@link android.telephony.PhoneStateListener} instead.
- * @param apnType specify for which apn to get connection state info.
- */
- DataState getDataConnectionState(String apnType);
-
- /**
- * Get the current DataActivityState. No change notification exists at this
- * interface -- use
- * {@link android.telephony.TelephonyManager} instead.
- */
- DataActivityState getDataActivityState();
-
- /**
- * Gets the context for the phone, as set at initialization time.
- */
- Context getContext();
-
- /**
- * Disables the DNS check (i.e., allows "0.0.0.0").
- * Useful for lab testing environment.
- * @param b true disables the check, false enables.
- */
- void disableDnsCheck(boolean b);
-
- /**
- * Returns true if the DNS check is currently disabled.
- */
- boolean isDnsCheckDisabled();
-
- /**
- * Get current coarse-grained voice call state.
- * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object)
- * registerForPreciseCallStateChanged()} for change notification. <p>
- * If the phone has an active call and call waiting occurs,
- * then the phone state is RINGING not OFFHOOK
- * <strong>Note:</strong>
- * This registration point provides notification of finer-grained
- * changes.<p>
- *
- */
- State getState();
-
- /**
- * Returns a string identifier for this phone interface for parties
- * outside the phone app process.
- * @return The string name.
- */
- String getPhoneName();
-
- /**
- * Return a numerical identifier for the phone radio interface.
- * @return PHONE_TYPE_XXX as defined above.
- */
- int getPhoneType();
-
- /**
- * Returns an array of string identifiers for the APN types serviced by the
- * currently active.
- * @return The string array will always return at least one entry, Phone.APN_TYPE_DEFAULT.
- * TODO: Revisit if we always should return at least one entry.
- */
- String[] getActiveApnTypes();
-
- /**
- * Returns string for the active APN host.
- * @return type as a string or null if none.
- */
- String getActiveApnHost(String apnType);
-
- /**
- * Return the LinkProperties for the named apn or null if not available
- */
- LinkProperties getLinkProperties(String apnType);
-
- /**
- * Return the LinkCapabilities
- */
- LinkCapabilities getLinkCapabilities(String apnType);
-
- /**
- * Get current signal strength. No change notification available on this
- * interface. Use <code>PhoneStateNotifier</code> or an equivalent.
- * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
- * The following special values are defined:</p>
- * <ul><li>0 means "-113 dBm or less".</li>
- * <li>31 means "-51 dBm or greater".</li></ul>
- *
- * @return Current signal strength as SignalStrength
- */
- SignalStrength getSignalStrength();
-
- /**
- * Notifies when a previously untracked non-ringing/waiting connection has appeared.
- * This is likely due to some other entity (eg, SIM card application) initiating a call.
- */
- void registerForUnknownConnection(Handler h, int what, Object obj);
-
- /**
- * Unregisters for unknown connection notifications.
- */
- void unregisterForUnknownConnection(Handler h);
-
- /**
- * Register for getting notifications for change in the Call State {@link Call.State}
- * This is called PreciseCallState because the call state is more precise than the
- * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
- *
- * Resulting events will have an AsyncResult in <code>Message.obj</code>.
- * AsyncResult.userData will be set to the obj argument here.
- * The <em>h</em> parameter is held only by a weak reference.
- */
- void registerForPreciseCallStateChanged(Handler h, int what, Object obj);
-
- /**
- * Unregisters for voice call state change notifications.
- * Extraneous calls are tolerated silently.
- */
- void unregisterForPreciseCallStateChanged(Handler h);
-
-
- /**
- * Notifies when a new ringing or waiting connection has appeared.<p>
- *
- * Messages received from this:
- * Message.obj will be an AsyncResult
- * AsyncResult.userObj = obj
- * AsyncResult.result = a Connection. <p>
- * Please check Connection.isRinging() to make sure the Connection
- * has not dropped since this message was posted.
- * If Connection.isRinging() is true, then
- * Connection.getCall() == Phone.getRingingCall()
- */
- void registerForNewRingingConnection(Handler h, int what, Object obj);
-
- /**
- * Unregisters for new ringing connection notification.
- * Extraneous calls are tolerated silently
- */
-
- void unregisterForNewRingingConnection(Handler h);
-
- /**
- * Notifies when an incoming call rings.<p>
- *
- * Messages received from this:
- * Message.obj will be an AsyncResult
- * AsyncResult.userObj = obj
- * AsyncResult.result = a Connection. <p>
- */
- void registerForIncomingRing(Handler h, int what, Object obj);
-
- /**
- * Unregisters for ring notification.
- * Extraneous calls are tolerated silently
- */
-
- void unregisterForIncomingRing(Handler h);
-
- /**
- * Notifies when out-band ringback tone is needed.<p>
- *
- * Messages received from this:
- * Message.obj will be an AsyncResult
- * AsyncResult.userObj = obj
- * AsyncResult.result = boolean, true to start play ringback tone
- * and false to stop. <p>
- */
- void registerForRingbackTone(Handler h, int what, Object obj);
-
- /**
- * Unregisters for ringback tone notification.
- */
-
- void unregisterForRingbackTone(Handler h);
-
- /**
- * Registers the handler to reset the uplink mute state to get
- * uplink audio.
- */
- void registerForResendIncallMute(Handler h, int what, Object obj);
-
- /**
- * Unregisters for resend incall mute notifications.
- */
- void unregisterForResendIncallMute(Handler h);
-
- /**
- * Notifies when a voice connection has disconnected, either due to local
- * or remote hangup or error.
- *
- * Messages received from this will have the following members:<p>
- * <ul><li>Message.obj will be an AsyncResult</li>
- * <li>AsyncResult.userObj = obj</li>
- * <li>AsyncResult.result = a Connection object that is
- * no longer connected.</li></ul>
- */
- void registerForDisconnect(Handler h, int what, Object obj);
-
- /**
- * Unregisters for voice disconnection notification.
- * Extraneous calls are tolerated silently
- */
- void unregisterForDisconnect(Handler h);
-
-
- /**
- * Register for notifications of initiation of a new MMI code request.
- * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
- *
- * Example: If Phone.dial is called with "*#31#", then the app will
- * be notified here.<p>
- *
- * The returned <code>Message.obj</code> will contain an AsyncResult.
- *
- * <code>obj.result</code> will be an "MmiCode" object.
- */
- void registerForMmiInitiate(Handler h, int what, Object obj);
-
- /**
- * Unregisters for new MMI initiate notification.
- * Extraneous calls are tolerated silently
- */
- void unregisterForMmiInitiate(Handler h);
-
- /**
- * Register for notifications that an MMI request has completed
- * its network activity and is in its final state. This may mean a state
- * of COMPLETE, FAILED, or CANCELLED.
- *
- * <code>Message.obj</code> will contain an AsyncResult.
- * <code>obj.result</code> will be an "MmiCode" object
- */
- void registerForMmiComplete(Handler h, int what, Object obj);
-
- /**
- * Unregisters for MMI complete notification.
- * Extraneous calls are tolerated silently
- */
- void unregisterForMmiComplete(Handler h);
-
- /**
- * Registration point for Ecm timer reset
- * @param h handler to notify
- * @param what user-defined message code
- * @param obj placed in Message.obj
- */
- public void registerForEcmTimerReset(Handler h, int what, Object obj);
-
- /**
- * Unregister for notification for Ecm timer reset
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForEcmTimerReset(Handler h);
-
- /**
- * Returns a list of MMI codes that are pending. (They have initiated
- * but have not yet completed).
- * Presently there is only ever one.
- * Use <code>registerForMmiInitiate</code>
- * and <code>registerForMmiComplete</code> for change notification.
- */
- public List<? extends MmiCode> getPendingMmiCodes();
-
- /**
- * Sends user response to a USSD REQUEST message. An MmiCode instance
- * representing this response is sent to handlers registered with
- * registerForMmiInitiate.
- *
- * @param ussdMessge Message to send in the response.
- */
- public void sendUssdResponse(String ussdMessge);
-
- /**
- * Register for ServiceState changed.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a ServiceState instance
- */
- void registerForServiceStateChanged(Handler h, int what, Object obj);
-
- /**
- * Unregisters for ServiceStateChange notification.
- * Extraneous calls are tolerated silently
- */
- void unregisterForServiceStateChanged(Handler h);
-
- /**
- * Register for Supplementary Service notifications from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a SuppServiceNotification instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForSuppServiceNotification(Handler h, int what, Object obj);
-
- /**
- * Unregisters for Supplementary Service notifications.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForSuppServiceNotification(Handler h);
-
- /**
- * Register for notifications when a supplementary service attempt fails.
- * Message.obj will contain an AsyncResult.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForSuppServiceFailed(Handler h, int what, Object obj);
-
- /**
- * Unregister for notifications when a supplementary service attempt fails.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForSuppServiceFailed(Handler h);
-
- /**
- * Register for notifications when a sInCall VoicePrivacy is enabled
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
-
- /**
- * Unegister for notifications when a sInCall VoicePrivacy is enabled
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForInCallVoicePrivacyOn(Handler h);
-
- /**
- * Register for notifications when a sInCall VoicePrivacy is disabled
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj);
-
- /**
- * Unegister for notifications when a sInCall VoicePrivacy is disabled
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForInCallVoicePrivacyOff(Handler h);
-
- /**
- * Register for notifications when CDMA OTA Provision status change
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForCdmaOtaStatusChange(Handler h, int what, Object obj);
-
- /**
- * Unegister for notifications when CDMA OTA Provision status change
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForCdmaOtaStatusChange(Handler h);
-
- /**
- * Registration point for subscription info ready
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForSubscriptionInfoReady(Handler h, int what, Object obj);
-
- /**
- * Unregister for notifications for subscription info
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForSubscriptionInfoReady(Handler h);
-
- /**
- * Returns SIM record load state. Use
- * <code>getSimCard().registerForReady()</code> for change notification.
- *
- * @return true if records from the SIM have been loaded and are
- * available (if applicable). If not applicable to the underlying
- * technology, returns true as well.
- */
- boolean getIccRecordsLoaded();
-
- /**
- * Returns the ICC card interface for this phone, or null
- * if not applicable to underlying technology.
- */
- IccCard getIccCard();
-
- /**
- * Answers a ringing or waiting call. Active calls, if any, go on hold.
- * Answering occurs asynchronously, and final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException when no call is ringing or waiting
- */
- void acceptCall() throws CallStateException;
-
- /**
- * Reject (ignore) a ringing call. In GSM, this means UDUB
- * (User Determined User Busy). Reject occurs asynchronously,
- * and final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException when no call is ringing or waiting
- */
- void rejectCall() throws CallStateException;
-
- /**
- * Places any active calls on hold, and makes any held calls
- * active. Switch occurs asynchronously and may fail.
- * Final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException if a call is ringing, waiting, or
- * dialing/alerting. In these cases, this operation may not be performed.
- */
- void switchHoldingAndActive() throws CallStateException;
-
- /**
- * Whether or not the phone can conference in the current phone
- * state--that is, one call holding and one call active.
- * @return true if the phone can conference; false otherwise.
- */
- boolean canConference();
-
- /**
- * Conferences holding and active. Conference occurs asynchronously
- * and may fail. Final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException if canConference() would return false.
- * In these cases, this operation may not be performed.
- */
- void conference() throws CallStateException;
-
- /**
- * Enable or disable enhanced Voice Privacy (VP). If enhanced VP is
- * disabled, normal VP is enabled.
- *
- * @param enable whether true or false to enable or disable.
- * @param onComplete a callback message when the action is completed.
- */
- void enableEnhancedVoicePrivacy(boolean enable, Message onComplete);
-
- /**
- * Get the currently set Voice Privacy (VP) mode.
- *
- * @param onComplete a callback message when the action is completed.
- */
- void getEnhancedVoicePrivacy(Message onComplete);
-
- /**
- * Whether or not the phone can do explicit call transfer in the current
- * phone state--that is, one call holding and one call active.
- * @return true if the phone can do explicit call transfer; false otherwise.
- */
- boolean canTransfer();
-
- /**
- * Connects the two calls and disconnects the subscriber from both calls
- * Explicit Call Transfer occurs asynchronously
- * and may fail. Final notification occurs via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- *
- * @exception CallStateException if canTransfer() would return false.
- * In these cases, this operation may not be performed.
- */
- void explicitCallTransfer() throws CallStateException;
-
- /**
- * Clears all DISCONNECTED connections from Call connection lists.
- * Calls that were in the DISCONNECTED state become idle. This occurs
- * synchronously.
- */
- void clearDisconnected();
-
-
- /**
- * Gets the foreground call object, which represents all connections that
- * are dialing or active (all connections
- * that have their audio path connected).<p>
- *
- * The foreground call is a singleton object. It is constant for the life
- * of this phone. It is never null.<p>
- *
- * The foreground call will only ever be in one of these states:
- * IDLE, ACTIVE, DIALING, ALERTING, or DISCONNECTED.
- *
- * State change notification is available via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- */
- Call getForegroundCall();
-
- /**
- * Gets the background call object, which represents all connections that
- * are holding (all connections that have been accepted or connected, but
- * do not have their audio path connected). <p>
- *
- * The background call is a singleton object. It is constant for the life
- * of this phone object . It is never null.<p>
- *
- * The background call will only ever be in one of these states:
- * IDLE, HOLDING or DISCONNECTED.
- *
- * State change notification is available via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- */
- Call getBackgroundCall();
-
- /**
- * Gets the ringing call object, which represents an incoming
- * connection (if present) that is pending answer/accept. (This connection
- * may be RINGING or WAITING, and there may be only one.)<p>
-
- * The ringing call is a singleton object. It is constant for the life
- * of this phone. It is never null.<p>
- *
- * The ringing call will only ever be in one of these states:
- * IDLE, INCOMING, WAITING or DISCONNECTED.
- *
- * State change notification is available via
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}.
- */
- Call getRingingCall();
-
- /**
- * Initiate a new voice connection. This happens asynchronously, so you
- * cannot assume the audio path is connected (or a call index has been
- * assigned) until PhoneStateChanged notification has occurred.
- *
- * @exception CallStateException if a new outgoing call is not currently
- * possible because no more call slots exist or a call exists that is
- * dialing, alerting, ringing, or waiting. Other errors are
- * handled asynchronously.
- */
- Connection dial(String dialString) throws CallStateException;
-
- /**
- * Initiate a new voice connection with supplementary User to User
- * Information. This happens asynchronously, so you cannot assume the audio
- * path is connected (or a call index has been assigned) until
- * PhoneStateChanged notification has occurred.
- *
- * @exception CallStateException if a new outgoing call is not currently
- * possible because no more call slots exist or a call exists
- * that is dialing, alerting, ringing, or waiting. Other
- * errors are handled asynchronously.
- */
- Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException;
-
- /**
- * 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.
- */
- boolean handlePinMmi(String dialString);
-
- /**
- * Handles in-call MMI commands. While in a call, or while receiving a
- * call, use this to execute MMI commands.
- * see 3GPP 20.030, section 6.5.5.1 for specs on the allowed MMI commands.
- *
- * @param command the MMI command to be executed.
- * @return true if the MMI command is executed.
- * @throws CallStateException
- */
- boolean handleInCallMmiCommands(String command) throws CallStateException;
-
- /**
- * Play a DTMF tone on the active call. Ignored if there is no active call.
- * @param c should be one of 0-9, '*' or '#'. Other values will be
- * silently ignored.
- */
- void sendDtmf(char c);
-
- /**
- * Start to paly a DTMF tone on the active call. Ignored if there is no active call
- * or there is a playing DTMF tone.
- * @param c should be one of 0-9, '*' or '#'. Other values will be
- * silently ignored.
- */
- void startDtmf(char c);
-
- /**
- * Stop the playing DTMF tone. Ignored if there is no playing DTMF
- * tone or no active call.
- */
- void stopDtmf();
-
- /**
- * send burst DTMF tone, it can send the string as single character or multiple character
- * ignore if there is no active call or not valid digits string.
- * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
- * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
- * this api can send single character and multiple character, also, this api has response
- * back to caller.
- *
- * @param dtmfString is string representing the dialing digit(s) in the active call
- * @param on the DTMF ON length in milliseconds, or 0 for default
- * @param off the DTMF OFF length in milliseconds, or 0 for default
- * @param onComplete is the callback message when the action is processed by BP
- *
- */
- void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete);
-
- /**
- * Sets the radio power on/off state (off is sometimes
- * called "airplane mode"). Current state can be gotten via
- * {@link #getServiceState()}.{@link
- * android.telephony.ServiceState#getState() getState()}.
- * <strong>Note: </strong>This request is asynchronous.
- * getServiceState().getState() will not change immediately after this call.
- * registerForServiceStateChanged() to find out when the
- * request is complete.
- *
- * @param power true means "on", false means "off".
- */
- void setRadioPower(boolean power);
-
- /**
- * Get voice message waiting indicator status. No change notification
- * available on this interface. Use PhoneStateNotifier or similar instead.
- *
- * @return true if there is a voice message waiting
- */
- boolean getMessageWaitingIndicator();
-
- /**
- * Get voice call forwarding indicator status. No change notification
- * available on this interface. Use PhoneStateNotifier or similar instead.
- *
- * @return true if there is a voice call forwarding
- */
- boolean getCallForwardingIndicator();
-
- /**
- * Get the line 1 phone number (MSISDN). For CDMA phones, the MDN is returned
- * and {@link #getMsisdn()} will return the MSISDN on CDMA/LTE phones.<p>
- *
- * @return phone number. May return null if not
- * available or the SIM is not ready
- */
- String getLine1Number();
-
- /**
- * Returns the alpha tag associated with the msisdn number.
- * If there is no alpha tag associated or the record is not yet available,
- * returns a default localized string. <p>
- */
- String getLine1AlphaTag();
-
- /**
- * Sets the MSISDN phone number in the SIM card.
- *
- * @param alphaTag the alpha tag associated with the MSISDN phone number
- * (see getMsisdnAlphaTag)
- * @param number the new MSISDN phone number to be set on the SIM.
- * @param onComplete a callback message when the action is completed.
- */
- void setLine1Number(String alphaTag, String number, Message onComplete);
-
- /**
- * Get the voice mail access phone number. Typically dialed when the
- * user holds the "1" key in the phone app. May return null if not
- * available or the SIM is not ready.<p>
- */
- String getVoiceMailNumber();
-
- /**
- * Returns unread voicemail count. This count is shown when the voicemail
- * notification is expanded.<p>
- */
- int getVoiceMessageCount();
-
- /**
- * Returns the alpha tag associated with the voice mail number.
- * If there is no alpha tag associated or the record is not yet available,
- * returns a default localized string. <p>
- *
- * Please use this value instead of some other localized string when
- * showing a name for this number in the UI. For example, call log
- * entries should show this alpha tag. <p>
- *
- * Usage of this alpha tag in the UI is a common carrier requirement.
- */
- String getVoiceMailAlphaTag();
-
- /**
- * setVoiceMailNumber
- * sets the voicemail number in the SIM card.
- *
- * @param alphaTag the alpha tag associated with the voice mail number
- * (see getVoiceMailAlphaTag)
- * @param voiceMailNumber the new voicemail number to be set on the SIM.
- * @param onComplete a callback message when the action is completed.
- */
- void setVoiceMailNumber(String alphaTag,
- String voiceMailNumber,
- Message onComplete);
-
- /**
- * getCallForwardingOptions
- * gets a call forwarding option. The return value of
- * ((AsyncResult)onComplete.obj) is an array of CallForwardInfo.
- *
- * @param commandInterfaceCFReason is one of the valid call forwarding
- * CF_REASONS, as defined in
- * <code>com.android.internal.telephony.CommandsInterface.</code>
- * @param onComplete a callback message when the action is completed.
- * @see com.android.internal.telephony.CallForwardInfo for details.
- */
- void getCallForwardingOption(int commandInterfaceCFReason,
- Message onComplete);
-
- /**
- * setCallForwardingOptions
- * sets a call forwarding option.
- *
- * @param commandInterfaceCFReason is one of the valid call forwarding
- * CF_REASONS, as defined in
- * <code>com.android.internal.telephony.CommandsInterface.</code>
- * @param commandInterfaceCFAction is one of the valid call forwarding
- * CF_ACTIONS, as defined in
- * <code>com.android.internal.telephony.CommandsInterface.</code>
- * @param dialingNumber is the target phone number to forward calls to
- * @param timerSeconds is used by CFNRy to indicate the timeout before
- * forwarding is attempted.
- * @param onComplete a callback message when the action is completed.
- */
- void setCallForwardingOption(int commandInterfaceCFReason,
- int commandInterfaceCFAction,
- String dialingNumber,
- int timerSeconds,
- Message onComplete);
-
- /**
- * getOutgoingCallerIdDisplay
- * gets outgoing caller id display. The return value of
- * ((AsyncResult)onComplete.obj) is an array of int, with a length of 2.
- *
- * @param onComplete a callback message when the action is completed.
- * @see com.android.internal.telephony.CommandsInterface#getCLIR for details.
- */
- void getOutgoingCallerIdDisplay(Message onComplete);
-
- /**
- * setOutgoingCallerIdDisplay
- * sets a call forwarding option.
- *
- * @param commandInterfaceCLIRMode is one of the valid call CLIR
- * modes, as defined in
- * <code>com.android.internal.telephony.CommandsInterface./code>
- * @param onComplete a callback message when the action is completed.
- */
- void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
- Message onComplete);
-
- /**
- * getCallWaiting
- * gets call waiting activation state. The return value of
- * ((AsyncResult)onComplete.obj) is an array of int, with a length of 1.
- *
- * @param onComplete a callback message when the action is completed.
- * @see com.android.internal.telephony.CommandsInterface#queryCallWaiting for details.
- */
- void getCallWaiting(Message onComplete);
-
- /**
- * setCallWaiting
- * sets a call forwarding option.
- *
- * @param enable is a boolean representing the state that you are
- * requesting, true for enabled, false for disabled.
- * @param onComplete a callback message when the action is completed.
- */
- void setCallWaiting(boolean enable, Message onComplete);
-
- /**
- * Scan available networks. This method is asynchronous; .
- * On completion, <code>response.obj</code> is set to an AsyncResult with
- * one of the following members:.<p>
- *<ul>
- * <li><code>response.obj.result</code> will be a <code>List</code> of
- * <code>OperatorInfo</code> objects, or</li>
- * <li><code>response.obj.exception</code> will be set with an exception
- * on failure.</li>
- * </ul>
- */
- void getAvailableNetworks(Message response);
-
- /**
- * Switches network selection mode to "automatic", re-scanning and
- * re-selecting a network if appropriate.
- *
- * @param response The message to dispatch when the network selection
- * is complete.
- *
- * @see #selectNetworkManually(OperatorInfo, android.os.Message )
- */
- void setNetworkSelectionModeAutomatic(Message response);
-
- /**
- * Manually selects a network. <code>response</code> is
- * dispatched when this is complete. <code>response.obj</code> will be
- * an AsyncResult, and <code>response.obj.exception</code> will be non-null
- * on failure.
- *
- * @see #setNetworkSelectionModeAutomatic(Message)
- */
- void selectNetworkManually(OperatorInfo network,
- Message response);
-
- /**
- * Requests to set the preferred network type for searching and registering
- * (CS/PS domain, RAT, and operation mode)
- * @param networkType one of NT_*_TYPE
- * @param response is callback message
- */
- void setPreferredNetworkType(int networkType, Message response);
-
- /**
- * Query the preferred network type setting
- *
- * @param response is callback message to report one of NT_*_TYPE
- */
- void getPreferredNetworkType(Message response);
-
- /**
- * Gets the default SMSC address.
- *
- * @param result Callback message contains the SMSC address.
- */
- void getSmscAddress(Message result);
-
- /**
- * Sets the default SMSC address.
- *
- * @param address new SMSC address
- * @param result Callback message is empty on completion
- */
- void setSmscAddress(String address, Message result);
-
- /**
- * Query neighboring cell IDs. <code>response</code> is dispatched when
- * this is complete. <code>response.obj</code> will be an AsyncResult,
- * and <code>response.obj.exception</code> will be non-null on failure.
- * On success, <code>AsyncResult.result</code> will be a <code>String[]</code>
- * containing the neighboring cell IDs. Index 0 will contain the count
- * of available cell IDs. Cell IDs are in hexadecimal format.
- *
- * @param response callback message that is dispatched when the query
- * completes.
- */
- void getNeighboringCids(Message response);
-
- /**
- * Sets an event to be fired when the telephony system processes
- * a post-dial character on an outgoing call.<p>
- *
- * Messages of type <code>what</code> will be sent to <code>h</code>.
- * The <code>obj</code> field of these Message's will be instances of
- * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
- * a Connection object.<p>
- *
- * Message.arg1 will be the post dial character being processed,
- * or 0 ('\0') if end of string.<p>
- *
- * If Connection.getPostDialState() == WAIT,
- * the application must call
- * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
- * Connection.proceedAfterWaitChar()} or
- * {@link com.android.internal.telephony.Connection#cancelPostDial()
- * Connection.cancelPostDial()}
- * for the telephony system to continue playing the post-dial
- * DTMF sequence.<p>
- *
- * If Connection.getPostDialState() == WILD,
- * the application must call
- * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
- * Connection.proceedAfterWildChar()}
- * or
- * {@link com.android.internal.telephony.Connection#cancelPostDial()
- * Connection.cancelPostDial()}
- * for the telephony system to continue playing the
- * post-dial DTMF sequence.<p>
- *
- * Only one post dial character handler may be set. <p>
- * Calling this method with "h" equal to null unsets this handler.<p>
- */
- void setOnPostDialCharacter(Handler h, int what, Object obj);
-
-
- /**
- * Mutes or unmutes the microphone for the active call. The microphone
- * is automatically unmuted if a call is answered, dialed, or resumed
- * from a holding state.
- *
- * @param muted true to mute the microphone,
- * false to activate the microphone.
- */
-
- void setMute(boolean muted);
-
- /**
- * Gets current mute status. Use
- * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
- * java.lang.Object) registerForPreciseCallStateChanged()}
- * as a change notifcation, although presently phone state changed is not
- * fired when setMute() is called.
- *
- * @return true is muting, false is unmuting
- */
- boolean getMute();
-
- /**
- * Enables or disables echo suppression.
- */
- void setEchoSuppressionEnabled(boolean enabled);
-
- /**
- * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation.
- *
- * @param data The data for the request.
- * @param response <strong>On success</strong>,
- * (byte[])(((AsyncResult)response.obj).result)
- * <strong>On failure</strong>,
- * (((AsyncResult)response.obj).result) == null and
- * (((AsyncResult)response.obj).exception) being an instance of
- * com.android.internal.telephony.gsm.CommandException
- *
- * @see #invokeOemRilRequestRaw(byte[], android.os.Message)
- */
- void invokeOemRilRequestRaw(byte[] data, Message response);
-
- /**
- * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation.
- *
- * @param strings The strings to make available as the request data.
- * @param response <strong>On success</strong>, "response" bytes is
- * made available as:
- * (String[])(((AsyncResult)response.obj).result).
- * <strong>On failure</strong>,
- * (((AsyncResult)response.obj).result) == null and
- * (((AsyncResult)response.obj).exception) being an instance of
- * com.android.internal.telephony.gsm.CommandException
- *
- * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message)
- */
- void invokeOemRilRequestStrings(String[] strings, Message response);
-
- /**
- * Get the current active Data Call list
- *
- * @param response <strong>On success</strong>, "response" bytes is
- * made available as:
- * (String[])(((AsyncResult)response.obj).result).
- * <strong>On failure</strong>,
- * (((AsyncResult)response.obj).result) == null and
- * (((AsyncResult)response.obj).exception) being an instance of
- * com.android.internal.telephony.gsm.CommandException
- */
- void getDataCallList(Message response);
-
- /**
- * Update the ServiceState CellLocation for current network registration.
- */
- void updateServiceLocation();
-
- /**
- * Enable location update notifications.
- */
- void enableLocationUpdates();
-
- /**
- * Disable location update notifications.
- */
- void disableLocationUpdates();
-
- /**
- * For unit tests; don't send notifications to "Phone"
- * mailbox registrants if true.
- */
- void setUnitTestMode(boolean f);
-
- /**
- * @return true If unit test mode is enabled
- */
- boolean getUnitTestMode();
-
- /**
- * Assign a specified band for RF configuration.
- *
- * @param bandMode one of BM_*_BAND
- * @param response is callback message
- */
- void setBandMode(int bandMode, Message response);
-
- /**
- * 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
- */
- void queryAvailableBandMode(Message response);
-
- /**
- * @return true if enable data connection on roaming
- */
- boolean getDataRoamingEnabled();
-
- /**
- * @param enable set true if enable data connection on roaming
- */
- void setDataRoamingEnabled(boolean enable);
-
- /**
- * 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);
-
- /**
- * If this is a simulated phone interface, returns a SimulatedRadioControl.
- * @ return A SimulatedRadioControl if this is a simulated interface;
- * otherwise, null.
- */
- SimulatedRadioControl getSimulatedRadioControl();
-
- /**
- * Enables the specified APN type. Only works for "special" APN types,
- * i.e., not the default APN.
- * @param type The desired APN type. Cannot be {@link #APN_TYPE_DEFAULT}.
- * @return <code>APN_ALREADY_ACTIVE</code> if the current APN
- * services the requested type.<br/>
- * <code>APN_TYPE_NOT_AVAILABLE</code> if the carrier does not
- * support the requested APN.<br/>
- * <code>APN_REQUEST_STARTED</code> if the request has been initiated.<br/>
- * <code>APN_REQUEST_FAILED</code> if the request was invalid.<br/>
- * A <code>ACTION_ANY_DATA_CONNECTION_STATE_CHANGED</code> broadcast will
- * indicate connection state progress.
- */
- int enableApnType(String type);
-
- /**
- * Disables the specified APN type, and switches back to the default APN,
- * if necessary. Switching to the default APN will not happen if default
- * data traffic has been explicitly disabled via a call to {@link #disableDataConnectivity}.
- * <p/>Only works for "special" APN types,
- * i.e., not the default APN.
- * @param type The desired APN type. Cannot be {@link #APN_TYPE_DEFAULT}.
- * @return <code>APN_ALREADY_ACTIVE</code> if the default APN
- * is already active.<br/>
- * <code>APN_REQUEST_STARTED</code> if the request to switch to the default
- * APN has been initiated.<br/>
- * <code>APN_REQUEST_FAILED</code> if the request was invalid.<br/>
- * A <code>ACTION_ANY_DATA_CONNECTION_STATE_CHANGED</code> broadcast will
- * indicate connection state progress.
- */
- int disableApnType(String type);
-
- /**
- * Report on whether data connectivity is allowed.
- */
- boolean isDataConnectivityPossible();
-
- /**
- * Report on whether data connectivity is allowed for an APN.
- */
- boolean isDataConnectivityPossible(String apnType);
-
- /**
- * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
- */
- String getDeviceId();
-
- /**
- * Retrieves the software version number for the device, e.g., IMEI/SV
- * for GSM phones.
- */
- String getDeviceSvn();
-
- /**
- * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones.
- */
- String getSubscriberId();
-
- /**
- * Retrieves the serial number of the ICC, if applicable.
- */
- String getIccSerialNumber();
-
- /* CDMA support methods */
-
- /**
- * Retrieves the MIN for CDMA phones.
- */
- String getCdmaMin();
-
- /**
- * Check if subscription data has been assigned to mMin
- *
- * return true if MIN info is ready; false otherwise.
- */
- boolean isMinInfoReady();
-
- /**
- * Retrieves PRL Version for CDMA phones
- */
- String getCdmaPrlVersion();
-
- /**
- * Retrieves the ESN for CDMA phones.
- */
- String getEsn();
-
- /**
- * Retrieves MEID for CDMA phones.
- */
- String getMeid();
-
- /**
- * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to
- * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns
- * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones.
- */
- String getMsisdn();
-
- /**
- * Retrieves IMEI for phones. Returns null if IMEI is not set.
- */
- String getImei();
-
- /**
- * Retrieves the PhoneSubInfo of the Phone
- */
- public PhoneSubInfo getPhoneSubInfo();
-
- /**
- * Retrieves the IccSmsInterfaceManager of the Phone
- */
- public IccSmsInterfaceManager getIccSmsInterfaceManager();
-
- /**
- * Retrieves the IccPhoneBookInterfaceManager of the Phone
- */
- public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager();
-
- /**
- * setTTYMode
- * sets a TTY mode option.
- * @param ttyMode is a one of the following:
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
- * @param onComplete a callback message when the action is completed
- */
- void setTTYMode(int ttyMode, Message onComplete);
-
- /**
- * queryTTYMode
- * query the status of the TTY mode
- *
- * @param onComplete a callback message when the action is completed.
- */
- void queryTTYMode(Message onComplete);
-
- /**
- * Activate or deactivate cell broadcast SMS.
- *
- * @param activate
- * 0 = activate, 1 = deactivate
- * @param response
- * Callback message is empty on completion
- */
- void activateCellBroadcastSms(int activate, Message response);
-
- /**
- * Query the current configuration of cdma cell broadcast SMS.
- *
- * @param response
- * Callback message is empty on completion
- */
- void getCellBroadcastSmsConfig(Message response);
-
- /**
- * Configure cell broadcast SMS.
- *
- * TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
- *
- * @param response
- * Callback message is empty on completion
- */
- public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response);
-
- public void notifyDataActivity();
-
- /**
- * Returns the CDMA ERI icon index to display
- */
- public int getCdmaEriIconIndex();
-
- /**
- * Returns the CDMA ERI icon mode,
- * 0 - ON
- * 1 - FLASHING
- */
- public int getCdmaEriIconMode();
-
- /**
- * Returns the CDMA ERI text,
- */
- public String getCdmaEriText();
-
- /**
- * request to exit emergency call back mode
- * the caller should use setOnECMModeExitResponse
- * to receive the emergency callback mode exit response
- */
- void exitEmergencyCallbackMode();
-
- /**
- * this decides if the dial number is OTA(Over the air provision) number or not
- * @param dialStr is string representing the dialing digit(s)
- * @return true means the dialStr is OTA number, and false means the dialStr is not OTA number
- */
- boolean isOtaSpNumber(String dialStr);
-
- /**
- * Returns true if OTA Service Provisioning needs to be performed.
- */
- boolean needsOtaServiceProvisioning();
-
- /**
- * Register for notifications when CDMA call waiting comes
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForCallWaiting(Handler h, int what, Object obj);
-
- /**
- * Unegister for notifications when CDMA Call waiting comes
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForCallWaiting(Handler h);
-
-
- /**
- * Register for signal information notifications from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a SuppServiceNotification instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
-
- void registerForSignalInfo(Handler h, int what, Object obj) ;
- /**
- * Unregisters for signal information notifications.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForSignalInfo(Handler h);
-
- /**
- * Register for display information notifications from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a SuppServiceNotification instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForDisplayInfo(Handler h, int what, Object obj);
-
- /**
- * Unregisters for display information notifications.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForDisplayInfo(Handler h) ;
-
- /**
- * Register for CDMA number information record notification from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec
- * instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForNumberInfo(Handler h, int what, Object obj);
-
- /**
- * Unregisters for number information record notifications.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForNumberInfo(Handler h);
-
- /**
- * Register for CDMA redirected number information record notification
- * from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec
- * instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
-
- /**
- * Unregisters for redirected number information record notification.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForRedirectedNumberInfo(Handler h);
-
- /**
- * Register for CDMA line control information record notification
- * from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec
- * instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForLineControlInfo(Handler h, int what, Object obj);
-
- /**
- * Unregisters for line control information notifications.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForLineControlInfo(Handler h);
-
- /**
- * Register for CDMA T53 CLIR information record notifications
- * from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec
- * instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerFoT53ClirlInfo(Handler h, int what, Object obj);
-
- /**
- * Unregisters for T53 CLIR information record notification
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForT53ClirInfo(Handler h);
-
- /**
- * Register for CDMA T53 audio control information record notifications
- * from the network.
- * Message.obj will contain an AsyncResult.
- * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec
- * instance.
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- void registerForT53AudioControlInfo(Handler h, int what, Object obj);
-
- /**
- * Unregisters for T53 audio control information record notifications.
- * Extraneous calls are tolerated silently
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unregisterForT53AudioControlInfo(Handler h);
-
- /**
- * registers for exit emergency call back mode request response
- *
- * @param h Handler that receives the notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
-
- void setOnEcbModeExitResponse(Handler h, int what, Object obj);
-
- /**
- * Unregisters for exit emergency call back mode request response
- *
- * @param h Handler to be removed from the registrant list.
- */
- void unsetOnEcbModeExitResponse(Handler h);
-
- /**
- * Return if the current radio is LTE on CDMA. This
- * is a tri-state return value as for a period of time
- * the mode may be unknown.
- *
- * @return {@link #LTE_ON_CDMA_UNKNOWN}, {@link #LTE_ON_CDMA_FALSE} or {@link #LTE_ON_CDMA_TRUE}
- */
- public int getLteOnCdmaMode();
-
- /**
- * TODO: Adding a function for each property is not good.
- * A fucntion of type getPhoneProp(propType) where propType is an
- * enum of GSM+CDMA+LTE props would be a better approach.
- *
- * Get "Restriction of menu options for manual PLMN selection" bit
- * status from EF_CSP data, this belongs to "Value Added Services Group".
- * @return true if this bit is set or EF_CSP data is unavailable,
- * false otherwise
- */
- boolean isCspPlmnEnabled();
-
- /**
- * Return an interface to retrieve the ISIM records for IMS, if available.
- * @return the interface to retrieve the ISIM records, or null if not supported
- */
- IsimRecords getIsimRecords();
-
- /**
- * Request the ISIM application on the UICC to perform the AKA
- * challenge/response algorithm for IMS authentication. The nonce string
- * and challenge response are Base64 encoded Strings.
- *
- * @param nonce the nonce string to pass with the ISIM authentication request
- * @param response a callback message with the String response in the obj field
- */
- void requestIsimAuthentication(String nonce, Message response);
-
- /**
- * 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
- */
- void setVoiceMessageWaiting(int line, int countWaiting);
-
- /**
- * Gets the USIM service table from the UICC, if present and available.
- * @return an interface to the UsimServiceTable record, or null if not available
- */
- UsimServiceTable getUsimServiceTable();
-
- /**
- * Unregister from all events it registered for and dispose objects
- * created by this object.
- */
- void dispose();
-
- /**
- * Remove references to external object stored in this object.
- */
- void removeReferences();
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
deleted file mode 100644
index 2ac9365..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.SharedPreferences;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.wifi.WifiManager;
-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.provider.Settings;
-import android.telephony.ServiceState;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.R;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.gsm.SIMRecords;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Locale;
-import java.util.concurrent.atomic.AtomicReference;
-
-
-/**
- * (<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.
- *
- * {@hide}
- *
- */
-
-public abstract class PhoneBase extends Handler implements Phone {
- private static final String LOG_TAG = "PHONE";
- private static final boolean LOCAL_DEBUG = true;
-
- // Key used to read and write the saved network selection numeric value
- public static final String NETWORK_SELECTION_KEY = "network_selection_key";
- // Key used to read and write the saved network selection operator name
- public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_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;
- protected static final int EVENT_CALL_RING_CONTINUE = 15;
-
- // Used to intercept the carrier selection calls so that
- // we can save the values.
- protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 16;
- protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17;
- protected static final int EVENT_SET_CLIR_COMPLETE = 18;
- protected static final int EVENT_REGISTERED_TO_NETWORK = 19;
- protected static final int EVENT_SET_VM_NUMBER_DONE = 20;
- // Events for CDMA support
- protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 21;
- protected static final int EVENT_RUIM_RECORDS_LOADED = 22;
- protected static final int EVENT_NV_READY = 23;
- protected static final int EVENT_SET_ENHANCED_VP = 24;
- protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25;
- protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
- protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
- // other
- protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28;
- protected static final int EVENT_NEW_ICC_SMS = 29;
- protected static final int EVENT_ICC_RECORD_EVENTS = 30;
-
- // 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;
- boolean mDnsCheckDisabled;
- public DataConnectionTracker mDataConnectionTracker;
- boolean mDoesRilSendMultipleCallRing;
- int mCallRingContinueToken;
- int mCallRingDelay;
- public boolean mIsTheCurrentActivePhone = true;
- boolean mIsVoiceCapable = true;
- public IccRecords mIccRecords;
- protected AtomicReference<IccCard> mIccCard = new AtomicReference<IccCard>();
- public SmsStorageMonitor mSmsStorageMonitor;
- public SmsUsageMonitor mSmsUsageMonitor;
- public SMSDispatcher mSMS;
-
- /**
- * 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 mPreciseCallStateRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mNewRingingConnectionRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mIncomingRingRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mDisconnectRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mServiceStateRegistrants
- = new RegistrantList();
-
- protected final RegistrantList mMmiCompleteRegistrants
- = new RegistrantList();
-
- 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 final Context mContext;
-
- /**
- * 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;
-
- protected SimulatedRadioControl mSimulatedRadioControl;
-
- boolean mUnitTestMode;
-
- /**
- * Constructs a PhoneBase in normal (non-unit test) mode.
- *
- * @param context Context object from hosting application
- * @param notifier An instance of DefaultPhoneNotifier,
- * unless unit testing.
- */
- protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci) {
- this(notifier, context, ci, false);
- }
-
- /**
- * Constructs a PhoneBase in normal (non-unit test) mode.
- *
- * @param context Context object from hosting application
- * @param notifier An instance of DefaultPhoneNotifier,
- * unless unit testing.
- * @param unitTestMode when true, prevents notifications
- * of state change events
- */
- protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci,
- boolean unitTestMode) {
- this.mNotifier = notifier;
- this.mContext = context;
- mLooper = Looper.myLooper();
- mCM = ci;
-
- setPropertiesByCarrier();
-
- setUnitTestMode(unitTestMode);
-
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
- mCM.setOnCallRing(this, EVENT_CALL_RING, null);
-
- /* "Voice capable" means that this device supports circuit-switched
- * (i.e. voice) phone calls over the telephony network, and is allowed
- * to display the in-call UI while a cellular voice call is active.
- * This will be false on "data only" devices which can't make voice
- * calls and don't support any in-call UI.
- */
- mIsVoiceCapable = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_voice_capable);
-
- /**
- * Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
- * to be generated locally. Ideally all ring tones should be loops
- * and this wouldn't be necessary. But to minimize changes to upper
- * layers it is requested that it be generated by lower layers.
- *
- * By default old phones won't have the property set but do generate
- * the RIL_UNSOL_CALL_RING so the default if there is no property is
- * true.
- */
- mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
- TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
- Log.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
-
- mCallRingDelay = SystemProperties.getInt(
- TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
- Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
-
- // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
- mSmsStorageMonitor = new SmsStorageMonitor(this);
- mSmsUsageMonitor = new SmsUsageMonitor(context);
- }
-
- public void dispose() {
- synchronized(PhoneProxy.lockForRadioTechnologyChange) {
- mCM.unSetOnCallRing(this);
- // Must cleanup all connectionS and needs to use sendMessage!
- mDataConnectionTracker.cleanUpAllConnections(null);
- mIsTheCurrentActivePhone = false;
- // Dispose the SMS usage and storage monitors
- mSmsStorageMonitor.dispose();
- mSmsUsageMonitor.dispose();
- }
- }
-
- public void removeReferences() {
- mSmsStorageMonitor = null;
- mSmsUsageMonitor = null;
- mSMS = null;
- mIccRecords = null;
- mIccCard.set(null);
- mDataConnectionTracker = null;
- }
-
- /**
- * When overridden the derived class needs to call
- * super.handleMessage(msg) so this method has a
- * a chance to process the message.
- *
- * @param msg
- */
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch(msg.what) {
- case EVENT_CALL_RING:
- Log.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- Phone.State state = getState();
- if ((!mDoesRilSendMultipleCallRing)
- && ((state == Phone.State.RINGING) || (state == Phone.State.IDLE))) {
- mCallRingContinueToken += 1;
- sendIncomingCallRingNotification(mCallRingContinueToken);
- } else {
- notifyIncomingRing();
- }
- }
- break;
-
- case EVENT_CALL_RING_CONTINUE:
- Log.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
- if (getState() == Phone.State.RINGING) {
- sendIncomingCallRingNotification(msg.arg1);
- }
- break;
-
- default:
- throw new RuntimeException("unexpected event not handled");
- }
- }
-
- // Inherited documentation suffices.
- public Context getContext() {
- 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.apply();
- }
-
- /**
- * Returns true if the DNS check is currently disabled.
- */
- public boolean isDnsCheckDisabled() {
- return mDnsCheckDisabled;
- }
-
- // Inherited documentation suffices.
- public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
- checkCorrectThread(h);
-
- mPreciseCallStateRegistrants.addUnique(h, what, obj);
- }
-
- // Inherited documentation suffices.
- public void unregisterForPreciseCallStateChanged(Handler h) {
- mPreciseCallStateRegistrants.remove(h);
- }
-
- /**
- * Subclasses of Phone probably want to replace this with a
- * version scoped to their packages
- */
- protected void notifyPreciseCallStateChangedP() {
- AsyncResult ar = new AsyncResult(null, this, null);
- mPreciseCallStateRegistrants.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) {
- checkCorrectThread(h);
-
- mNewRingingConnectionRegistrants.addUnique(h, what, obj);
- }
-
- // Inherited documentation suffices.
- public void unregisterForNewRingingConnection(Handler h) {
- 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);
- }
-
- // Inherited documentation suffices.
- 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);
-
- mDisconnectRegistrants.addUnique(h, what, obj);
- }
-
- // Inherited documentation suffices.
- public void unregisterForDisconnect(Handler h) {
- mDisconnectRegistrants.remove(h);
- }
-
- // 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);
-
- mMmiRegistrants.addUnique(h, what, obj);
- }
-
- // Inherited documentation suffices.
- public void unregisterForMmiInitiate(Handler h) {
- mMmiRegistrants.remove(h);
- }
-
- // Inherited documentation suffices.
- public void registerForMmiComplete(Handler h, int what, Object obj) {
- checkCorrectThread(h);
-
- mMmiCompleteRegistrants.addUnique(h, what, obj);
- }
-
- // Inherited documentation suffices.
- public void unregisterForMmiComplete(Handler h) {
- checkCorrectThread(h);
-
- mMmiCompleteRegistrants.remove(h);
- }
-
- /**
- * Method to retrieve the saved operator id from the Shared Preferences
- */
- 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;
- }
-
- // Inherited documentation suffices.
- public boolean getUnitTestMode() {
- return mUnitTestMode;
- }
-
- /**
- * To be invoked when a voice call Connection disconnects.
- *
- * Subclasses of Phone probably want to replace this with a
- * version scoped to their packages
- */
- protected void notifyDisconnectP(Connection cn) {
- AsyncResult ar = new AsyncResult(null, cn, null);
- mDisconnectRegistrants.notifyRegistrants(ar);
- }
-
- // Inherited documentation suffices.
- public void registerForServiceStateChanged(
- Handler h, int what, Object obj) {
- checkCorrectThread(h);
-
- mServiceStateRegistrants.add(h, what, obj);
- }
-
- // Inherited documentation suffices.
- public void unregisterForServiceStateChanged(Handler h) {
- mServiceStateRegistrants.remove(h);
- }
-
- // Inherited documentation suffices.
- public void registerForRingbackTone(Handler h, int what, Object obj) {
- mCM.registerForRingbackTone(h,what,obj);
- }
-
- // Inherited documentation suffices.
- public void unregisterForRingbackTone(Handler h) {
- mCM.unregisterForRingbackTone(h);
- }
-
- // Inherited documentation suffices.
- public void registerForResendIncallMute(Handler h, int what, Object obj) {
- mCM.registerForResendIncallMute(h,what,obj);
- }
-
- // Inherited documentation suffices.
- public void unregisterForResendIncallMute(Handler h) {
- mCM.unregisterForResendIncallMute(h);
- }
-
- public void setEchoSuppressionEnabled(boolean enabled) {
- // no need for regular phone
- }
-
- /**
- * Subclasses of Phone probably want to replace this with a
- * version scoped to their packages
- */
- protected void notifyServiceStateChangedP(ServiceState ss) {
- AsyncResult ar = new AsyncResult(null, ss, null);
- mServiceStateRegistrants.notifyRegistrants(ar);
-
- mNotifier.notifyServiceState(this);
- }
-
- // Inherited documentation suffices.
- public SimulatedRadioControl getSimulatedRadioControl() {
- return mSimulatedRadioControl;
- }
-
- /**
- * Verifies the current thread is the same as the thread originally
- * used in the initialization of this instance. Throws RuntimeException
- * if not.
- *
- * @exception RuntimeException if the current thread is not
- * the thread that originally obtained this PhoneBase instance.
- */
- private void checkCorrectThread(Handler h) {
- if (h.getLooper() != mLooper) {
- throw new RuntimeException(
- "com.android.internal.telephony.Phone must be used from within one thread");
- }
- }
-
- /**
- * Set the properties by matching the carrier string in
- * a string-array resource
- */
- private void setPropertiesByCarrier() {
- String carrier = SystemProperties.get("ro.carrier");
-
- if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
- return;
- }
-
- CharSequence[] carrierLocales = mContext.
- getResources().getTextArray(R.array.carrier_properties);
-
- for (int i = 0; i < carrierLocales.length; i+=3) {
- String c = carrierLocales[i].toString();
- if (carrier.equals(c)) {
- String l = carrierLocales[i+1].toString();
-
- String language = l.substring(0, 2);
- String country = "";
- if (l.length() >=5) {
- country = l.substring(3, 5);
- }
- MccTable.setSystemLocale(mContext, language, country);
-
- if (!country.isEmpty()) {
- try {
- Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.WIFI_COUNTRY_CODE);
- } catch (Settings.SettingNotFoundException e) {
- // note this is not persisting
- WifiManager wM = (WifiManager)
- mContext.getSystemService(Context.WIFI_SERVICE);
- wM.setCountryCode(country, false);
- }
- }
- return;
- }
- }
- }
-
- /**
- * Get state
- */
- public abstract Phone.State getState();
-
- /**
- * Retrieves the IccFileHandler of the Phone instance
- */
- public IccFileHandler getIccFileHandler(){
- IccCard iccCard = mIccCard.get();
- if (iccCard == null) return null;
- return iccCard.getIccFileHandler();
- }
-
- /*
- * Retrieves the Handler of the Phone instance
- */
- public Handler getHandler() {
- return this;
- }
-
- /**
- * Retrieves the ServiceStateTracker of the phone instance.
- */
- public ServiceStateTracker getServiceStateTracker() {
- return null;
- }
-
- /**
- * Get call tracker
- */
- public CallTracker getCallTracker() {
- return null;
- }
-
- @Override
- public IccCard getIccCard() {
- return mIccCard.get();
- }
-
- @Override
- public String getIccSerialNumber() {
- return mIccRecords.iccid;
- }
-
- @Override
- public boolean getIccRecordsLoaded() {
- return mIccRecords.getRecordsLoaded();
- }
-
- @Override
- public boolean getMessageWaitingIndicator() {
- return mIccRecords.getVoiceMessageWaiting();
- }
-
- @Override
- public boolean getCallForwardingIndicator() {
- return mIccRecords.getVoiceCallForwardingFlag();
- }
-
- /**
- * 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.setCdmaSubscriptionSource(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);
- }
-
- public void getPreferredNetworkType(Message response) {
- mCM.getPreferredNetworkType(response);
- }
-
- public void getSmscAddress(Message result) {
- mCM.getSmscAddress(result);
- }
-
- public void setSmscAddress(String address, Message result) {
- mCM.setSmscAddress(address, result);
- }
-
- public void setTTYMode(int ttyMode, Message onComplete) {
- mCM.setTTYMode(ttyMode, onComplete);
- }
-
- public void queryTTYMode(Message onComplete) {
- mCM.queryTTYMode(onComplete);
- }
-
- public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy");
- }
-
- public void getEnhancedVoicePrivacy(Message onComplete) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy");
- }
-
- 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 notifyMessageWaitingIndicator() {
- // Do not notify voice mail waiting if device doesn't support voice
- if (!mIsVoiceCapable)
- return;
-
- // This function is added to send the notification to DefaultPhoneNotifier.
- mNotifier.notifyMessageWaitingChanged(this);
- }
-
- public void notifyDataConnection(String reason, String apnType,
- Phone.DataState state) {
- mNotifier.notifyDataConnection(this, reason, apnType, state);
- }
-
- public void notifyDataConnection(String reason, String apnType) {
- mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
- }
-
- public void notifyDataConnection(String reason) {
- String types[] = getActiveApnTypes();
- for (String apnType : types) {
- mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
- }
- }
-
- public void notifyOtaspChanged(int otaspMode) {
- mNotifier.notifyOtaspChanged(this, otaspMode);
- }
-
- /**
- * @return true if a mobile originating emergency call is active
- */
- public boolean isInEmergencyCall() {
- return false;
- }
-
- /**
- * @return true if we are in the emergency call back mode. This is a period where
- * the phone should be using as little power as possible and be ready to receive an
- * incoming call from the emergency operator.
- */
- public boolean isInEcm() {
- return false;
- }
-
- public abstract String getPhoneName();
-
- public abstract int getPhoneType();
-
- /** @hide */
- public int getVoiceMessageCount(){
- return 0;
- }
-
- /**
- * Returns the CDMA ERI icon index to display
- */
- public int getCdmaEriIconIndex() {
- logUnexpectedCdmaMethodCall("getCdmaEriIconIndex");
- return -1;
- }
-
- /**
- * Returns the CDMA ERI icon mode,
- * 0 - ON
- * 1 - FLASHING
- */
- public int getCdmaEriIconMode() {
- logUnexpectedCdmaMethodCall("getCdmaEriIconMode");
- return -1;
- }
-
- /**
- * Returns the CDMA ERI text,
- */
- public String getCdmaEriText() {
- logUnexpectedCdmaMethodCall("getCdmaEriText");
- return "GSM nw, no ERI";
- }
-
- public String getCdmaMin() {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("getCdmaMin");
- return null;
- }
-
- public boolean isMinInfoReady() {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("isMinInfoReady");
- return false;
- }
-
- public String getCdmaPrlVersion(){
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("getCdmaPrlVersion");
- return null;
- }
-
- public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("sendBurstDtmf");
- }
-
- public void exitEmergencyCallbackMode() {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode");
- }
-
- public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange");
- }
-
- public void unregisterForCdmaOtaStatusChange(Handler h) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange");
- }
-
- public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady");
- }
-
- public void unregisterForSubscriptionInfoReady(Handler h) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady");
- }
-
- /**
- * Returns true if OTA Service Provisioning needs to be performed.
- * If not overridden return false.
- */
- public boolean needsOtaServiceProvisioning() {
- return false;
- }
-
- /**
- * Return true if number is an OTASP number.
- * If not overridden return false.
- */
- public boolean isOtaSpNumber(String dialStr) {
- return false;
- }
-
- public void registerForCallWaiting(Handler h, int what, Object obj){
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("registerForCallWaiting");
- }
-
- public void unregisterForCallWaiting(Handler h){
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("unregisterForCallWaiting");
- }
-
- public void registerForEcmTimerReset(Handler h, int what, Object obj) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("registerForEcmTimerReset");
- }
-
- public void unregisterForEcmTimerReset(Handler h) {
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset");
- }
-
- public void registerForSignalInfo(Handler h, int what, Object obj) {
- mCM.registerForSignalInfo(h, what, obj);
- }
-
- public void unregisterForSignalInfo(Handler h) {
- mCM.unregisterForSignalInfo(h);
- }
-
- public void registerForDisplayInfo(Handler h, int what, Object obj) {
- mCM.registerForDisplayInfo(h, what, obj);
- }
-
- public void unregisterForDisplayInfo(Handler h) {
- mCM.unregisterForDisplayInfo(h);
- }
-
- public void registerForNumberInfo(Handler h, int what, Object obj) {
- mCM.registerForNumberInfo(h, what, obj);
- }
-
- public void unregisterForNumberInfo(Handler h) {
- mCM.unregisterForNumberInfo(h);
- }
-
- public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
- mCM.registerForRedirectedNumberInfo(h, what, obj);
- }
-
- public void unregisterForRedirectedNumberInfo(Handler h) {
- mCM.unregisterForRedirectedNumberInfo(h);
- }
-
- public void registerForLineControlInfo(Handler h, int what, Object obj) {
- mCM.registerForLineControlInfo( h, what, obj);
- }
-
- public void unregisterForLineControlInfo(Handler h) {
- mCM.unregisterForLineControlInfo(h);
- }
-
- public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
- mCM.registerFoT53ClirlInfo(h, what, obj);
- }
-
- public void unregisterForT53ClirInfo(Handler h) {
- mCM.unregisterForT53ClirInfo(h);
- }
-
- public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
- mCM.registerForT53AudioControlInfo( h, what, obj);
- }
-
- public void unregisterForT53AudioControlInfo(Handler h) {
- mCM.unregisterForT53AudioControlInfo(h);
- }
-
- public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse");
- }
-
- public void unsetOnEcbModeExitResponse(Handler h){
- // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
- logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse");
- }
-
- public String[] getActiveApnTypes() {
- return mDataConnectionTracker.getActiveApnTypes();
- }
-
- public String getActiveApnHost(String apnType) {
- return mDataConnectionTracker.getActiveApnString(apnType);
- }
-
- public LinkProperties getLinkProperties(String apnType) {
- return mDataConnectionTracker.getLinkProperties(apnType);
- }
-
- public LinkCapabilities getLinkCapabilities(String apnType) {
- return mDataConnectionTracker.getLinkCapabilities(apnType);
- }
-
- public int enableApnType(String type) {
- return mDataConnectionTracker.enableApnType(type);
- }
-
- public int disableApnType(String type) {
- return mDataConnectionTracker.disableApnType(type);
- }
-
- public boolean isDataConnectivityPossible() {
- return isDataConnectivityPossible(Phone.APN_TYPE_DEFAULT);
- }
-
- public boolean isDataConnectivityPossible(String apnType) {
- return ((mDataConnectionTracker != null) &&
- (mDataConnectionTracker.isDataPossible(apnType)));
- }
-
- /**
- * Notify registrants of a new ringing Connection.
- * Subclasses of Phone probably want to replace this with a
- * version scoped to their packages
- */
- protected void notifyNewRingingConnectionP(Connection cn) {
- if (!mIsVoiceCapable)
- return;
- AsyncResult ar = new AsyncResult(null, cn, null);
- mNewRingingConnectionRegistrants.notifyRegistrants(ar);
- }
-
- /**
- * Notify registrants of a RING event.
- */
- private void notifyIncomingRing() {
- if (!mIsVoiceCapable)
- return;
- AsyncResult ar = new AsyncResult(null, this, null);
- mIncomingRingRegistrants.notifyRegistrants(ar);
- }
-
- /**
- * Send the incoming call Ring notification if conditions are right.
- */
- private void sendIncomingCallRingNotification(int token) {
- if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
- (token == mCallRingContinueToken)) {
- Log.d(LOG_TAG, "Sending notifyIncomingRing");
- notifyIncomingRing();
- sendMessageDelayed(
- obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
- } else {
- Log.d(LOG_TAG, "Ignoring ring notification request,"
- + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
- + " token=" + token
- + " mCallRingContinueToken=" + mCallRingContinueToken
- + " mIsVoiceCapable=" + mIsVoiceCapable);
- }
- }
-
- public boolean isCspPlmnEnabled() {
- // This function should be overridden by the class GSMPhone.
- // Not implemented in CDMAPhone.
- logUnexpectedGsmMethodCall("isCspPlmnEnabled");
- return false;
- }
-
- public IsimRecords getIsimRecords() {
- Log.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
- return null;
- }
-
- public void requestIsimAuthentication(String nonce, Message result) {
- Log.e(LOG_TAG, "requestIsimAuthentication() is only supported on LTE devices");
- }
-
- public String getMsisdn() {
- logUnexpectedGsmMethodCall("getMsisdn");
- return null;
- }
-
- /**
- * Common error logger method for unexpected calls to CDMA-only methods.
- */
- private static void logUnexpectedCdmaMethodCall(String name)
- {
- Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
- "called, CDMAPhone inactive.");
- }
-
- public DataState getDataConnectionState() {
- return getDataConnectionState(APN_TYPE_DEFAULT);
- }
-
- /**
- * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
- */
- private static void logUnexpectedGsmMethodCall(String name) {
- Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
- "called, GSMPhone inactive.");
- }
-
- // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
- public void notifyCallForwardingIndicator() {
- // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
- Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
- }
-
- public void notifyDataConnectionFailed(String reason, String apnType) {
- mNotifier.notifyDataConnectionFailed(this, reason, apnType);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getLteOnCdmaMode() {
- return mCM.getLteOnCdmaMode();
- }
-
- /**
- * 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
- */
- @Override
- public void setVoiceMessageWaiting(int line, int countWaiting) {
- mIccRecords.setVoiceMessageWaiting(line, countWaiting);
- }
-
- /**
- * Gets the USIM service table from the UICC, if present and available.
- * @return an interface to the UsimServiceTable record, or null if not available
- */
- @Override
- public UsimServiceTable getUsimServiceTable() {
- return mIccRecords.getUsimServiceTable();
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("PhoneBase:");
- pw.println(" mCM=" + mCM);
- pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
- pw.println(" mDataConnectionTracker=" + mDataConnectionTracker);
- pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
- pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
- pw.println(" mCallRingDelay=" + mCallRingDelay);
- pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
- pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
- pw.println(" mIccRecords=" + mIccRecords);
- pw.println(" mIccCard=" + mIccCard.get());
- pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
- pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
- pw.println(" mSMS=" + mSMS);
- pw.flush();
- pw.println(" mLooper=" + mLooper);
- pw.println(" mContext=" + mContext);
- pw.println(" mNotifier=" + mNotifier);
- pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
- pw.println(" mUnitTestMode=" + mUnitTestMode);
- pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
- pw.println(" getUnitTestMode()=" + getUnitTestMode());
- pw.println(" getState()=" + getState());
- pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
- pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
- pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
- pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
- pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
- pw.flush();
- pw.println(" isInEcm()=" + isInEcm());
- pw.println(" getPhoneName()=" + getPhoneName());
- pw.println(" getPhoneType()=" + getPhoneType());
- pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
- pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
- pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible());
- pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
new file mode 100644
index 0000000..16ea625
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.telephony;
+
+/**
+ * @hide
+ */
+public class PhoneConstants {
+
+ /**
+ * The phone state. One of the following:<p>
+ * <ul>
+ * <li>IDLE = no phone activity</li>
+ * <li>RINGING = a phone call is ringing or call waiting.
+ * In the latter case, another call is active as well</li>
+ * <li>OFFHOOK = The phone is off hook. At least one call
+ * exists that is dialing, active or holding and no calls are
+ * ringing or waiting.</li>
+ * </ul>
+ */
+ public enum State {
+ IDLE, RINGING, OFFHOOK;
+ };
+
+ /**
+ * The state of a data connection.
+ * <ul>
+ * <li>CONNECTED = IP traffic should be available</li>
+ * <li>CONNECTING = Currently setting up data connection</li>
+ * <li>DISCONNECTED = IP not available</li>
+ * <li>SUSPENDED = connection is created but IP traffic is
+ * temperately not available. i.e. voice call is in place
+ * in 2G network</li>
+ * </ul>
+ */
+ public enum DataState {
+ CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED;
+ };
+
+ public static final String STATE_KEY = "state";
+
+ // Radio Type
+ public static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE;
+ public static final int PHONE_TYPE_GSM = RILConstants.GSM_PHONE;
+ public static final int PHONE_TYPE_CDMA = RILConstants.CDMA_PHONE;
+ public static final int PHONE_TYPE_SIP = RILConstants.SIP_PHONE;
+
+ // Modes for LTE_ON_CDMA
+ public static final int LTE_ON_CDMA_UNKNOWN = RILConstants.LTE_ON_CDMA_UNKNOWN;
+ public static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE;
+ public static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE;
+
+ // Number presentation type for caller id display (From internal/Conneciton.java)
+ public static int PRESENTATION_ALLOWED = 1; // normal
+ public static int PRESENTATION_RESTRICTED = 2; // block by user
+ public static int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network
+ public static int PRESENTATION_PAYPHONE = 4; // show pay phone info
+
+
+ public static final String PHONE_NAME_KEY = "phoneName";
+ public static final String FAILURE_REASON_KEY = "reason";
+ public static final String STATE_CHANGE_REASON_KEY = "reason";
+ public static final String DATA_APN_TYPE_KEY = "apnType";
+ public static final String DATA_APN_KEY = "apn";
+ public static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
+ public static final String DATA_LINK_CAPABILITIES_KEY = "linkCapabilities";
+
+ public static final String DATA_IFACE_NAME_KEY = "iface";
+ public static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
+ public static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming";
+ public static final String PHONE_IN_ECM_STATE = "phoneinECMState";
+
+ public static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
+
+ /**
+ * Return codes for <code>enableApnType()</code>
+ */
+ public static final int APN_ALREADY_ACTIVE = 0;
+ public static final int APN_REQUEST_STARTED = 1;
+ public static final int APN_TYPE_NOT_AVAILABLE = 2;
+ public static final int APN_REQUEST_FAILED = 3;
+ public static final int APN_ALREADY_INACTIVE = 4;
+
+ /**
+ * APN types for data connections. These are usage categories for an APN
+ * entry. One APN entry may support multiple APN types, eg, a single APN
+ * may service regular internet traffic ("default") as well as MMS-specific
+ * connections.<br/>
+ * APN_TYPE_ALL is a special type to indicate that this APN entry can
+ * service all data connections.
+ */
+ public static final String APN_TYPE_ALL = "*";
+ /** APN type for default data traffic */
+ public static final String APN_TYPE_DEFAULT = "default";
+ /** APN type for MMS traffic */
+ public static final String APN_TYPE_MMS = "mms";
+ /** APN type for SUPL assisted GPS */
+ public static final String APN_TYPE_SUPL = "supl";
+ /** APN type for DUN traffic */
+ public static final String APN_TYPE_DUN = "dun";
+ /** APN type for HiPri traffic */
+ public static final String APN_TYPE_HIPRI = "hipri";
+ /** APN type for FOTA */
+ public static final String APN_TYPE_FOTA = "fota";
+ /** APN type for IMS */
+ public static final String APN_TYPE_IMS = "ims";
+ /** APN type for CBS */
+ public static final String APN_TYPE_CBS = "cbs";
+
+}
diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java
deleted file mode 100644
index f495d7e..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneFactory.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * 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.net.LocalServerSocket;
-import android.os.Looper;
-import android.provider.Settings;
-import android.util.Log;
-import android.os.SystemProperties;
-
-import com.android.internal.telephony.cdma.CDMAPhone;
-import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.sip.SipPhone;
-import com.android.internal.telephony.sip.SipPhoneFactory;
-
-/**
- * {@hide}
- */
-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
-
- 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 final int preferredCdmaSubscription =
- CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION;
-
- //***** Class Methods
-
- public static void makeDefaultPhones(Context context) {
- makeDefaultPhone(context);
- }
-
- /**
- * FIXME replace this with some other way of making these
- * instances
- */
- public static void makeDefaultPhone(Context context) {
- synchronized(Phone.class) {
- if (!sMadeDefaults) {
- sLooper = Looper.myLooper();
- sContext = context;
-
- if (sLooper == null) {
- throw new RuntimeException(
- "PhoneFactory.makeDefaultPhone must be called from Looper thread");
- }
-
- int retryCount = 0;
- for(;;) {
- boolean hasException = false;
- retryCount ++;
-
- try {
- // use UNIX domain socket to
- // prevent subsequent initialization
- new LocalServerSocket("com.android.internal.telephony");
- } catch (java.io.IOException ex) {
- hasException = true;
- }
-
- if ( !hasException ) {
- break;
- } else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
- throw new RuntimeException("PhoneFactory probably already running");
- } else {
- try {
- Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
- } catch (InterruptedException er) {
- }
- }
- }
-
- sPhoneNotifier = new DefaultPhoneNotifier();
-
- // Get preferred network mode
- int preferredNetworkMode = RILConstants.PREFERRED_NETWORK_MODE;
- if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
- preferredNetworkMode = Phone.NT_MODE_GLOBAL;
- }
- int networkMode = Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
- Log.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkMode));
-
- // Get cdmaSubscription
- // TODO: Change when the ril will provides a way to know at runtime
- // the configuration, bug 4202572. And the ril issues the
- // RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, bug 4295439.
- int cdmaSubscription;
- int lteOnCdma = BaseCommands.getLteOnCdmaModeStatic();
- switch (lteOnCdma) {
- case Phone.LTE_ON_CDMA_FALSE:
- cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV;
- Log.i(LOG_TAG, "lteOnCdma is 0 use SUBSCRIPTION_FROM_NV");
- break;
- case Phone.LTE_ON_CDMA_TRUE:
- cdmaSubscription = CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM;
- Log.i(LOG_TAG, "lteOnCdma is 1 use SUBSCRIPTION_FROM_RUIM");
- break;
- case Phone.LTE_ON_CDMA_UNKNOWN:
- default:
- //Get cdmaSubscription mode from Settings.System
- cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
- preferredCdmaSubscription);
- Log.i(LOG_TAG, "lteOnCdma not set, using PREFERRED_CDMA_SUBSCRIPTION");
- break;
- }
- Log.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);
-
- //reads the system properties and makes commandsinterface
- sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);
-
- int phoneType = getPhoneType(networkMode);
- if (phoneType == Phone.PHONE_TYPE_GSM) {
- Log.i(LOG_TAG, "Creating GSMPhone");
- sProxyPhone = new PhoneProxy(new GSMPhone(context,
- sCommandsInterface, sPhoneNotifier));
- } else if (phoneType == Phone.PHONE_TYPE_CDMA) {
- switch (BaseCommands.getLteOnCdmaModeStatic()) {
- case Phone.LTE_ON_CDMA_TRUE:
- Log.i(LOG_TAG, "Creating CDMALTEPhone");
- sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
- sCommandsInterface, sPhoneNotifier));
- break;
- case Phone.LTE_ON_CDMA_FALSE:
- default:
- Log.i(LOG_TAG, "Creating CDMAPhone");
- sProxyPhone = new PhoneProxy(new CDMAPhone(context,
- sCommandsInterface, sPhoneNotifier));
- break;
- }
- }
-
- sMadeDefaults = true;
- }
- }
- }
-
- /*
- * This function returns the type of the phone, depending
- * on the network mode.
- *
- * @param network mode
- * @return Phone Type
- */
- public static int getPhoneType(int networkMode) {
- switch(networkMode) {
- case RILConstants.NETWORK_MODE_CDMA:
- case RILConstants.NETWORK_MODE_CDMA_NO_EVDO:
- case RILConstants.NETWORK_MODE_EVDO_NO_CDMA:
- return Phone.PHONE_TYPE_CDMA;
-
- case RILConstants.NETWORK_MODE_WCDMA_PREF:
- case RILConstants.NETWORK_MODE_GSM_ONLY:
- case RILConstants.NETWORK_MODE_WCDMA_ONLY:
- case RILConstants.NETWORK_MODE_GSM_UMTS:
- return Phone.PHONE_TYPE_GSM;
-
- // Use CDMA Phone for the global mode including CDMA
- case RILConstants.NETWORK_MODE_GLOBAL:
- case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
- case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
- return Phone.PHONE_TYPE_CDMA;
-
- case RILConstants.NETWORK_MODE_LTE_ONLY:
- if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
- return Phone.PHONE_TYPE_CDMA;
- } else {
- return Phone.PHONE_TYPE_GSM;
- }
- default:
- return Phone.PHONE_TYPE_GSM;
- }
- }
-
- 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;
- }
-
- public static Phone getCdmaPhone() {
- Phone phone;
- synchronized(PhoneProxy.lockForRadioTechnologyChange) {
- switch (BaseCommands.getLteOnCdmaModeStatic()) {
- case Phone.LTE_ON_CDMA_TRUE: {
- phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
- break;
- }
- case Phone.LTE_ON_CDMA_FALSE:
- case Phone.LTE_ON_CDMA_UNKNOWN:
- default: {
- phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
- break;
- }
- }
- }
- return phone;
- }
-
- public static Phone getGsmPhone() {
- synchronized(PhoneProxy.lockForRadioTechnologyChange) {
- Phone phone = new GSMPhone(sContext, sCommandsInterface, sPhoneNotifier);
- return phone;
- }
- }
-
- /**
- * Makes a {@link SipPhone} object.
- * @param sipUri the local SIP URI the phone runs on
- * @return the {@code SipPhone} object or null if the SIP URI is not valid
- */
- public static SipPhone makeSipPhone(String sipUri) {
- return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneNotifier.java b/telephony/java/com/android/internal/telephony/PhoneNotifier.java
deleted file mode 100644
index 1076870..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.telephony.CellInfo;
-
-/**
- * {@hide}
- */
-public interface PhoneNotifier {
-
- public void notifyPhoneState(Phone sender);
-
- public void notifyServiceState(Phone sender);
-
- public void notifyCellLocation(Phone sender);
-
- public void notifySignalStrength(Phone sender);
-
- public void notifyMessageWaitingChanged(Phone sender);
-
- public void notifyCallForwardingChanged(Phone sender);
-
- /** TODO - reason should never be null */
- public void notifyDataConnection(Phone sender, String reason, String apnType,
- Phone.DataState state);
-
- public void notifyDataConnectionFailed(Phone sender, String reason, String apnType);
-
- public void notifyDataActivity(Phone sender);
-
- public void notifyOtaspChanged(Phone sender, int otaspMode);
-
- // TODO - trigger notifyCellInfo from ServiceStateTracker
- public void notifyCellInfo(Phone sender, CellInfo cellInfo);
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
deleted file mode 100644
index 1a8b3ca..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-
-import android.app.ActivityManagerNative;
-import android.content.Context;
-import android.content.Intent;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.telephony.CellLocation;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.util.Log;
-
-import com.android.internal.telephony.cdma.CDMAPhone;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.UsimServiceTable;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.CallManager;
-
-import java.util.List;
-
-public class PhoneProxy extends Handler implements Phone {
- public final static Object lockForRadioTechnologyChange = new Object();
-
- private Phone mActivePhone;
- private CommandsInterface mCommandsInterface;
- private IccSmsInterfaceManagerProxy mIccSmsInterfaceManagerProxy;
- private IccPhoneBookInterfaceManagerProxy mIccPhoneBookInterfaceManagerProxy;
- private PhoneSubInfoProxy mPhoneSubInfoProxy;
-
- private boolean mResetModemOnRadioTechnologyChange = false;
-
- private int mRilVersion;
-
- private static final int EVENT_VOICE_RADIO_TECH_CHANGED = 1;
- private static final int EVENT_RADIO_ON = 2;
- private static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE = 3;
- private static final int EVENT_RIL_CONNECTED = 4;
-
- private static final String LOG_TAG = "PHONE";
-
- //***** Class Methods
- public PhoneProxy(Phone phone) {
- mActivePhone = phone;
- mResetModemOnRadioTechnologyChange = SystemProperties.getBoolean(
- TelephonyProperties.PROPERTY_RESET_ON_RADIO_TECH_CHANGE, false);
- mIccSmsInterfaceManagerProxy = new IccSmsInterfaceManagerProxy(
- phone.getIccSmsInterfaceManager());
- mIccPhoneBookInterfaceManagerProxy = new IccPhoneBookInterfaceManagerProxy(
- phone.getIccPhoneBookInterfaceManager());
- mPhoneSubInfoProxy = new PhoneSubInfoProxy(phone.getPhoneSubInfo());
- mCommandsInterface = ((PhoneBase)mActivePhone).mCM;
-
- mCommandsInterface.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
- mCommandsInterface.registerForOn(this, EVENT_RADIO_ON, null);
- mCommandsInterface.registerForVoiceRadioTechChanged(
- this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
- }
-
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar = (AsyncResult) msg.obj;
- switch(msg.what) {
- case EVENT_RADIO_ON:
- /* Proactively query voice radio technologies */
- mCommandsInterface.getVoiceRadioTechnology(
- this.obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE));
- break;
-
- case EVENT_RIL_CONNECTED:
- if (ar.exception == null && ar.result != null) {
- mRilVersion = (Integer) ar.result;
- } else {
- logd("Unexpected exception on EVENT_RIL_CONNECTED");
- mRilVersion = -1;
- }
- break;
-
- case EVENT_VOICE_RADIO_TECH_CHANGED:
- case EVENT_REQUEST_VOICE_RADIO_TECH_DONE:
-
- if (ar.exception == null) {
- if ((ar.result != null) && (((int[]) ar.result).length != 0)) {
- int newVoiceTech = ((int[]) ar.result)[0];
- updatePhoneObject(newVoiceTech);
- } else {
- loge("Voice Radio Technology event " + msg.what + " has no tech!");
- }
- } else {
- loge("Voice Radio Technology event " + msg.what + " exception!" + ar.exception);
- }
- break;
-
- default:
- loge("Error! This handler was not registered for this message type. Message: "
- + msg.what);
- break;
- }
- super.handleMessage(msg);
- }
-
- private static 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);
- }
-
- private void updatePhoneObject(int newVoiceRadioTech) {
-
- if (mActivePhone != null) {
- if(mRilVersion == 6 && getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
- /*
- * On v6 RIL, when LTE_ON_CDMA is TRUE, always create CDMALTEPhone
- * irrespective of the voice radio tech reported.
- */
- if (mActivePhone.getPhoneType() == PHONE_TYPE_CDMA) {
- logd("LTE ON CDMA property is set. Use CDMA Phone" +
- " newVoiceRadioTech = " + newVoiceRadioTech +
- " Active Phone = " + mActivePhone.getPhoneName());
- return;
- } else {
- logd("LTE ON CDMA property is set. Switch to CDMALTEPhone" +
- " newVoiceRadioTech = " + newVoiceRadioTech +
- " Active Phone = " + mActivePhone.getPhoneName());
- newVoiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT;
- }
- } else {
- if ((ServiceState.isCdma(newVoiceRadioTech) &&
- mActivePhone.getPhoneType() == PHONE_TYPE_CDMA) ||
- (ServiceState.isGsm(newVoiceRadioTech) &&
- mActivePhone.getPhoneType() == PHONE_TYPE_GSM)) {
- // Nothing changed. Keep phone as it is.
- logd("Ignoring voice radio technology changed message." +
- " newVoiceRadioTech = " + newVoiceRadioTech +
- " Active Phone = " + mActivePhone.getPhoneName());
- return;
- }
- }
- }
-
- if (newVoiceRadioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
- // We need some voice phone object to be active always, so never
- // delete the phone without anything to replace it with!
- logd("Ignoring voice radio technology changed message. newVoiceRadioTech = Unknown."
- + " Active Phone = " + mActivePhone.getPhoneName());
- return;
- }
-
- boolean oldPowerState = false; // old power state to off
- if (mResetModemOnRadioTechnologyChange) {
- if (mCommandsInterface.getRadioState().isOn()) {
- oldPowerState = true;
- logd("Setting Radio Power to Off");
- mCommandsInterface.setRadioPower(false, null);
- }
- }
-
- deleteAndCreatePhone(newVoiceRadioTech);
-
- if (mResetModemOnRadioTechnologyChange && oldPowerState) { // restore power state
- logd("Resetting Radio");
- mCommandsInterface.setRadioPower(oldPowerState, 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.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName());
- ActivityManagerNative.broadcastStickyIntent(intent, null);
-
- }
-
- private void deleteAndCreatePhone(int newVoiceRadioTech) {
-
- String outgoingPhoneName = "Unknown";
- Phone oldPhone = mActivePhone;
-
- if (oldPhone != null) {
- outgoingPhoneName = ((PhoneBase) oldPhone).getPhoneName();
- }
-
- logd("Switching Voice Phone : " + outgoingPhoneName + " >>> "
- + (ServiceState.isGsm(newVoiceRadioTech) ? "GSM" : "CDMA"));
-
- if (oldPhone != null) {
- CallManager.getInstance().unregisterPhone(oldPhone);
- logd("Disposing old phone..");
- oldPhone.dispose();
- }
-
- // 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();
-
- if (ServiceState.isCdma(newVoiceRadioTech)) {
- mActivePhone = PhoneFactory.getCdmaPhone();
- } else if (ServiceState.isGsm(newVoiceRadioTech)) {
- mActivePhone = PhoneFactory.getGsmPhone();
- }
-
- if (oldPhone != null) {
- oldPhone.removeReferences();
- }
-
- if(mActivePhone != null) {
- CallManager.getInstance().registerPhone(mActivePhone);
- }
-
- oldPhone = null;
- }
-
- public ServiceState getServiceState() {
- return mActivePhone.getServiceState();
- }
-
- public CellLocation getCellLocation() {
- return mActivePhone.getCellLocation();
- }
-
- public DataState getDataConnectionState() {
- return mActivePhone.getDataConnectionState(Phone.APN_TYPE_DEFAULT);
- }
-
- public DataState getDataConnectionState(String apnType) {
- return mActivePhone.getDataConnectionState(apnType);
- }
-
- 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 int getPhoneType() {
- return mActivePhone.getPhoneType();
- }
-
- public String[] getActiveApnTypes() {
- return mActivePhone.getActiveApnTypes();
- }
-
- public String getActiveApnHost(String apnType) {
- return mActivePhone.getActiveApnHost(apnType);
- }
-
- public LinkProperties getLinkProperties(String apnType) {
- return mActivePhone.getLinkProperties(apnType);
- }
-
- public LinkCapabilities getLinkCapabilities(String apnType) {
- return mActivePhone.getLinkCapabilities(apnType);
- }
-
- public SignalStrength getSignalStrength() {
- return mActivePhone.getSignalStrength();
- }
-
- public void registerForUnknownConnection(Handler h, int what, Object obj) {
- mActivePhone.registerForUnknownConnection(h, what, obj);
- }
-
- public void unregisterForUnknownConnection(Handler h) {
- mActivePhone.unregisterForUnknownConnection(h);
- }
-
- public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
- mActivePhone.registerForPreciseCallStateChanged(h, what, obj);
- }
-
- public void unregisterForPreciseCallStateChanged(Handler h) {
- mActivePhone.unregisterForPreciseCallStateChanged(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 void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
- mActivePhone.registerForCdmaOtaStatusChange(h,what,obj);
- }
-
- public void unregisterForCdmaOtaStatusChange(Handler h) {
- mActivePhone.unregisterForCdmaOtaStatusChange(h);
- }
-
- public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
- mActivePhone.registerForSubscriptionInfoReady(h, what, obj);
- }
-
- public void unregisterForSubscriptionInfoReady(Handler h) {
- mActivePhone.unregisterForSubscriptionInfoReady(h);
- }
-
- public void registerForEcmTimerReset(Handler h, int what, Object obj) {
- mActivePhone.registerForEcmTimerReset(h,what,obj);
- }
-
- public void unregisterForEcmTimerReset(Handler h) {
- mActivePhone.unregisterForEcmTimerReset(h);
- }
-
- public void registerForRingbackTone(Handler h, int what, Object obj) {
- mActivePhone.registerForRingbackTone(h,what,obj);
- }
-
- public void unregisterForRingbackTone(Handler h) {
- mActivePhone.unregisterForRingbackTone(h);
- }
-
- public void registerForResendIncallMute(Handler h, int what, Object obj) {
- mActivePhone.registerForResendIncallMute(h,what,obj);
- }
-
- public void unregisterForResendIncallMute(Handler h) {
- mActivePhone.unregisterForResendIncallMute(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 Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {
- return mActivePhone.dial(dialString, uusInfo);
- }
-
- 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 getCdmaMin() {
- return mActivePhone.getCdmaMin();
- }
-
- public boolean isMinInfoReady() {
- return mActivePhone.isMinInfoReady();
- }
-
- public String getCdmaPrlVersion() {
- return mActivePhone.getCdmaPrlVersion();
- }
-
- 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();
- }
-
- /** @hide */
- public int getVoiceMessageCount(){
- return mActivePhone.getVoiceMessageCount();
- }
-
- 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(OperatorInfo 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 setEchoSuppressionEnabled(boolean enabled) {
- mActivePhone.setEchoSuppressionEnabled(enabled);
- }
-
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- mActivePhone.invokeOemRilRequestRaw(data, response);
- }
-
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- mActivePhone.invokeOemRilRequestStrings(strings, response);
- }
-
- public void getDataCallList(Message response) {
- mActivePhone.getDataCallList(response);
- }
-
- public void updateServiceLocation() {
- mActivePhone.updateServiceLocation();
- }
-
- 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 int enableApnType(String type) {
- return mActivePhone.enableApnType(type);
- }
-
- public int disableApnType(String type) {
- return mActivePhone.disableApnType(type);
- }
-
- public boolean isDataConnectivityPossible() {
- return mActivePhone.isDataConnectivityPossible(Phone.APN_TYPE_DEFAULT);
- }
-
- public boolean isDataConnectivityPossible(String apnType) {
- return mActivePhone.isDataConnectivityPossible(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 String getMsisdn() {
- return mActivePhone.getMsisdn();
- }
-
- public String getImei() {
- return mActivePhone.getImei();
- }
-
- public PhoneSubInfo getPhoneSubInfo(){
- return mActivePhone.getPhoneSubInfo();
- }
-
- public IccSmsInterfaceManager getIccSmsInterfaceManager(){
- return mActivePhone.getIccSmsInterfaceManager();
- }
-
- public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
- return mActivePhone.getIccPhoneBookInterfaceManager();
- }
-
- public void setTTYMode(int ttyMode, Message onComplete) {
- mActivePhone.setTTYMode(ttyMode, onComplete);
- }
-
- public void queryTTYMode(Message onComplete) {
- mActivePhone.queryTTYMode(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();
- }
-
- public void getSmscAddress(Message result) {
- mActivePhone.getSmscAddress(result);
- }
-
- public void setSmscAddress(String address, Message result) {
- mActivePhone.setSmscAddress(address, result);
- }
-
- public int getCdmaEriIconIndex() {
- return mActivePhone.getCdmaEriIconIndex();
- }
-
- public String getCdmaEriText() {
- return mActivePhone.getCdmaEriText();
- }
-
- public int getCdmaEriIconMode() {
- return mActivePhone.getCdmaEriIconMode();
- }
-
- public Phone getActivePhone() {
- return mActivePhone;
- }
-
- public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete){
- mActivePhone.sendBurstDtmf(dtmfString, on, off, onComplete);
- }
-
- public void exitEmergencyCallbackMode(){
- mActivePhone.exitEmergencyCallbackMode();
- }
-
- public boolean needsOtaServiceProvisioning(){
- return mActivePhone.needsOtaServiceProvisioning();
- }
-
- public boolean isOtaSpNumber(String dialStr){
- return mActivePhone.isOtaSpNumber(dialStr);
- }
-
- public void registerForCallWaiting(Handler h, int what, Object obj){
- mActivePhone.registerForCallWaiting(h,what,obj);
- }
-
- public void unregisterForCallWaiting(Handler h){
- mActivePhone.unregisterForCallWaiting(h);
- }
-
- public void registerForSignalInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForSignalInfo(h,what,obj);
- }
-
- public void unregisterForSignalInfo(Handler h) {
- mActivePhone.unregisterForSignalInfo(h);
- }
-
- public void registerForDisplayInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForDisplayInfo(h,what,obj);
- }
-
- public void unregisterForDisplayInfo(Handler h) {
- mActivePhone.unregisterForDisplayInfo(h);
- }
-
- public void registerForNumberInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForNumberInfo(h, what, obj);
- }
-
- public void unregisterForNumberInfo(Handler h) {
- mActivePhone.unregisterForNumberInfo(h);
- }
-
- public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForRedirectedNumberInfo(h, what, obj);
- }
-
- public void unregisterForRedirectedNumberInfo(Handler h) {
- mActivePhone.unregisterForRedirectedNumberInfo(h);
- }
-
- public void registerForLineControlInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForLineControlInfo( h, what, obj);
- }
-
- public void unregisterForLineControlInfo(Handler h) {
- mActivePhone.unregisterForLineControlInfo(h);
- }
-
- public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
- mActivePhone.registerFoT53ClirlInfo(h, what, obj);
- }
-
- public void unregisterForT53ClirInfo(Handler h) {
- mActivePhone.unregisterForT53ClirInfo(h);
- }
-
- public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
- mActivePhone.registerForT53AudioControlInfo( h, what, obj);
- }
-
- public void unregisterForT53AudioControlInfo(Handler h) {
- mActivePhone.unregisterForT53AudioControlInfo(h);
- }
-
- public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
- mActivePhone.setOnEcbModeExitResponse(h,what,obj);
- }
-
- public void unsetOnEcbModeExitResponse(Handler h){
- mActivePhone.unsetOnEcbModeExitResponse(h);
- }
-
- public boolean isCspPlmnEnabled() {
- return mActivePhone.isCspPlmnEnabled();
- }
-
- public IsimRecords getIsimRecords() {
- return mActivePhone.getIsimRecords();
- }
-
- public void requestIsimAuthentication(String nonce, Message response) {
- mActivePhone.requestIsimAuthentication(nonce, response);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getLteOnCdmaMode() {
- return mActivePhone.getLteOnCdmaMode();
- }
-
- @Override
- public void setVoiceMessageWaiting(int line, int countWaiting) {
- mActivePhone.setVoiceMessageWaiting(line, countWaiting);
- }
-
- @Override
- public UsimServiceTable getUsimServiceTable() {
- return mActivePhone.getUsimServiceTable();
- }
-
- public void dispose() {
- mCommandsInterface.unregisterForOn(this);
- mCommandsInterface.unregisterForVoiceRadioTechChanged(this);
- mCommandsInterface.unregisterForRilConnected(this);
- }
-
- public void removeReferences() {
- mActivePhone = null;
- mCommandsInterface = null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
deleted file mode 100644
index 898e624..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-/**
- *
- * DO NOT USE THIS CLASS:
- *
- * Use android.telephony.TelephonyManager and PhoneStateListener instead.
- *
- *
- */
-@Deprecated
-public final class PhoneStateIntentReceiver extends BroadcastReceiver {
- private static final String LOG_TAG = "PHONE";
- private static final boolean DBG = false;
-
- private static final int NOTIF_PHONE = 1 << 0;
- private static final int NOTIF_SERVICE = 1 << 1;
- private static final int NOTIF_SIGNAL = 1 << 2;
-
- private static final int NOTIF_MAX = 1 << 5;
-
- Phone.State mPhoneState = Phone.State.IDLE;
- ServiceState mServiceState = new ServiceState();
- SignalStrength mSignalStrength = new SignalStrength();
-
- private Context mContext;
- private Handler mTarget;
- private IntentFilter mFilter;
- private int mWants;
- private int mPhoneStateEventWhat;
- private int mServiceStateEventWhat;
- private int mLocationEventWhat;
- private int mAsuEventWhat;
-
- public PhoneStateIntentReceiver() {
- super();
- mFilter = new IntentFilter();
- }
-
- public PhoneStateIntentReceiver(Context context, Handler target) {
- this();
- setContext(context);
- setTarget(target);
- }
-
- public void setContext(Context c) {
- mContext = c;
- }
-
- public void setTarget(Handler h) {
- mTarget = h;
- }
-
- public Phone.State getPhoneState() {
- if ((mWants & NOTIF_PHONE) == 0) {
- throw new RuntimeException
- ("client must call notifyPhoneCallState(int)");
- }
- return mPhoneState;
- }
-
- public ServiceState getServiceState() {
- if ((mWants & NOTIF_SERVICE) == 0) {
- throw new RuntimeException
- ("client must call notifyServiceState(int)");
- }
- return mServiceState;
- }
-
- /**
- * Returns current signal strength in as an asu 0..31
- *
- * Throws RuntimeException if client has not called notifySignalStrength()
- */
- public int getSignalStrengthLevelAsu() {
- // TODO: use new SignalStrength instead of asu
- if ((mWants & NOTIF_SIGNAL) == 0) {
- throw new RuntimeException
- ("client must call notifySignalStrength(int)");
- }
- return mSignalStrength.getAsuLevel();
- }
-
- /**
- * Return current signal strength in "dBm", ranging from -113 - -51dBm
- * or -1 if unknown
- *
- * @return signal strength in dBm, -1 if not yet updated
- * Throws RuntimeException if client has not called notifySignalStrength()
- */
- public int getSignalStrengthDbm() {
- if ((mWants & NOTIF_SIGNAL) == 0) {
- throw new RuntimeException
- ("client must call notifySignalStrength(int)");
- }
- return mSignalStrength.getDbm();
- }
-
- public void notifyPhoneCallState(int eventWhat) {
- mWants |= NOTIF_PHONE;
- mPhoneStateEventWhat = eventWhat;
- mFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
- }
-
- public boolean getNotifyPhoneCallState() {
- return ((mWants & NOTIF_PHONE) != 0);
- }
-
- public void notifyServiceState(int eventWhat) {
- mWants |= NOTIF_SERVICE;
- mServiceStateEventWhat = eventWhat;
- mFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
- }
-
- public boolean getNotifyServiceState() {
- return ((mWants & NOTIF_SERVICE) != 0);
- }
-
- public void notifySignalStrength (int eventWhat) {
- mWants |= NOTIF_SIGNAL;
- mAsuEventWhat = eventWhat;
- mFilter.addAction(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
- }
-
- public boolean getNotifySignalStrength() {
- return ((mWants & NOTIF_SIGNAL) != 0);
- }
-
- public void registerIntent() {
- mContext.registerReceiver(this, mFilter);
- }
-
- public void unregisterIntent() {
- mContext.unregisterReceiver(this);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- try {
- if (TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED.equals(action)) {
- mSignalStrength = SignalStrength.newFromBundle(intent.getExtras());
-
- if (mTarget != null && getNotifySignalStrength()) {
- Message message = Message.obtain(mTarget, mAsuEventWhat);
- mTarget.sendMessage(message);
- }
- } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
- if (DBG) Log.d(LOG_TAG, "onReceiveIntent: ACTION_PHONE_STATE_CHANGED, state="
- + intent.getStringExtra(Phone.STATE_KEY));
- String phoneState = intent.getStringExtra(Phone.STATE_KEY);
- mPhoneState = (Phone.State) Enum.valueOf(
- Phone.State.class, phoneState);
-
- if (mTarget != null && getNotifyPhoneCallState()) {
- Message message = Message.obtain(mTarget,
- mPhoneStateEventWhat);
- mTarget.sendMessage(message);
- }
- } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
- mServiceState = ServiceState.newFromBundle(intent.getExtras());
-
- if (mTarget != null && getNotifyServiceState()) {
- Message message = Message.obtain(mTarget,
- mServiceStateEventWhat);
- mTarget.sendMessage(message);
- }
- }
- } catch (Exception ex) {
- Log.e(LOG_TAG, "[PhoneStateIntentRecv] caught " + ex);
- ex.printStackTrace();
- }
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
deleted file mode 100755
index e8449ce..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.telephony;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.ims.IsimRecords;
-
-public class PhoneSubInfo extends IPhoneSubInfo.Stub {
- static final String LOG_TAG = "PHONE";
- private Phone mPhone;
- private Context mContext;
- private static final String READ_PHONE_STATE =
- android.Manifest.permission.READ_PHONE_STATE;
- // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE
- private static final String CALL_PRIVILEGED =
- android.Manifest.permission.CALL_PRIVILEGED;
- private static final String READ_PRIVILEGED_PHONE_STATE =
- android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
-
- public PhoneSubInfo(Phone phone) {
- mPhone = phone;
- mContext = phone.getContext();
- }
-
- public void dispose() {
- }
-
- protected void finalize() {
- try {
- super.finalize();
- } catch (Throwable throwable) {
- Log.e(LOG_TAG, "Error while finalizing:", throwable);
- }
- Log.d(LOG_TAG, "PhoneSubInfo finalized");
- }
-
- /**
- * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
- */
- public String getDeviceId() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- return mPhone.getDeviceId();
- }
-
- /**
- * Retrieves the software version number for the device, e.g., IMEI/SV
- * for GSM phones.
- */
- public String getDeviceSvn() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- return mPhone.getDeviceSvn();
- }
-
- /**
- * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones.
- */
- public String getSubscriberId() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- return mPhone.getSubscriberId();
- }
-
- /**
- * Retrieves the serial number of the ICC, if applicable.
- */
- public String getIccSerialNumber() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- return mPhone.getIccSerialNumber();
- }
-
- /**
- * Retrieves the phone number string for line 1.
- */
- public String getLine1Number() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- return mPhone.getLine1Number();
- }
-
- /**
- * Retrieves the alpha identifier for line 1.
- */
- public String getLine1AlphaTag() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- return (String) mPhone.getLine1AlphaTag();
- }
-
- /**
- * Retrieves the MSISDN string.
- */
- public String getMsisdn() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- return mPhone.getMsisdn();
- }
-
- /**
- * Retrieves the voice mail number.
- */
- public String getVoiceMailNumber() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- String number = PhoneNumberUtils.extractNetworkPortion(mPhone.getVoiceMailNumber());
- Log.d(LOG_TAG, "VM: PhoneSubInfo.getVoiceMailNUmber: "); // + number);
- return number;
- }
-
- /**
- * Retrieves the complete voice mail number.
- *
- * @hide
- */
- public String getCompleteVoiceMailNumber() {
- mContext.enforceCallingOrSelfPermission(CALL_PRIVILEGED,
- "Requires CALL_PRIVILEGED");
- String number = mPhone.getVoiceMailNumber();
- Log.d(LOG_TAG, "VM: PhoneSubInfo.getCompleteVoiceMailNUmber: "); // + number);
- return number;
- }
-
- /**
- * Retrieves the alpha identifier associated with the voice mail number.
- */
- public String getVoiceMailAlphaTag() {
- mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
- return (String) mPhone.getVoiceMailAlphaTag();
- }
-
- /**
- * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
- * @return the IMPI, or null if not present or not loaded
- */
- public String getIsimImpi() {
- mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
- "Requires READ_PRIVILEGED_PHONE_STATE");
- IsimRecords isim = mPhone.getIsimRecords();
- if (isim != null) {
- return isim.getIsimImpi();
- } else {
- return null;
- }
- }
-
- /**
- * Returns the IMS home network domain name that was loaded from the ISIM.
- * @return the IMS domain name, or null if not present or not loaded
- */
- public String getIsimDomain() {
- mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
- "Requires READ_PRIVILEGED_PHONE_STATE");
- IsimRecords isim = mPhone.getIsimRecords();
- if (isim != null) {
- return isim.getIsimDomain();
- } else {
- return null;
- }
- }
-
- /**
- * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
- * @return an array of IMPU strings, with one IMPU per string, or null if
- * not present or not loaded
- */
- public String[] getIsimImpu() {
- mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE,
- "Requires READ_PRIVILEGED_PHONE_STATE");
- IsimRecords isim = mPhone.getIsimRecords();
- if (isim != null) {
- return isim.getIsimImpu();
- } else {
- return null;
- }
- }
-
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump PhoneSubInfo from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
- pw.println("Phone Subscriber Info:");
- pw.println(" Phone Type = " + mPhone.getPhoneName());
- pw.println(" Device ID = " + mPhone.getDeviceId());
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
deleted file mode 100755
index bd130de..0000000
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.ServiceManager;
-
-
-public class PhoneSubInfoProxy extends IPhoneSubInfo.Stub {
- private PhoneSubInfo mPhoneSubInfo;
-
- public PhoneSubInfoProxy(PhoneSubInfo phoneSubInfo) {
- mPhoneSubInfo = phoneSubInfo;
- if(ServiceManager.getService("iphonesubinfo") == null) {
- ServiceManager.addService("iphonesubinfo", this);
- }
- }
-
- public void setmPhoneSubInfo(PhoneSubInfo phoneSubInfo) {
- this.mPhoneSubInfo = phoneSubInfo;
- }
-
- public String getDeviceId() {
- return mPhoneSubInfo.getDeviceId();
- }
-
- public String getDeviceSvn() {
- return mPhoneSubInfo.getDeviceSvn();
- }
-
- /**
- * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones.
- */
- public String getSubscriberId() {
- return mPhoneSubInfo.getSubscriberId();
- }
-
- /**
- * Retrieves the serial number of the ICC, if applicable.
- */
- public String getIccSerialNumber() {
- return mPhoneSubInfo.getIccSerialNumber();
- }
-
- /**
- * Retrieves the phone number string for line 1.
- */
- public String getLine1Number() {
- return mPhoneSubInfo.getLine1Number();
- }
-
- /**
- * Retrieves the alpha identifier for line 1.
- */
- public String getLine1AlphaTag() {
- return mPhoneSubInfo.getLine1AlphaTag();
- }
-
- /**
- * Retrieves the MSISDN Number.
- */
- public String getMsisdn() {
- return mPhoneSubInfo.getMsisdn();
- }
-
- /**
- * Retrieves the voice mail number.
- */
- public String getVoiceMailNumber() {
- return mPhoneSubInfo.getVoiceMailNumber();
- }
-
- /**
- * Retrieves the complete voice mail number.
- */
- public String getCompleteVoiceMailNumber() {
- return mPhoneSubInfo.getCompleteVoiceMailNumber();
- }
-
- /**
- * Retrieves the alpha identifier associated with the voice mail number.
- */
- public String getVoiceMailAlphaTag() {
- return mPhoneSubInfo.getVoiceMailAlphaTag();
- }
-
- /**
- * Returns the IMS private user identity (IMPI) that was loaded from the ISIM.
- * @return the IMPI, or null if not present or not loaded
- */
- public String getIsimImpi() {
- return mPhoneSubInfo.getIsimImpi();
- }
-
- /**
- * Returns the IMS home network domain name that was loaded from the ISIM.
- * @return the IMS domain name, or null if not present or not loaded
- */
- public String getIsimDomain() {
- return mPhoneSubInfo.getIsimDomain();
- }
-
- /**
- * Returns the IMS public user identities (IMPU) that were loaded from the ISIM.
- * @return an array of IMPU strings, with one IMPU per string, or null if
- * not present or not loaded
- */
- public String[] getIsimImpu() {
- return mPhoneSubInfo.getIsimImpu();
- }
-
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mPhoneSubInfo.dump(fd, pw, args);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
deleted file mode 100644
index b14f6c8..0000000
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ /dev/null
@@ -1,3861 +0,0 @@
-/*
- * 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 static com.android.internal.telephony.RILConstants.*;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcel;
-import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.os.PowerManager.WakeLock;
-import android.telephony.NeighboringCellInfo;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsManager;
-import android.telephony.SmsMessage;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
-import com.android.internal.telephony.cdma.CdmaInformationRecords;
-import com.android.internal.telephony.IccRefreshResponse;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * {@hide}
- */
-class RILRequest {
- static final String LOG_TAG = "RILJ";
-
- //***** Class Variables
- static int sNextSerial = 0;
- static Object sSerialMonitor = new Object();
- private static Object sPoolSync = new Object();
- private static RILRequest sPool = null;
- private static int sPoolSize = 0;
- private static final int MAX_POOL_SIZE = 4;
-
- //***** Instance Variables
- int mSerial;
- int mRequest;
- Message mResult;
- Parcel mp;
- RILRequest mNext;
-
- /**
- * Retrieves a new RILRequest instance from the pool.
- *
- * @param request RIL_REQUEST_*
- * @param result sent when operation completes
- * @return a RILRequest instance from the pool.
- */
- static RILRequest obtain(int request, Message result) {
- RILRequest rr = null;
-
- synchronized(sPoolSync) {
- if (sPool != null) {
- rr = sPool;
- sPool = rr.mNext;
- rr.mNext = null;
- sPoolSize--;
- }
- }
-
- if (rr == null) {
- rr = new RILRequest();
- }
-
- synchronized(sSerialMonitor) {
- rr.mSerial = sNextSerial++;
- }
- rr.mRequest = request;
- rr.mResult = result;
- rr.mp = Parcel.obtain();
-
- if (result != null && result.getTarget() == null) {
- throw new NullPointerException("Message target must not be null");
- }
-
- // first elements in any RIL Parcel
- rr.mp.writeInt(request);
- rr.mp.writeInt(rr.mSerial);
-
- return rr;
- }
-
- /**
- * Returns a RILRequest instance to the pool.
- *
- * Note: This should only be called once per use.
- */
- void release() {
- synchronized (sPoolSync) {
- if (sPoolSize < MAX_POOL_SIZE) {
- this.mNext = sPool;
- sPool = this;
- sPoolSize++;
- mResult = null;
- }
- }
- }
-
- private RILRequest() {
- }
-
- static void
- resetSerial() {
- synchronized(sSerialMonitor) {
- sNextSerial = 0;
- }
- }
-
- String
- serialString() {
- //Cheesy way to do %04d
- StringBuilder sb = new StringBuilder(8);
- String sn;
-
- sn = Integer.toString(mSerial);
-
- //sb.append("J[");
- sb.append('[');
- for (int i = 0, s = sn.length() ; i < 4 - s; i++) {
- sb.append('0');
- }
-
- sb.append(sn);
- sb.append(']');
- return sb.toString();
- }
-
- void
- onError(int error, Object ret) {
- CommandException ex;
-
- ex = CommandException.fromRilErrno(error);
-
- if (RIL.RILJ_LOGD) Log.d(LOG_TAG, serialString() + "< "
- + RIL.requestToString(mRequest)
- + " error: " + ex);
-
- if (mResult != null) {
- AsyncResult.forMessage(mResult, ret, ex);
- mResult.sendToTarget();
- }
-
- if (mp != null) {
- mp.recycle();
- mp = null;
- }
- }
-}
-
-
-/**
- * RIL implementation of the CommandsInterface.
- * FIXME public only for testing
- *
- * {@hide}
- */
-public final class RIL extends BaseCommands implements CommandsInterface {
- static final String LOG_TAG = "RILJ";
- static final boolean RILJ_LOGD = true;
- static final boolean RILJ_LOGV = false; // STOP SHIP if true
-
- /**
- * Wake lock timeout should be longer than the longest timeout in
- * the vendor ril.
- */
- private static final int DEFAULT_WAKE_LOCK_TIMEOUT = 60000;
-
- //***** Instance Variables
-
- LocalSocket mSocket;
- HandlerThread mSenderThread;
- RILSender mSender;
- Thread mReceiverThread;
- RILReceiver mReceiver;
- WakeLock mWakeLock;
- int mWakeLockTimeout;
- // The number of requests pending to be sent out, it increases before calling
- // EVENT_SEND and decreases while handling EVENT_SEND. It gets cleared while
- // WAKE_LOCK_TIMEOUT occurs.
- int mRequestMessagesPending;
- // The number of requests sent out but waiting for response. It increases while
- // sending request and decreases while handling response. It should match
- // mRequestList.size() unless there are requests no replied while
- // WAKE_LOCK_TIMEOUT occurs.
- int mRequestMessagesWaiting;
-
- //I'd rather this be LinkedList or something
- ArrayList<RILRequest> mRequestsList = new ArrayList<RILRequest>();
-
- Object mLastNITZTimeInfo;
-
- // When we are testing emergency calls
- AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false);
-
- //***** Events
-
- static final int EVENT_SEND = 1;
- static final int EVENT_WAKE_LOCK_TIMEOUT = 2;
-
- //***** Constants
-
- // match with constant in ril.cpp
- static final int RIL_MAX_COMMAND_BYTES = (8 * 1024);
- static final int RESPONSE_SOLICITED = 0;
- static final int RESPONSE_UNSOLICITED = 1;
-
- static final String SOCKET_NAME_RIL = "rild";
-
- static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000;
-
- // The number of the required config values for broadcast SMS stored in the C struct
- // RIL_CDMA_BroadcastServiceInfo
- private static final int CDMA_BSI_NO_OF_INTS_STRUCT = 3;
-
- private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31;
-
- BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
- sendScreenState(true);
- } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
- sendScreenState(false);
- } else {
- Log.w(LOG_TAG, "RIL received unexpected Intent: " + intent.getAction());
- }
- }
- };
-
- class RILSender extends Handler implements Runnable {
- public RILSender(Looper looper) {
- super(looper);
- }
-
- // Only allocated once
- byte[] dataLength = new byte[4];
-
- //***** Runnable implementation
- public void
- run() {
- //setup if needed
- }
-
-
- //***** Handler implementation
- @Override public void
- handleMessage(Message msg) {
- RILRequest rr = (RILRequest)(msg.obj);
- RILRequest req = null;
-
- switch (msg.what) {
- case EVENT_SEND:
- /**
- * mRequestMessagePending++ already happened for every
- * EVENT_SEND, thus we must make sure
- * mRequestMessagePending-- happens once and only once
- */
- boolean alreadySubtracted = false;
- try {
- LocalSocket s;
-
- s = mSocket;
-
- if (s == null) {
- rr.onError(RADIO_NOT_AVAILABLE, null);
- rr.release();
- if (mRequestMessagesPending > 0)
- mRequestMessagesPending--;
- alreadySubtracted = true;
- return;
- }
-
- synchronized (mRequestsList) {
- mRequestsList.add(rr);
- mRequestMessagesWaiting++;
- }
-
- if (mRequestMessagesPending > 0)
- mRequestMessagesPending--;
- alreadySubtracted = true;
-
- byte[] data;
-
- data = rr.mp.marshall();
- rr.mp.recycle();
- rr.mp = null;
-
- if (data.length > RIL_MAX_COMMAND_BYTES) {
- throw new RuntimeException(
- "Parcel larger than max bytes allowed! "
- + data.length);
- }
-
- // parcel length in big endian
- dataLength[0] = dataLength[1] = 0;
- dataLength[2] = (byte)((data.length >> 8) & 0xff);
- dataLength[3] = (byte)((data.length) & 0xff);
-
- //Log.v(LOG_TAG, "writing packet: " + data.length + " bytes");
-
- s.getOutputStream().write(dataLength);
- s.getOutputStream().write(data);
- } catch (IOException ex) {
- Log.e(LOG_TAG, "IOException", ex);
- req = findAndRemoveRequestFromList(rr.mSerial);
- // make sure this request has not already been handled,
- // eg, if RILReceiver cleared the list.
- if (req != null || !alreadySubtracted) {
- rr.onError(RADIO_NOT_AVAILABLE, null);
- rr.release();
- }
- } catch (RuntimeException exc) {
- Log.e(LOG_TAG, "Uncaught exception ", exc);
- req = findAndRemoveRequestFromList(rr.mSerial);
- // make sure this request has not already been handled,
- // eg, if RILReceiver cleared the list.
- if (req != null || !alreadySubtracted) {
- rr.onError(GENERIC_FAILURE, null);
- rr.release();
- }
- } finally {
- // Note: We are "Done" only if there are no outstanding
- // requests or replies. Thus this code path will only release
- // the wake lock on errors.
- releaseWakeLockIfDone();
- }
-
- if (!alreadySubtracted && mRequestMessagesPending > 0) {
- mRequestMessagesPending--;
- }
-
- break;
-
- case EVENT_WAKE_LOCK_TIMEOUT:
- // Haven't heard back from the last request. Assume we're
- // not getting a response and release the wake lock.
- synchronized (mWakeLock) {
- if (mWakeLock.isHeld()) {
- // The timer of WAKE_LOCK_TIMEOUT is reset with each
- // new send request. So when WAKE_LOCK_TIMEOUT occurs
- // all requests in mRequestList already waited at
- // least DEFAULT_WAKE_LOCK_TIMEOUT but no response.
- // Reset mRequestMessagesWaiting to enable
- // releaseWakeLockIfDone().
- //
- // Note: Keep mRequestList so that delayed response
- // can still be handled when response finally comes.
- if (mRequestMessagesWaiting != 0) {
- Log.d(LOG_TAG, "NOTE: mReqWaiting is NOT 0 but"
- + mRequestMessagesWaiting + " at TIMEOUT, reset!"
- + " There still msg waitng for response");
-
- mRequestMessagesWaiting = 0;
-
- if (RILJ_LOGD) {
- synchronized (mRequestsList) {
- int count = mRequestsList.size();
- Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
- " mRequestList=" + count);
-
- for (int i = 0; i < count; i++) {
- rr = mRequestsList.get(i);
- Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] "
- + requestToString(rr.mRequest));
- }
- }
- }
- }
- // mRequestMessagesPending shows how many
- // requests are waiting to be sent (and before
- // to be added in request list) since star the
- // WAKE_LOCK_TIMEOUT timer. Since WAKE_LOCK_TIMEOUT
- // is the expected time to get response, all requests
- // should already sent out (i.e.
- // mRequestMessagesPending is 0 )while TIMEOUT occurs.
- if (mRequestMessagesPending != 0) {
- Log.e(LOG_TAG, "ERROR: mReqPending is NOT 0 but"
- + mRequestMessagesPending + " at TIMEOUT, reset!");
- mRequestMessagesPending = 0;
-
- }
- mWakeLock.release();
- }
- }
- break;
- }
- }
- }
-
- /**
- * Reads in a single RIL message off the wire. A RIL message consists
- * of a 4-byte little-endian length and a subsequent series of bytes.
- * The final message (length header omitted) is read into
- * <code>buffer</code> and the length of the final message (less header)
- * is returned. A return value of -1 indicates end-of-stream.
- *
- * @param is non-null; Stream to read from
- * @param buffer Buffer to fill in. Must be as large as maximum
- * message size, or an ArrayOutOfBounds exception will be thrown.
- * @return Length of message less header, or -1 on end of stream.
- * @throws IOException
- */
- private static int readRilMessage(InputStream is, byte[] buffer)
- throws IOException {
- int countRead;
- int offset;
- int remaining;
- int messageLength;
-
- // First, read in the length of the message
- offset = 0;
- remaining = 4;
- do {
- countRead = is.read(buffer, offset, remaining);
-
- if (countRead < 0 ) {
- Log.e(LOG_TAG, "Hit EOS reading message length");
- return -1;
- }
-
- offset += countRead;
- remaining -= countRead;
- } while (remaining > 0);
-
- messageLength = ((buffer[0] & 0xff) << 24)
- | ((buffer[1] & 0xff) << 16)
- | ((buffer[2] & 0xff) << 8)
- | (buffer[3] & 0xff);
-
- // Then, re-use the buffer and read in the message itself
- offset = 0;
- remaining = messageLength;
- do {
- countRead = is.read(buffer, offset, remaining);
-
- if (countRead < 0 ) {
- Log.e(LOG_TAG, "Hit EOS reading message. messageLength=" + messageLength
- + " remaining=" + remaining);
- return -1;
- }
-
- offset += countRead;
- remaining -= countRead;
- } while (remaining > 0);
-
- return messageLength;
- }
-
- class RILReceiver implements Runnable {
- byte[] buffer;
-
- RILReceiver() {
- buffer = new byte[RIL_MAX_COMMAND_BYTES];
- }
-
- public void
- run() {
- int retryCount = 0;
-
- try {for (;;) {
- LocalSocket s = null;
- LocalSocketAddress l;
-
- try {
- s = new LocalSocket();
- l = new LocalSocketAddress(SOCKET_NAME_RIL,
- LocalSocketAddress.Namespace.RESERVED);
- s.connect(l);
- } catch (IOException ex){
- try {
- if (s != null) {
- s.close();
- }
- } catch (IOException ex2) {
- //ignore failure to close after failure to connect
- }
-
- // don't print an error message after the the first time
- // or after the 8th time
-
- if (retryCount == 8) {
- Log.e (LOG_TAG,
- "Couldn't find '" + SOCKET_NAME_RIL
- + "' socket after " + retryCount
- + " times, continuing to retry silently");
- } else if (retryCount > 0 && retryCount < 8) {
- Log.i (LOG_TAG,
- "Couldn't find '" + SOCKET_NAME_RIL
- + "' socket; retrying after timeout");
- }
-
- try {
- Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
- } catch (InterruptedException er) {
- }
-
- retryCount++;
- continue;
- }
-
- retryCount = 0;
-
- mSocket = s;
- Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");
-
- int length = 0;
- try {
- InputStream is = mSocket.getInputStream();
-
- for (;;) {
- Parcel p;
-
- length = readRilMessage(is, buffer);
-
- if (length < 0) {
- // End-of-stream reached
- break;
- }
-
- p = Parcel.obtain();
- p.unmarshall(buffer, 0, length);
- p.setDataPosition(0);
-
- //Log.v(LOG_TAG, "Read packet: " + length + " bytes");
-
- processResponse(p);
- p.recycle();
- }
- } catch (java.io.IOException ex) {
- Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",
- ex);
- } catch (Throwable tr) {
- Log.e(LOG_TAG, "Uncaught exception read length=" + length +
- "Exception:" + tr.toString());
- }
-
- Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL
- + "' socket");
-
- setRadioState (RadioState.RADIO_UNAVAILABLE);
-
- try {
- mSocket.close();
- } catch (IOException ex) {
- }
-
- mSocket = null;
- RILRequest.resetSerial();
-
- // Clear request list on close
- clearRequestsList(RADIO_NOT_AVAILABLE, false);
- }} catch (Throwable tr) {
- Log.e(LOG_TAG,"Uncaught exception", tr);
- }
-
- /* We're disconnected so we don't know the ril version */
- notifyRegistrantsRilConnectionChanged(-1);
- }
- }
-
-
-
- //***** Constructors
-
- public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
- super(context);
- if (RILJ_LOGD) {
- riljLog("RIL(context, preferredNetworkType=" + preferredNetworkType +
- " cdmaSubscription=" + cdmaSubscription + ")");
- }
- mCdmaSubscription = cdmaSubscription;
- mPreferredNetworkType = preferredNetworkType;
- mPhoneType = RILConstants.NO_PHONE;
-
- PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
- mWakeLock.setReferenceCounted(false);
- mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,
- DEFAULT_WAKE_LOCK_TIMEOUT);
- mRequestMessagesPending = 0;
- mRequestMessagesWaiting = 0;
-
- mSenderThread = new HandlerThread("RILSender");
- mSenderThread.start();
-
- Looper looper = mSenderThread.getLooper();
- mSender = new RILSender(looper);
-
- ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
- riljLog("Not starting RILReceiver: wifi-only");
- } else {
- riljLog("Starting RILReceiver");
- mReceiver = new RILReceiver();
- mReceiverThread = new Thread(mReceiver, "RILReceiver");
- mReceiverThread.start();
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- context.registerReceiver(mIntentReceiver, filter);
- }
- }
-
- //***** CommandsInterface implementation
-
- public void getVoiceRadioTechnology(Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_VOICE_RADIO_TECH, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
-
- @Override public void
- setOnNITZTime(Handler h, int what, Object obj) {
- super.setOnNITZTime(h, what, obj);
-
- // Send the last NITZ time if we have it
- if (mLastNITZTimeInfo != null) {
- mNITZTimeRegistrant
- .notifyRegistrant(
- new AsyncResult (null, mLastNITZTimeInfo, null));
- mLastNITZTimeInfo = null;
- }
- }
-
- public void
- getIccCardStatus(Message result) {
- //Note: This RIL request has not been renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- @Override public void
- supplyIccPin(String pin, Message result) {
- supplyIccPinForApp(pin, null, result);
- }
-
- @Override public void
- supplyIccPinForApp(String pin, String aid, Message result) {
- //Note: This RIL request has not been renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeInt(2);
- rr.mp.writeString(pin);
- rr.mp.writeString(aid);
-
- send(rr);
- }
-
- @Override public void
- supplyIccPuk(String puk, String newPin, Message result) {
- supplyIccPukForApp(puk, newPin, null, result);
- }
-
- @Override public void
- supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
- //Note: This RIL request has not been renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeInt(3);
- rr.mp.writeString(puk);
- rr.mp.writeString(newPin);
- rr.mp.writeString(aid);
-
- send(rr);
- }
-
- @Override public void
- supplyIccPin2(String pin, Message result) {
- supplyIccPin2ForApp(pin, null, result);
- }
-
- @Override public void
- supplyIccPin2ForApp(String pin, String aid, Message result) {
- //Note: This RIL request has not been renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeInt(2);
- rr.mp.writeString(pin);
- rr.mp.writeString(aid);
-
- send(rr);
- }
-
- @Override public void
- supplyIccPuk2(String puk2, String newPin2, Message result) {
- supplyIccPuk2ForApp(puk2, newPin2, null, result);
- }
-
- @Override public void
- supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
- //Note: This RIL request has not been renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeInt(3);
- rr.mp.writeString(puk);
- rr.mp.writeString(newPin2);
- rr.mp.writeString(aid);
-
- send(rr);
- }
-
- @Override public void
- changeIccPin(String oldPin, String newPin, Message result) {
- changeIccPinForApp(oldPin, newPin, null, result);
- }
-
- @Override public void
- changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
- //Note: This RIL request has not been renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeInt(3);
- rr.mp.writeString(oldPin);
- rr.mp.writeString(newPin);
- rr.mp.writeString(aid);
-
- send(rr);
- }
-
- @Override public void
- changeIccPin2(String oldPin2, String newPin2, Message result) {
- changeIccPin2ForApp(oldPin2, newPin2, null, result);
- }
-
- @Override public void
- changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
- //Note: This RIL request has not been renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeInt(3);
- rr.mp.writeString(oldPin2);
- rr.mp.writeString(newPin2);
- rr.mp.writeString(aid);
-
- send(rr);
- }
-
- public void
- changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeInt(3);
- rr.mp.writeString(facility);
- rr.mp.writeString(oldPwd);
- rr.mp.writeString(newPwd);
-
- send(rr);
- }
-
- public void
- supplyNetworkDepersonalization(String netpin, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeInt(1);
- rr.mp.writeString(netpin);
-
- send(rr);
- }
-
- public void
- getCurrentCalls (Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- @Deprecated public void
- getPDPContextList(Message result) {
- getDataCallList(result);
- }
-
- public void
- getDataCallList(Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_DATA_CALL_LIST, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- dial (String address, int clirMode, Message result) {
- dial(address, clirMode, null, result);
- }
-
- public void
- dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
-
- rr.mp.writeString(address);
- rr.mp.writeInt(clirMode);
- rr.mp.writeInt(0); // UUS information is absent
-
- if (uusInfo == null) {
- rr.mp.writeInt(0); // UUS information is absent
- } else {
- rr.mp.writeInt(1); // UUS information is present
- rr.mp.writeInt(uusInfo.getType());
- rr.mp.writeInt(uusInfo.getDcs());
- rr.mp.writeByteArray(uusInfo.getUserData());
- }
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getIMSI(Message result) {
- getIMSIForApp(null, result);
- }
-
- public void
- getIMSIForApp(String aid, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result);
-
- rr.mp.writeInt(1);
- rr.mp.writeString(aid);
-
- if (RILJ_LOGD) riljLog(rr.serialString() +
- "> getIMSI: " + requestToString(rr.mRequest)
- + " aid: " + aid);
-
- send(rr);
- }
-
- public void
- getIMEI(Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEI, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getIMEISV(Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEISV, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
-
- public void
- hangupConnection (int gsmIndex, Message result) {
- if (RILJ_LOGD) riljLog("hangupConnection: gsmIndex=" + gsmIndex);
-
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " +
- gsmIndex);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(gsmIndex);
-
- send(rr);
- }
-
- public void
- hangupWaitingOrBackground (Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND,
- result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- hangupForegroundResumeBackground (Message result) {
- RILRequest rr
- = RILRequest.obtain(
- RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
- result);
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- switchWaitingOrHoldingAndActive (Message result) {
- RILRequest rr
- = RILRequest.obtain(
- RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
- result);
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- conference (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_CONFERENCE, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
-
- public void setPreferredVoicePrivacy(boolean enable, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE,
- result);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(enable ? 1:0);
-
- send(rr);
- }
-
- public void getPreferredVoicePrivacy(Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE,
- result);
- send(rr);
- }
-
- public void
- separateConnection (int gsmIndex, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SEPARATE_CONNECTION, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + gsmIndex);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(gsmIndex);
-
- send(rr);
- }
-
- public void
- acceptCall (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_ANSWER, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- rejectCall (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_UDUB, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- explicitCallTransfer (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getLastCallFailCause (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * @deprecated
- */
- public void
- getLastPdpFailCause (Message result) {
- getLastDataCallFailCause (result);
- }
-
- /**
- * The preferred new alternative to getLastPdpFailCause
- */
- public void
- getLastDataCallFailCause (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- setMute (boolean enableMute, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_MUTE, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + enableMute);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(enableMute ? 1 : 0);
-
- send(rr);
- }
-
- public void
- getMute (Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_GET_MUTE, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getSignalStrength (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getVoiceRegistrationState (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_VOICE_REGISTRATION_STATE, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getDataRegistrationState (Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getOperator(Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_OPERATOR, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- sendDtmf(char c, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_DTMF, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeString(Character.toString(c));
-
- send(rr);
- }
-
- public void
- startDtmf(char c, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_DTMF_START, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeString(Character.toString(c));
-
- send(rr);
- }
-
- public void
- stopDtmf(Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_DTMF_STOP, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- sendBurstDtmf(String dtmfString, int on, int off, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BURST_DTMF, result);
-
- rr.mp.writeInt(3);
- rr.mp.writeString(dtmfString);
- rr.mp.writeString(Integer.toString(on));
- rr.mp.writeString(Integer.toString(off));
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " : " + dtmfString);
-
- send(rr);
- }
-
- public void
- sendSMS (String smscPDU, String pdu, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result);
-
- rr.mp.writeInt(2);
- rr.mp.writeString(smscPDU);
- rr.mp.writeString(pdu);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- sendCdmaSms(byte[] pdu, Message result) {
- int address_nbr_of_digits;
- int subaddr_nbr_of_digits;
- int bearerDataLength;
- ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
- DataInputStream dis = new DataInputStream(bais);
-
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_CDMA_SEND_SMS, result);
-
- try {
- rr.mp.writeInt(dis.readInt()); //teleServiceId
- rr.mp.writeByte((byte) dis.readInt()); //servicePresent
- rr.mp.writeInt(dis.readInt()); //serviceCategory
- rr.mp.writeInt(dis.read()); //address_digit_mode
- rr.mp.writeInt(dis.read()); //address_nbr_mode
- rr.mp.writeInt(dis.read()); //address_ton
- rr.mp.writeInt(dis.read()); //address_nbr_plan
- address_nbr_of_digits = (byte) dis.read();
- rr.mp.writeByte((byte) address_nbr_of_digits);
- for(int i=0; i < address_nbr_of_digits; i++){
- rr.mp.writeByte(dis.readByte()); // address_orig_bytes[i]
- }
- rr.mp.writeInt(dis.read()); //subaddressType
- rr.mp.writeByte((byte) dis.read()); //subaddr_odd
- subaddr_nbr_of_digits = (byte) dis.read();
- rr.mp.writeByte((byte) subaddr_nbr_of_digits);
- for(int i=0; i < subaddr_nbr_of_digits; i++){
- rr.mp.writeByte(dis.readByte()); //subaddr_orig_bytes[i]
- }
-
- bearerDataLength = dis.read();
- rr.mp.writeInt(bearerDataLength);
- for(int i=0; i < bearerDataLength; i++){
- rr.mp.writeByte(dis.readByte()); //bearerData[i]
- }
- }catch (IOException ex){
- if (RILJ_LOGD) riljLog("sendSmsCdma: conversion from input stream to object failed: "
- + ex);
- }
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void deleteSmsOnSim(int index, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_DELETE_SMS_ON_SIM,
- response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(index);
-
- if (false) {
- if (RILJ_LOGD) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest)
- + " " + index);
- }
-
- send(rr);
- }
-
- public void deleteSmsOnRuim(int index, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM,
- response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(index);
-
- if (false) {
- if (RILJ_LOGD) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest)
- + " " + index);
- }
-
- send(rr);
- }
-
- public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
- status = translateStatus(status);
-
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_WRITE_SMS_TO_SIM,
- response);
-
- rr.mp.writeInt(status);
- rr.mp.writeString(pdu);
- rr.mp.writeString(smsc);
-
- if (false) {
- if (RILJ_LOGD) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest)
- + " " + status);
- }
-
- send(rr);
- }
-
- public void writeSmsToRuim(int status, String pdu, Message response) {
- status = translateStatus(status);
-
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM,
- response);
-
- rr.mp.writeInt(status);
- rr.mp.writeString(pdu);
-
- if (false) {
- if (RILJ_LOGD) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest)
- + " " + status);
- }
-
- send(rr);
- }
-
- /**
- * Translates EF_SMS status bits to a status value compatible with
- * SMS AT commands. See TS 27.005 3.1.
- */
- private int translateStatus(int status) {
- switch(status & 0x7) {
- case SmsManager.STATUS_ON_ICC_READ:
- return 1;
- case SmsManager.STATUS_ON_ICC_UNREAD:
- return 0;
- case SmsManager.STATUS_ON_ICC_SENT:
- return 3;
- case SmsManager.STATUS_ON_ICC_UNSENT:
- return 2;
- }
-
- // Default to READ.
- return 1;
- }
-
- public void
- setupDataCall(String radioTechnology, String profile, String apn,
- String user, String password, String authType, String protocol,
- Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
-
- rr.mp.writeInt(7);
-
- rr.mp.writeString(radioTechnology);
- rr.mp.writeString(profile);
- rr.mp.writeString(apn);
- rr.mp.writeString(user);
- rr.mp.writeString(password);
- rr.mp.writeString(authType);
- rr.mp.writeString(protocol);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest) + " " + radioTechnology + " "
- + profile + " " + apn + " " + user + " "
- + password + " " + authType + " " + protocol);
-
- send(rr);
- }
-
- public void
- deactivateDataCall(int cid, int reason, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DATA_CALL, result);
-
- rr.mp.writeInt(2);
- rr.mp.writeString(Integer.toString(cid));
- rr.mp.writeString(Integer.toString(reason));
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " +
- requestToString(rr.mRequest) + " " + cid + " " + reason);
-
- send(rr);
- }
-
- public void
- setRadioPower(boolean on, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(on ? 1 : 0);
-
- if (RILJ_LOGD) {
- riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + (on ? " on" : " off"));
- }
-
- send(rr);
- }
-
- public void
- setSuppServiceNotifications(boolean enable, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(enable ? 1 : 0);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result);
-
- rr.mp.writeInt(2);
- rr.mp.writeInt(success ? 1 : 0);
- rr.mp.writeInt(cause);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + success + " " + cause);
-
- send(rr);
- }
-
- public void
- acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result);
-
- rr.mp.writeInt(success ? 0 : 1); //RIL_CDMA_SMS_ErrorClass
- // cause code according to X.S004-550E
- rr.mp.writeInt(cause);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + success + " " + cause);
-
- send(rr);
- }
-
- public void
- acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result);
-
- rr.mp.writeInt(2);
- rr.mp.writeString(success ? "1" : "0");
- rr.mp.writeString(ackPdu);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + ' ' + success + " [" + ackPdu + ']');
-
- send(rr);
- }
-
- public void
- iccIO (int command, int fileid, String path, int p1, int p2, int p3,
- String data, String pin2, Message result) {
- iccIOForApp(command, fileid, path, p1, p2, p3, data, pin2, null, result);
- }
- public void
- iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3,
- String data, String pin2, String aid, Message result) {
- //Note: This RIL request has not been renamed to ICC,
- // but this request is also valid for SIM and RUIM
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SIM_IO, result);
-
- rr.mp.writeInt(command);
- rr.mp.writeInt(fileid);
- rr.mp.writeString(path);
- rr.mp.writeInt(p1);
- rr.mp.writeInt(p2);
- rr.mp.writeInt(p3);
- rr.mp.writeString(data);
- rr.mp.writeString(pin2);
- rr.mp.writeString(aid);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: "
- + requestToString(rr.mRequest)
- + " 0x" + Integer.toHexString(command)
- + " 0x" + Integer.toHexString(fileid) + " "
- + " path: " + path + ","
- + p1 + "," + p2 + "," + p3
- + " aid: " + aid);
-
- send(rr);
- }
-
- public void
- getCLIR(Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_GET_CLIR, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- setCLIR(int clirMode, Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_CLIR, result);
-
- // count ints
- rr.mp.writeInt(1);
-
- rr.mp.writeInt(clirMode);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + clirMode);
-
- send(rr);
- }
-
- public void
- queryCallWaiting(int serviceClass, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_WAITING, response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(serviceClass);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + serviceClass);
-
- send(rr);
- }
-
- public void
- setCallWaiting(boolean enable, int serviceClass, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_CALL_WAITING, response);
-
- rr.mp.writeInt(2);
- rr.mp.writeInt(enable ? 1 : 0);
- rr.mp.writeInt(serviceClass);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + enable + ", " + serviceClass);
-
- send(rr);
- }
-
- public void
- setNetworkSelectionModeAutomatic(Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC,
- response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- setNetworkSelectionModeManual(String operatorNumeric, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
- response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + operatorNumeric);
-
- rr.mp.writeString(operatorNumeric);
-
- send(rr);
- }
-
- public void
- getNetworkSelectionMode(Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE,
- response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getAvailableNetworks(Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS,
- response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- setCallForward(int action, int cfReason, int serviceClass,
- String number, int timeSeconds, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_CALL_FORWARD, response);
-
- rr.mp.writeInt(action);
- rr.mp.writeInt(cfReason);
- rr.mp.writeInt(serviceClass);
- rr.mp.writeInt(PhoneNumberUtils.toaFromString(number));
- rr.mp.writeString(number);
- rr.mp.writeInt (timeSeconds);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + action + " " + cfReason + " " + serviceClass
- + timeSeconds);
-
- send(rr);
- }
-
- public void
- queryCallForwardStatus(int cfReason, int serviceClass,
- String number, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, response);
-
- rr.mp.writeInt(2); // 2 is for query action, not in used anyway
- rr.mp.writeInt(cfReason);
- rr.mp.writeInt(serviceClass);
- rr.mp.writeInt(PhoneNumberUtils.toaFromString(number));
- rr.mp.writeString(number);
- rr.mp.writeInt (0);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + cfReason + " " + serviceClass);
-
- send(rr);
- }
-
- public void
- queryCLIP(Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_QUERY_CLIP, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
-
- public void
- getBasebandVersion (Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_BASEBAND_VERSION, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- @Override
- public void
- queryFacilityLock(String facility, String password, int serviceClass,
- Message response) {
- queryFacilityLockForApp(facility, password, serviceClass, null, response);
- }
-
- @Override
- public void
- queryFacilityLockForApp(String facility, String password, int serviceClass, String appId,
- Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- // count strings
- rr.mp.writeInt(4);
-
- rr.mp.writeString(facility);
- rr.mp.writeString(password);
-
- rr.mp.writeString(Integer.toString(serviceClass));
- rr.mp.writeString(appId);
-
- send(rr);
- }
-
- @Override
- public void
- setFacilityLock (String facility, boolean lockState, String password,
- int serviceClass, Message response) {
- setFacilityLockForApp(facility, lockState, password, serviceClass, null, response);
- }
-
- @Override
- public void
- setFacilityLockForApp(String facility, boolean lockState, String password,
- int serviceClass, String appId, Message response) {
- String lockString;
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- // count strings
- rr.mp.writeInt(5);
-
- rr.mp.writeString(facility);
- lockString = (lockState)?"1":"0";
- rr.mp.writeString(lockString);
- rr.mp.writeString(password);
- rr.mp.writeString(Integer.toString(serviceClass));
- rr.mp.writeString(appId);
-
- send(rr);
-
- }
-
- public void
- sendUSSD (String ussdString, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SEND_USSD, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + ussdString);
-
- rr.mp.writeString(ussdString);
-
- send(rr);
- }
-
- // inherited javadoc suffices
- public void cancelPendingUssd (Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_CANCEL_USSD, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString()
- + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
-
- public void resetRadio(Message result) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_RESET_RADIO, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_RAW, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + "[" + IccUtils.bytesToHexString(data) + "]");
-
- rr.mp.writeByteArray(data);
-
- send(rr);
-
- }
-
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_STRINGS, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeStringArray(strings);
-
- send(rr);
- }
-
- /**
- * Assign a specified band for RF configuration.
- *
- * @param bandMode one of BM_*_BAND
- * @param response is callback message
- */
- public void setBandMode (int bandMode, Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_SET_BAND_MODE, response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(bandMode);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " " + bandMode);
-
- send(rr);
- }
-
- /**
- * 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
- */
- public void queryAvailableBandMode (Message response) {
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE,
- response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void sendTerminalResponse(String contents, Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeString(contents);
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void sendEnvelope(String contents, Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- rr.mp.writeString(contents);
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void sendEnvelopeWithStatus(String contents, Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + '[' + contents + ']');
-
- rr.mp.writeString(contents);
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void handleCallSetupRequestFromSim(
- boolean accept, Message response) {
-
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
- response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- int[] param = new int[1];
- param[0] = accept ? 1 : 0;
- rr.mp.writeIntArray(param);
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setCurrentPreferredNetworkType() {
- if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType: " + mSetPreferredNetworkType);
- setPreferredNetworkType(mSetPreferredNetworkType, null);
- }
- private int mSetPreferredNetworkType;
-
- /**
- * {@inheritDoc}
- */
- public void setPreferredNetworkType(int networkType , Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(networkType);
-
- mSetPreferredNetworkType = networkType;
- mPreferredNetworkType = networkType;
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " : " + networkType);
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void getPreferredNetworkType(Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void getNeighboringCids(Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setLocationUpdates(boolean enable, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_LOCATION_UPDATES, response);
- rr.mp.writeInt(1);
- rr.mp.writeInt(enable ? 1 : 0);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest) + ": " + enable);
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void getSmscAddress(Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SMSC_ADDRESS, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setSmscAddress(String address, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_SMSC_ADDRESS, result);
-
- rr.mp.writeString(address);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " : " + address);
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void reportSmsMemoryStatus(boolean available, Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result);
- rr.mp.writeInt(1);
- rr.mp.writeInt(available ? 1 : 0);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> "
- + requestToString(rr.mRequest) + ": " + available);
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void reportStkServiceIsRunning(Message result) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void getGsmBroadcastConfig(Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, response);
-
- int numOfConfig = config.length;
- rr.mp.writeInt(numOfConfig);
-
- for(int i = 0; i < numOfConfig; i++) {
- rr.mp.writeInt(config[i].getFromServiceId());
- rr.mp.writeInt(config[i].getToServiceId());
- rr.mp.writeInt(config[i].getFromCodeScheme());
- rr.mp.writeInt(config[i].getToCodeScheme());
- rr.mp.writeInt(config[i].isSelected() ? 1 : 0);
- }
-
- if (RILJ_LOGD) {
- riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " with " + numOfConfig + " configs : ");
- for (int i = 0; i < numOfConfig; i++) {
- riljLog(config[i].toString());
- }
- }
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setGsmBroadcastActivation(boolean activate, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(activate ? 0 : 1);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- //***** Private Methods
-
- private void sendScreenState(boolean on) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_SCREEN_STATE, null);
- rr.mp.writeInt(1);
- rr.mp.writeInt(on ? 1 : 0);
-
- if (RILJ_LOGD) riljLog(rr.serialString()
- + "> " + requestToString(rr.mRequest) + ": " + on);
-
- send(rr);
- }
-
- protected void
- onRadioAvailable() {
- // In case screen state was lost (due to process crash),
- // this ensures that the RIL knows the correct screen state.
-
- // TODO: Should query Power Manager and send the actual
- // screen state. Just send true for now.
- sendScreenState(true);
- }
-
- private RadioState getRadioStateFromInt(int stateInt) {
- RadioState state;
-
- /* RIL_RadioState ril.h */
- switch(stateInt) {
- case 0: state = RadioState.RADIO_OFF; break;
- case 1: state = RadioState.RADIO_UNAVAILABLE; break;
- case 10: state = RadioState.RADIO_ON; break;
-
- default:
- throw new RuntimeException(
- "Unrecognized RIL_RadioState: " + stateInt);
- }
- return state;
- }
-
- private void switchToRadioState(RadioState newState) {
- setRadioState(newState);
- }
-
- /**
- * Holds a PARTIAL_WAKE_LOCK whenever
- * a) There is outstanding RIL request sent to RIL deamon and no replied
- * b) There is a request pending to be sent out.
- *
- * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
- * happen often.
- */
-
- private void
- acquireWakeLock() {
- synchronized (mWakeLock) {
- mWakeLock.acquire();
- mRequestMessagesPending++;
-
- mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
- Message msg = mSender.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
- mSender.sendMessageDelayed(msg, mWakeLockTimeout);
- }
- }
-
- private void
- releaseWakeLockIfDone() {
- synchronized (mWakeLock) {
- if (mWakeLock.isHeld() &&
- (mRequestMessagesPending == 0) &&
- (mRequestMessagesWaiting == 0)) {
- mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
- mWakeLock.release();
- }
- }
- }
-
- private void
- send(RILRequest rr) {
- Message msg;
-
- if (mSocket == null) {
- rr.onError(RADIO_NOT_AVAILABLE, null);
- rr.release();
- return;
- }
-
- msg = mSender.obtainMessage(EVENT_SEND, rr);
-
- acquireWakeLock();
-
- msg.sendToTarget();
- }
-
- private void
- processResponse (Parcel p) {
- int type;
-
- type = p.readInt();
-
- if (type == RESPONSE_UNSOLICITED) {
- processUnsolicited (p);
- } else if (type == RESPONSE_SOLICITED) {
- processSolicited (p);
- }
-
- releaseWakeLockIfDone();
- }
-
- /**
- * Release each request in mReqeustsList then clear the list
- * @param error is the RIL_Errno sent back
- * @param loggable true means to print all requests in mRequestslist
- */
- private void clearRequestsList(int error, boolean loggable) {
- RILRequest rr;
- synchronized (mRequestsList) {
- int count = mRequestsList.size();
- if (RILJ_LOGD && loggable) {
- Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
- " mReqPending=" + mRequestMessagesPending +
- " mRequestList=" + count);
- }
-
- for (int i = 0; i < count ; i++) {
- rr = mRequestsList.get(i);
- if (RILJ_LOGD && loggable) {
- Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " +
- requestToString(rr.mRequest));
- }
- rr.onError(error, null);
- rr.release();
- }
- mRequestsList.clear();
- mRequestMessagesWaiting = 0;
- }
- }
-
- private RILRequest findAndRemoveRequestFromList(int serial) {
- synchronized (mRequestsList) {
- for (int i = 0, s = mRequestsList.size() ; i < s ; i++) {
- RILRequest rr = mRequestsList.get(i);
-
- if (rr.mSerial == serial) {
- mRequestsList.remove(i);
- if (mRequestMessagesWaiting > 0)
- mRequestMessagesWaiting--;
- return rr;
- }
- }
- }
-
- return null;
- }
-
- private void
- processSolicited (Parcel p) {
- int serial, error;
- boolean found = false;
-
- serial = p.readInt();
- error = p.readInt();
-
- RILRequest rr;
-
- rr = findAndRemoveRequestFromList(serial);
-
- if (rr == null) {
- Log.w(LOG_TAG, "Unexpected solicited response! sn: "
- + serial + " error: " + error);
- return;
- }
-
- Object ret = null;
-
- if (error == 0 || p.dataAvail() > 0) {
- // either command succeeds or command fails but with data payload
- try {switch (rr.mRequest) {
- /*
- cat libs/telephony/ril_commands.h \
- | egrep "^ *{RIL_" \
- | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/'
- */
- case RIL_REQUEST_GET_SIM_STATUS: ret = responseIccCardStatus(p); break;
- case RIL_REQUEST_ENTER_SIM_PIN: ret = responseInts(p); break;
- case RIL_REQUEST_ENTER_SIM_PUK: ret = responseInts(p); break;
- case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseInts(p); break;
- case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseInts(p); break;
- case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseInts(p); break;
- case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseInts(p); break;
- case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseInts(p); break;
- case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break;
- case RIL_REQUEST_DIAL: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_IMSI: ret = responseString(p); break;
- case RIL_REQUEST_HANGUP: ret = responseVoid(p); break;
- case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break;
- case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: {
- if (mTestingEmergencyCall.getAndSet(false)) {
- if (mEmergencyCallbackModeRegistrant != null) {
- riljLog("testing emergency call, notify ECM Registrants");
- mEmergencyCallbackModeRegistrant.notifyRegistrant();
- }
- }
- ret = responseVoid(p);
- break;
- }
- case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break;
- case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break;
- case RIL_REQUEST_UDUB: ret = responseVoid(p); break;
- case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break;
- case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
- case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseStrings(p); break;
- case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break;
- case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break;
- case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break;
- case RIL_REQUEST_DTMF: ret = responseVoid(p); break;
- case RIL_REQUEST_SEND_SMS: ret = responseSMS(p); break;
- case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret = responseSMS(p); break;
- case RIL_REQUEST_SETUP_DATA_CALL: ret = responseSetupDataCall(p); break;
- case RIL_REQUEST_SIM_IO: ret = responseICC_IO(p); break;
- case RIL_REQUEST_SEND_USSD: ret = responseVoid(p); break;
- case RIL_REQUEST_CANCEL_USSD: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_CLIR: ret = responseInts(p); break;
- case RIL_REQUEST_SET_CLIR: ret = responseVoid(p); break;
- case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret = responseCallForward(p); break;
- case RIL_REQUEST_SET_CALL_FORWARD: ret = responseVoid(p); break;
- case RIL_REQUEST_QUERY_CALL_WAITING: ret = responseInts(p); break;
- case RIL_REQUEST_SET_CALL_WAITING: ret = responseVoid(p); break;
- case RIL_REQUEST_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_IMEI: ret = responseString(p); break;
- case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break;
- case RIL_REQUEST_ANSWER: ret = responseVoid(p); break;
- case RIL_REQUEST_DEACTIVATE_DATA_CALL: ret = responseVoid(p); break;
- case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break;
- case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseInts(p); break;
- case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break;
- case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break;
- case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret = responseVoid(p); break;
- case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret = responseOperatorInfos(p); break;
- case RIL_REQUEST_DTMF_START: ret = responseVoid(p); break;
- case RIL_REQUEST_DTMF_STOP: ret = responseVoid(p); break;
- case RIL_REQUEST_BASEBAND_VERSION: ret = responseString(p); break;
- case RIL_REQUEST_SEPARATE_CONNECTION: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_MUTE: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break;
- case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break;
- case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: ret = responseInts(p); break;
- case RIL_REQUEST_DATA_CALL_LIST: ret = responseDataCallList(p); break;
- case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break;
- case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break;
- case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break;
- case RIL_REQUEST_SCREEN_STATE: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break;
- case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break;
- case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break;
- case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break;
- case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break;
- case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break;
- case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break;
- case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break;
- case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break;
- case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break;
- case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseGetPreferredNetworkType(p); break;
- case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
- case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break;
- case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break;
- case RIL_REQUEST_QUERY_TTY_MODE: ret = responseInts(p); break;
- case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: ret = responseInts(p); break;
- case RIL_REQUEST_CDMA_FLASH: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break;
- case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
- case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break;
- case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
- case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break;
- case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break;
- case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break;
- case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break;
- case RIL_REQUEST_DEVICE_IDENTITY: ret = responseStrings(p); break;
- case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
- case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
- case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
- case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
- case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break;
- case RIL_REQUEST_ISIM_AUTHENTICATION: ret = responseString(p); break;
- case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: ret = responseVoid(p); break;
- case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: ret = responseICC_IO(p); break;
- case RIL_REQUEST_VOICE_RADIO_TECH: ret = responseInts(p); break;
- default:
- throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
- //break;
- }} catch (Throwable tr) {
- // Exceptions here usually mean invalid RIL responses
-
- Log.w(LOG_TAG, rr.serialString() + "< "
- + requestToString(rr.mRequest)
- + " exception, possible invalid RIL response", tr);
-
- if (rr.mResult != null) {
- AsyncResult.forMessage(rr.mResult, null, tr);
- rr.mResult.sendToTarget();
- }
- rr.release();
- return;
- }
- }
-
- if (error != 0) {
- rr.onError(error, ret);
- rr.release();
- return;
- }
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
- + " " + retToString(rr.mRequest, ret));
-
- if (rr.mResult != null) {
- AsyncResult.forMessage(rr.mResult, ret, null);
- rr.mResult.sendToTarget();
- }
-
- rr.release();
- }
-
- private String
- retToString(int req, Object ret) {
- if (ret == null) return "";
- switch (req) {
- // Don't log these return values, for privacy's sake.
- case RIL_REQUEST_GET_IMSI:
- case RIL_REQUEST_GET_IMEI:
- case RIL_REQUEST_GET_IMEISV:
- if (!RILJ_LOGV) {
- // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
- return "";
- }
- }
-
- StringBuilder sb;
- String s;
- int length;
- if (ret instanceof int[]){
- int[] intArray = (int[]) ret;
- length = intArray.length;
- sb = new StringBuilder("{");
- if (length > 0) {
- int i = 0;
- sb.append(intArray[i++]);
- while ( i < length) {
- sb.append(", ").append(intArray[i++]);
- }
- }
- sb.append("}");
- s = sb.toString();
- } else if (ret instanceof String[]) {
- String[] strings = (String[]) ret;
- length = strings.length;
- sb = new StringBuilder("{");
- if (length > 0) {
- int i = 0;
- sb.append(strings[i++]);
- while ( i < length) {
- sb.append(", ").append(strings[i++]);
- }
- }
- sb.append("}");
- s = sb.toString();
- }else if (req == RIL_REQUEST_GET_CURRENT_CALLS) {
- ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret;
- sb = new StringBuilder(" ");
- for (DriverCall dc : calls) {
- sb.append("[").append(dc).append("] ");
- }
- s = sb.toString();
- } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) {
- ArrayList<NeighboringCellInfo> cells;
- cells = (ArrayList<NeighboringCellInfo>) ret;
- sb = new StringBuilder(" ");
- for (NeighboringCellInfo cell : cells) {
- sb.append(cell).append(" ");
- }
- s = sb.toString();
- } else {
- s = ret.toString();
- }
- return s;
- }
-
- private void
- processUnsolicited (Parcel p) {
- int response;
- Object ret;
-
- response = p.readInt();
-
- try {switch(response) {
-/*
- cat libs/telephony/ril_unsol_commands.h \
- | egrep "^ *{RIL_" \
- | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
-*/
-
- case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
- case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break;
- case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
- case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;
- case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break;
- case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break;
- case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break;
- case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break;
- case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
- case RIL_UNSOL_DATA_CALL_LIST_CHANGED: ret = responseDataCallList(p);break;
- case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break;
- case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break;
- case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break;
- case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break;
- case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break;
- case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
- case RIL_UNSOL_SIM_REFRESH: ret = responseSimRefresh(p); break;
- case RIL_UNSOL_CALL_RING: ret = responseCallRing(p); break;
- case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
- case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
- case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break;
- case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseRaw(p); break;
- case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
- case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
- case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
- case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
- case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
- case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
- case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
- case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
- case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: ret = responseInts(p); break;
- case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
- case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
- case RIL_UNSOL_RIL_CONNECTED: ret = responseInts(p); break;
- case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: ret = responseInts(p); break;
-
- default:
- throw new RuntimeException("Unrecognized unsol response: " + response);
- //break; (implied)
- }} catch (Throwable tr) {
- Log.e(LOG_TAG, "Exception processing unsol response: " + response +
- "Exception:" + tr.toString());
- return;
- }
-
- switch(response) {
- case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
- /* has bonus radio state int */
- RadioState newState = getRadioStateFromInt(p.readInt());
- if (RILJ_LOGD) unsljLogMore(response, newState.toString());
-
- switchToRadioState(newState);
- break;
- case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
- if (RILJ_LOGD) unsljLog(response);
-
- mCallStateRegistrants
- .notifyRegistrants(new AsyncResult(null, null, null));
- break;
- case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
- if (RILJ_LOGD) unsljLog(response);
-
- mVoiceNetworkStateRegistrants
- .notifyRegistrants(new AsyncResult(null, null, null));
- break;
- case RIL_UNSOL_RESPONSE_NEW_SMS: {
- if (RILJ_LOGD) unsljLog(response);
-
- // FIXME this should move up a layer
- String a[] = new String[2];
-
- a[1] = (String)ret;
-
- SmsMessage sms;
-
- sms = SmsMessage.newFromCMT(a);
- if (mGsmSmsRegistrant != null) {
- mGsmSmsRegistrant
- .notifyRegistrant(new AsyncResult(null, sms, null));
- }
- break;
- }
- case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mSmsStatusRegistrant != null) {
- mSmsStatusRegistrant.notifyRegistrant(
- new AsyncResult(null, ret, null));
- }
- break;
- case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- int[] smsIndex = (int[])ret;
-
- if(smsIndex.length == 1) {
- if (mSmsOnSimRegistrant != null) {
- mSmsOnSimRegistrant.
- notifyRegistrant(new AsyncResult(null, smsIndex, null));
- }
- } else {
- if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length "
- + smsIndex.length);
- }
- break;
- case RIL_UNSOL_ON_USSD:
- String[] resp = (String[])ret;
-
- if (resp.length < 2) {
- resp = new String[2];
- resp[0] = ((String[])ret)[0];
- resp[1] = null;
- }
- if (RILJ_LOGD) unsljLogMore(response, resp[0]);
- if (mUSSDRegistrant != null) {
- mUSSDRegistrant.notifyRegistrant(
- new AsyncResult (null, resp, null));
- }
- break;
- case RIL_UNSOL_NITZ_TIME_RECEIVED:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- // has bonus long containing milliseconds since boot that the NITZ
- // time was received
- long nitzReceiveTime = p.readLong();
-
- Object[] result = new Object[2];
-
- result[0] = ret;
- result[1] = Long.valueOf(nitzReceiveTime);
-
- boolean ignoreNitz = SystemProperties.getBoolean(
- TelephonyProperties.PROPERTY_IGNORE_NITZ, false);
-
- if (ignoreNitz) {
- if (RILJ_LOGD) riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED");
- } else {
- if (mNITZTimeRegistrant != null) {
-
- mNITZTimeRegistrant
- .notifyRegistrant(new AsyncResult (null, result, null));
- } else {
- // in case NITZ time registrant isnt registered yet
- mLastNITZTimeInfo = result;
- }
- }
- break;
-
- case RIL_UNSOL_SIGNAL_STRENGTH:
- // Note this is set to "verbose" because it happens
- // frequently
- if (RILJ_LOGV) unsljLogvRet(response, ret);
-
- if (mSignalStrengthRegistrant != null) {
- mSignalStrengthRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
- break;
- case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
- break;
-
- case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mSsnRegistrant != null) {
- mSsnRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_STK_SESSION_END:
- if (RILJ_LOGD) unsljLog(response);
-
- if (mCatSessionEndRegistrant != null) {
- mCatSessionEndRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_STK_PROACTIVE_COMMAND:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mCatProCmdRegistrant != null) {
- mCatProCmdRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_STK_EVENT_NOTIFY:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mCatEventRegistrant != null) {
- mCatEventRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_STK_CALL_SETUP:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mCatCallSetUpRegistrant != null) {
- mCatCallSetUpRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
- if (RILJ_LOGD) unsljLog(response);
-
- if (mIccSmsFullRegistrant != null) {
- mIccSmsFullRegistrant.notifyRegistrant();
- }
- break;
-
- case RIL_UNSOL_SIM_REFRESH:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mIccRefreshRegistrants != null) {
- mIccRefreshRegistrants.notifyRegistrants(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_CALL_RING:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mRingRegistrant != null) {
- mRingRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
- if (RILJ_LOGD) unsljLogvRet(response, ret);
- if (mRestrictedStateRegistrant != null) {
- mRestrictedStateRegistrant.notifyRegistrant(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
- if (RILJ_LOGD) unsljLog(response);
-
- if (mIccStatusChangedRegistrants != null) {
- mIccStatusChangedRegistrants.notifyRegistrants();
- }
- break;
-
- case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
- if (RILJ_LOGD) unsljLog(response);
-
- SmsMessage sms = (SmsMessage) ret;
-
- if (mCdmaSmsRegistrant != null) {
- mCdmaSmsRegistrant
- .notifyRegistrant(new AsyncResult(null, sms, null));
- }
- break;
-
- case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
- if (RILJ_LOGD) unsljLog(response);
-
- if (mGsmBroadcastSmsRegistrant != null) {
- mGsmBroadcastSmsRegistrant
- .notifyRegistrant(new AsyncResult(null, ret, null));
- }
- break;
-
- case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
- if (RILJ_LOGD) unsljLog(response);
-
- if (mIccSmsFullRegistrant != null) {
- mIccSmsFullRegistrant.notifyRegistrant();
- }
- break;
-
- case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
- if (RILJ_LOGD) unsljLog(response);
-
- if (mEmergencyCallbackModeRegistrant != null) {
- mEmergencyCallbackModeRegistrant.notifyRegistrant();
- }
- break;
-
- case RIL_UNSOL_CDMA_CALL_WAITING:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mCallWaitingInfoRegistrants != null) {
- mCallWaitingInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mOtaProvisionRegistrants != null) {
- mOtaProvisionRegistrants.notifyRegistrants(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_CDMA_INFO_REC:
- ArrayList<CdmaInformationRecords> listInfoRecs;
-
- try {
- listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
- } catch (ClassCastException e) {
- Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
- break;
- }
-
- for (CdmaInformationRecords rec : listInfoRecs) {
- if (RILJ_LOGD) unsljLogRet(response, rec);
- notifyRegistrantsCdmaInfoRec(rec);
- }
- break;
-
- case RIL_UNSOL_OEM_HOOK_RAW:
- if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[])ret));
- if (mUnsolOemHookRawRegistrant != null) {
- mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
- }
- break;
-
- case RIL_UNSOL_RINGBACK_TONE:
- if (RILJ_LOGD) unsljLogvRet(response, ret);
- if (mRingbackToneRegistrants != null) {
- boolean playtone = (((int[])ret)[0] == 1);
- mRingbackToneRegistrants.notifyRegistrants(
- new AsyncResult (null, playtone, null));
- }
- break;
-
- case RIL_UNSOL_RESEND_INCALL_MUTE:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mResendIncallMuteRegistrants != null) {
- mResendIncallMuteRegistrants.notifyRegistrants(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mVoiceRadioTechChangedRegistrants != null) {
- mVoiceRadioTechChangedRegistrants.notifyRegistrants(
- new AsyncResult(null, ret, null));
- }
- break;
-
- case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mCdmaSubscriptionChangedRegistrants != null) {
- mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOl_CDMA_PRL_CHANGED:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mCdmaPrlChangedRegistrants != null) {
- mCdmaPrlChangedRegistrants.notifyRegistrants(
- new AsyncResult (null, ret, null));
- }
- break;
-
- case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- if (mExitEmergencyCallbackModeRegistrants != null) {
- mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
- new AsyncResult (null, null, null));
- }
- break;
-
- case RIL_UNSOL_RIL_CONNECTED: {
- if (RILJ_LOGD) unsljLogRet(response, ret);
-
- // Initial conditions
- setRadioPower(false, null);
- setPreferredNetworkType(mPreferredNetworkType, null);
- setCdmaSubscriptionSource(mCdmaSubscription, null);
- notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
- break;
- }
- }
- }
-
- /**
- * Notifiy all registrants that the ril has connected or disconnected.
- *
- * @param rilVer is the version of the ril or -1 if disconnected.
- */
- private void notifyRegistrantsRilConnectionChanged(int rilVer) {
- mRilVersion = rilVer;
- if (mRilConnectedRegistrants != null) {
- mRilConnectedRegistrants.notifyRegistrants(
- new AsyncResult (null, new Integer(rilVer), null));
- }
- }
-
- private Object
- responseInts(Parcel p) {
- int numInts;
- int response[];
-
- numInts = p.readInt();
-
- response = new int[numInts];
-
- for (int i = 0 ; i < numInts ; i++) {
- response[i] = p.readInt();
- }
-
- return response;
- }
-
-
- private Object
- responseVoid(Parcel p) {
- return null;
- }
-
- private Object
- responseCallForward(Parcel p) {
- int numInfos;
- CallForwardInfo infos[];
-
- numInfos = p.readInt();
-
- infos = new CallForwardInfo[numInfos];
-
- for (int i = 0 ; i < numInfos ; i++) {
- infos[i] = new CallForwardInfo();
-
- infos[i].status = p.readInt();
- infos[i].reason = p.readInt();
- infos[i].serviceClass = p.readInt();
- infos[i].toa = p.readInt();
- infos[i].number = p.readString();
- infos[i].timeSeconds = p.readInt();
- }
-
- return infos;
- }
-
- private Object
- responseSuppServiceNotification(Parcel p) {
- SuppServiceNotification notification = new SuppServiceNotification();
-
- notification.notificationType = p.readInt();
- notification.code = p.readInt();
- notification.index = p.readInt();
- notification.type = p.readInt();
- notification.number = p.readString();
-
- return notification;
- }
-
- private Object
- responseCdmaSms(Parcel p) {
- SmsMessage sms;
- sms = SmsMessage.newFromParcel(p);
-
- return sms;
- }
-
- private Object
- responseString(Parcel p) {
- String response;
-
- response = p.readString();
-
- return response;
- }
-
- private Object
- responseStrings(Parcel p) {
- int num;
- String response[];
-
- response = p.readStringArray();
-
- if (false) {
- num = p.readInt();
-
- response = new String[num];
- for (int i = 0; i < num; i++) {
- response[i] = p.readString();
- }
- }
-
- return response;
- }
-
- private Object
- responseRaw(Parcel p) {
- int num;
- byte response[];
-
- response = p.createByteArray();
-
- return response;
- }
-
- private Object
- responseSMS(Parcel p) {
- int messageRef, errorCode;
- String ackPDU;
-
- messageRef = p.readInt();
- ackPDU = p.readString();
- errorCode = p.readInt();
-
- SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode);
-
- return response;
- }
-
-
- private Object
- responseICC_IO(Parcel p) {
- int sw1, sw2;
- byte data[] = null;
- Message ret;
-
- sw1 = p.readInt();
- sw2 = p.readInt();
-
- String s = p.readString();
-
- if (RILJ_LOGV) riljLog("< iccIO: "
- + " 0x" + Integer.toHexString(sw1)
- + " 0x" + Integer.toHexString(sw2) + " "
- + s);
-
- return new IccIoResult(sw1, sw2, s);
- }
-
- private Object
- responseIccCardStatus(Parcel p) {
- IccCardApplication ca;
-
- IccCardStatus status = new IccCardStatus();
- status.setCardState(p.readInt());
- status.setUniversalPinState(p.readInt());
- status.setGsmUmtsSubscriptionAppIndex(p.readInt());
- status.setCdmaSubscriptionAppIndex(p.readInt());
- status.setImsSubscriptionAppIndex(p.readInt());
- int numApplications = p.readInt();
-
- // limit to maximum allowed applications
- if (numApplications > IccCardStatus.CARD_MAX_APPS) {
- numApplications = IccCardStatus.CARD_MAX_APPS;
- }
- status.setNumApplications(numApplications);
-
- for (int i = 0 ; i < numApplications ; i++) {
- ca = new IccCardApplication();
- ca.app_type = ca.AppTypeFromRILInt(p.readInt());
- ca.app_state = ca.AppStateFromRILInt(p.readInt());
- ca.perso_substate = ca.PersoSubstateFromRILInt(p.readInt());
- ca.aid = p.readString();
- ca.app_label = p.readString();
- ca.pin1_replaced = p.readInt();
- ca.pin1 = ca.PinStateFromRILInt(p.readInt());
- ca.pin2 = ca.PinStateFromRILInt(p.readInt());
- status.addApplication(ca);
- }
- return status;
- }
-
- private Object
- responseSimRefresh(Parcel p) {
- IccRefreshResponse response = new IccRefreshResponse();
-
- response.refreshResult = p.readInt();
- response.efId = p.readInt();
- response.aid = p.readString();
- return response;
- }
-
- private Object
- responseCallList(Parcel p) {
- int num;
- int voiceSettings;
- ArrayList<DriverCall> response;
- DriverCall dc;
-
- num = p.readInt();
- response = new ArrayList<DriverCall>(num);
-
- if (RILJ_LOGV) {
- riljLog("responseCallList: num=" + num +
- " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant +
- " mTestingEmergencyCall=" + mTestingEmergencyCall.get());
- }
- for (int i = 0 ; i < num ; i++) {
- dc = new DriverCall();
-
- dc.state = DriverCall.stateFromCLCC(p.readInt());
- dc.index = p.readInt();
- dc.TOA = p.readInt();
- dc.isMpty = (0 != p.readInt());
- dc.isMT = (0 != p.readInt());
- dc.als = p.readInt();
- voiceSettings = p.readInt();
- dc.isVoice = (0 == voiceSettings) ? false : true;
- dc.isVoicePrivacy = (0 != p.readInt());
- dc.number = p.readString();
- int np = p.readInt();
- dc.numberPresentation = DriverCall.presentationFromCLIP(np);
- dc.name = p.readString();
- dc.namePresentation = p.readInt();
- int uusInfoPresent = p.readInt();
- if (uusInfoPresent == 1) {
- dc.uusInfo = new UUSInfo();
- dc.uusInfo.setType(p.readInt());
- dc.uusInfo.setDcs(p.readInt());
- byte[] userData = p.createByteArray();
- dc.uusInfo.setUserData(userData);
- riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
- dc.uusInfo.getType(), dc.uusInfo.getDcs(),
- dc.uusInfo.getUserData().length));
- riljLogv("Incoming UUS : data (string)="
- + new String(dc.uusInfo.getUserData()));
- riljLogv("Incoming UUS : data (hex): "
- + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
- } else {
- riljLogv("Incoming UUS : NOT present!");
- }
-
- // Make sure there's a leading + on addresses with a TOA of 145
- dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
-
- response.add(dc);
-
- if (dc.isVoicePrivacy) {
- mVoicePrivacyOnRegistrants.notifyRegistrants();
- riljLog("InCall VoicePrivacy is enabled");
- } else {
- mVoicePrivacyOffRegistrants.notifyRegistrants();
- riljLog("InCall VoicePrivacy is disabled");
- }
- }
-
- Collections.sort(response);
-
- if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) {
- if (mEmergencyCallbackModeRegistrant != null) {
- riljLog("responseCallList: call ended, testing emergency call," +
- " notify ECM Registrants");
- mEmergencyCallbackModeRegistrant.notifyRegistrant();
- }
- }
-
- return response;
- }
-
- private DataCallState getDataCallState(Parcel p, int version) {
- DataCallState dataCall = new DataCallState();
-
- dataCall.version = version;
- if (version < 5) {
- dataCall.cid = p.readInt();
- dataCall.active = p.readInt();
- dataCall.type = p.readString();
- String addresses = p.readString();
- if (!TextUtils.isEmpty(addresses)) {
- dataCall.addresses = addresses.split(" ");
- }
- } else {
- dataCall.status = p.readInt();
- dataCall.suggestedRetryTime = p.readInt();
- dataCall.cid = p.readInt();
- dataCall.active = p.readInt();
- dataCall.type = p.readString();
- dataCall.ifname = p.readString();
- if ((dataCall.status == DataConnection.FailCause.NONE.getErrorCode()) &&
- TextUtils.isEmpty(dataCall.ifname)) {
- throw new RuntimeException("getDataCallState, no ifname");
- }
- String addresses = p.readString();
- if (!TextUtils.isEmpty(addresses)) {
- dataCall.addresses = addresses.split(" ");
- }
- String dnses = p.readString();
- if (!TextUtils.isEmpty(dnses)) {
- dataCall.dnses = dnses.split(" ");
- }
- String gateways = p.readString();
- if (!TextUtils.isEmpty(gateways)) {
- dataCall.gateways = gateways.split(" ");
- }
- }
- return dataCall;
- }
-
- private Object
- responseDataCallList(Parcel p) {
- ArrayList<DataCallState> response;
-
- int ver = p.readInt();
- int num = p.readInt();
- riljLog("responseDataCallList ver=" + ver + " num=" + num);
-
- response = new ArrayList<DataCallState>(num);
- for (int i = 0; i < num; i++) {
- response.add(getDataCallState(p, ver));
- }
-
- return response;
- }
-
- private Object
- responseSetupDataCall(Parcel p) {
- int ver = p.readInt();
- int num = p.readInt();
- if (RILJ_LOGV) riljLog("responseSetupDataCall ver=" + ver + " num=" + num);
-
- DataCallState dataCall;
-
- if (ver < 5) {
- dataCall = new DataCallState();
- dataCall.version = ver;
- dataCall.cid = Integer.parseInt(p.readString());
- dataCall.ifname = p.readString();
- if (TextUtils.isEmpty(dataCall.ifname)) {
- throw new RuntimeException(
- "RIL_REQUEST_SETUP_DATA_CALL response, no ifname");
- }
- String addresses = p.readString();
- if (!TextUtils.isEmpty(addresses)) {
- dataCall.addresses = addresses.split(" ");
- }
- if (num >= 4) {
- String dnses = p.readString();
- if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses);
- if (!TextUtils.isEmpty(dnses)) {
- dataCall.dnses = dnses.split(" ");
- }
- }
- if (num >= 5) {
- String gateways = p.readString();
- if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways);
- if (!TextUtils.isEmpty(gateways)) {
- dataCall.gateways = gateways.split(" ");
- }
- }
- } else {
- if (num != 1) {
- throw new RuntimeException(
- "RIL_REQUEST_SETUP_DATA_CALL response expecting 1 RIL_Data_Call_response_v5"
- + " got " + num);
- }
- dataCall = getDataCallState(p, ver);
- }
-
- return dataCall;
- }
-
- private Object
- responseOperatorInfos(Parcel p) {
- String strings[] = (String [])responseStrings(p);
- ArrayList<OperatorInfo> ret;
-
- if (strings.length % 4 != 0) {
- throw new RuntimeException(
- "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got "
- + strings.length + " strings, expected multible of 4");
- }
-
- ret = new ArrayList<OperatorInfo>(strings.length / 4);
-
- for (int i = 0 ; i < strings.length ; i += 4) {
- ret.add (
- new OperatorInfo(
- strings[i+0],
- strings[i+1],
- strings[i+2],
- strings[i+3]));
- }
-
- return ret;
- }
-
- private Object
- responseCellList(Parcel p) {
- int num, rssi;
- String location;
- ArrayList<NeighboringCellInfo> response;
- NeighboringCellInfo cell;
-
- num = p.readInt();
- response = new ArrayList<NeighboringCellInfo>();
-
- // Determine the radio access type
- String radioString = SystemProperties.get(
- TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, "unknown");
- int radioType;
- if (radioString.equals("GPRS")) {
- radioType = NETWORK_TYPE_GPRS;
- } else if (radioString.equals("EDGE")) {
- radioType = NETWORK_TYPE_EDGE;
- } else if (radioString.equals("UMTS")) {
- radioType = NETWORK_TYPE_UMTS;
- } else if (radioString.equals("HSDPA")) {
- radioType = NETWORK_TYPE_HSDPA;
- } else if (radioString.equals("HSUPA")) {
- radioType = NETWORK_TYPE_HSUPA;
- } else if (radioString.equals("HSPA")) {
- radioType = NETWORK_TYPE_HSPA;
- } else {
- radioType = NETWORK_TYPE_UNKNOWN;
- }
-
- // Interpret the location based on radio access type
- if (radioType != NETWORK_TYPE_UNKNOWN) {
- for (int i = 0 ; i < num ; i++) {
- rssi = p.readInt();
- location = p.readString();
- cell = new NeighboringCellInfo(rssi, location, radioType);
- response.add(cell);
- }
- }
- return response;
- }
-
- private Object responseGetPreferredNetworkType(Parcel p) {
- int [] response = (int[]) responseInts(p);
-
- if (response.length >= 1) {
- // Since this is the response for getPreferredNetworkType
- // we'll assume that it should be the value we want the
- // vendor ril to take if we reestablish a connection to it.
- mPreferredNetworkType = response[0];
- }
- return response;
- }
-
- private Object responseGmsBroadcastConfig(Parcel p) {
- int num;
- ArrayList<SmsBroadcastConfigInfo> response;
- SmsBroadcastConfigInfo info;
-
- num = p.readInt();
- response = new ArrayList<SmsBroadcastConfigInfo>(num);
-
- for (int i = 0; i < num; i++) {
- int fromId = p.readInt();
- int toId = p.readInt();
- int fromScheme = p.readInt();
- int toScheme = p.readInt();
- boolean selected = (p.readInt() == 1);
-
- info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme,
- toScheme, selected);
- response.add(info);
- }
- return response;
- }
-
- private Object
- responseCdmaBroadcastConfig(Parcel p) {
- int numServiceCategories;
- int response[];
-
- numServiceCategories = p.readInt();
-
- if (numServiceCategories == 0) {
- // TODO: The logic of providing default values should
- // not be done by this transport layer. And needs to
- // be done by the vendor ril or application logic.
- int numInts;
- numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
- response = new int[numInts];
-
- // Faking a default record for all possible records.
- response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
-
- // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
- // default language and selection status to false for all.
- for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) {
- response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT;
- response[i + 1] = 1;
- response[i + 2] = 0;
- }
- } else {
- int numInts;
- numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
- response = new int[numInts];
-
- response[0] = numServiceCategories;
- for (int i = 1 ; i < numInts; i++) {
- response[i] = p.readInt();
- }
- }
-
- return response;
- }
-
- private Object
- responseSignalStrength(Parcel p) {
- int numInts = 12;
- int response[];
-
- /* TODO: Add SignalStrength class to match RIL_SignalStrength */
- response = new int[numInts];
- for (int i = 0 ; i < numInts ; i++) {
- response[i] = p.readInt();
- }
-
- return response;
- }
-
- private ArrayList<CdmaInformationRecords>
- responseCdmaInformationRecord(Parcel p) {
- int numberOfInfoRecs;
- ArrayList<CdmaInformationRecords> response;
-
- /**
- * Loop through all of the information records unmarshalling them
- * and converting them to Java Objects.
- */
- numberOfInfoRecs = p.readInt();
- response = new ArrayList<CdmaInformationRecords>(numberOfInfoRecs);
-
- for (int i = 0; i < numberOfInfoRecs; i++) {
- CdmaInformationRecords InfoRec = new CdmaInformationRecords(p);
- response.add(InfoRec);
- }
-
- return response;
- }
-
- private Object
- responseCdmaCallWaiting(Parcel p) {
- CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
-
- notification.number = p.readString();
- notification.numberPresentation = notification.presentationFromCLIP(p.readInt());
- notification.name = p.readString();
- notification.namePresentation = notification.numberPresentation;
- notification.isPresent = p.readInt();
- notification.signalType = p.readInt();
- notification.alertPitch = p.readInt();
- notification.signal = p.readInt();
- notification.numberType = p.readInt();
- notification.numberPlan = p.readInt();
-
- return notification;
- }
-
- private Object
- responseCallRing(Parcel p){
- char response[] = new char[4];
-
- response[0] = (char) p.readInt(); // isPresent
- response[1] = (char) p.readInt(); // signalType
- response[2] = (char) p.readInt(); // alertPitch
- response[3] = (char) p.readInt(); // signal
-
- return response;
- }
-
- private void
- notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
- int response = RIL_UNSOL_CDMA_INFO_REC;
- if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
- if (mDisplayInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
- mDisplayInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.record, null));
- }
- } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
- if (mSignalInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
- mSignalInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.record, null));
- }
- } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
- if (mNumberInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
- mNumberInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.record, null));
- }
- } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
- if (mRedirNumInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
- mRedirNumInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.record, null));
- }
- } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
- if (mLineControlInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
- mLineControlInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.record, null));
- }
- } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
- if (mT53ClirInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
- mT53ClirInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.record, null));
- }
- } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
- if (mT53AudCntrlInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
- mT53AudCntrlInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.record, null));
- }
- }
- }
-
- static String
- requestToString(int request) {
-/*
- cat libs/telephony/ril_commands.h \
- | egrep "^ *{RIL_" \
- | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
-*/
- switch(request) {
- case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
- case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
- case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
- case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
- case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
- case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
- case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
- case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
- case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
- case RIL_REQUEST_DIAL: return "DIAL";
- case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
- case RIL_REQUEST_HANGUP: return "HANGUP";
- case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
- case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
- case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
- case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
- case RIL_REQUEST_UDUB: return "UDUB";
- case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
- case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
- case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
- case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
- case RIL_REQUEST_OPERATOR: return "OPERATOR";
- case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
- case RIL_REQUEST_DTMF: return "DTMF";
- case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
- case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
- case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
- case RIL_REQUEST_SIM_IO: return "SIM_IO";
- case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
- case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
- case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
- case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
- case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
- case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
- case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
- case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
- case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
- case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
- case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
- case RIL_REQUEST_ANSWER: return "ANSWER";
- case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
- case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
- case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
- case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
- case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
- case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
- case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
- case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS ";
- case RIL_REQUEST_DTMF_START: return "DTMF_START";
- case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
- case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
- case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
- case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
- case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
- case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
- case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
- case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
- case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
- case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
- case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
- case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
- case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION";
- case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
- case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM";
- case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
- case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
- case RIL_REQUEST_STK_GET_PROFILE: return "REQUEST_STK_GET_PROFILE";
- case RIL_REQUEST_STK_SET_PROFILE: return "REQUEST_STK_SET_PROFILE";
- case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "REQUEST_STK_SEND_ENVELOPE_COMMAND";
- case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "REQUEST_STK_SEND_TERMINAL_RESPONSE";
- case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
- case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER";
- case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "REQUEST_SET_PREFERRED_NETWORK_TYPE";
- case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
- case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS";
- case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES";
- case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
- case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
- case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
- case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE";
- case RIL_REQUEST_QUERY_TTY_MODE: return "RIL_REQUEST_QUERY_TTY_MODE";
- case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
- case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
- case RIL_REQUEST_CDMA_FLASH: return "RIL_REQUEST_CDMA_FLASH";
- case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF";
- case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS";
- case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
- case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
- case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
- case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
- case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
- case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
- case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
- case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
- case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
- case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
- case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM";
- case RIL_REQUEST_DEVICE_IDENTITY: return "RIL_REQUEST_DEVICE_IDENTITY";
- case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS";
- case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS";
- case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
- case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
- case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
- case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
- case RIL_REQUEST_ISIM_AUTHENTICATION: return "RIL_REQUEST_ISIM_AUTHENTICATION";
- case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
- case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
- case RIL_REQUEST_VOICE_RADIO_TECH: return "RIL_REQUEST_VOICE_RADIO_TECH";
- default: return "<unknown request>";
- }
- }
-
- static String
- responseToString(int request)
- {
-/*
- cat libs/telephony/ril_unsol_commands.h \
- | egrep "^ *{RIL_" \
- | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
-*/
- switch(request) {
- case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
- case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
- case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
- case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
- case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
- case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
- case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
- case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST";
- case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
- case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
- case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
- case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
- case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
- case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
- case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
- case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
- case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL";
- case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
- case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
- case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
- case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS";
- case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
- case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
- case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
- case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
- case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
- case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
- case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
- case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
- case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
- case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
- case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "CDMA_SUBSCRIPTION_SOURCE_CHANGED";
- case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
- case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
- case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
- case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
- default: return "<unknown reponse>";
- }
- }
-
- private void riljLog(String msg) {
- Log.d(LOG_TAG, msg);
- }
-
- private void riljLogv(String msg) {
- Log.v(LOG_TAG, msg);
- }
-
- private void unsljLog(int response) {
- riljLog("[UNSL]< " + responseToString(response));
- }
-
- private void unsljLogMore(int response, String more) {
- riljLog("[UNSL]< " + responseToString(response) + " " + more);
- }
-
- private void unsljLogRet(int response, Object ret) {
- riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
- }
-
- private void unsljLogvRet(int response, Object ret) {
- riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
- }
-
-
- // ***** Methods for CDMA support
- public void
- getDeviceIdentity(Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_DEVICE_IDENTITY, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void
- getCDMASubscription(Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SUBSCRIPTION, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- @Override
- public void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructor
- if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
- mPhoneType = phoneType;
- }
-
- /**
- * {@inheritDoc}
- */
- public void queryCdmaRoamingPreference(Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(cdmaRoamingType);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " : " + cdmaRoamingType);
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(cdmaSubscription);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " : " + cdmaSubscription);
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void getCdmaSubscriptionSource(Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void queryTTYMode(Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void setTTYMode(int ttyMode, Message response) {
- RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_SET_TTY_MODE, response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(ttyMode);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " : " + ttyMode);
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void
- sendCDMAFeatureCode(String FeatureCode, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response);
-
- rr.mp.writeString(FeatureCode);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + " : " + FeatureCode);
-
- send(rr);
- }
-
- public void getCdmaBroadcastConfig(Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, response);
-
- send(rr);
- }
-
- // TODO: Change the configValuesArray to a RIL_BroadcastSMSConfig
- public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, response);
-
- for(int i = 0; i < configValuesArray.length; i++) {
- rr.mp.writeInt(configValuesArray[i]);
- }
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void setCdmaBroadcastActivation(boolean activate, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response);
-
- rr.mp.writeInt(1);
- rr.mp.writeInt(activate ? 0 :1);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /**
- * {@inheritDoc}
- */
- public void exitEmergencyCallbackMode(Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, response);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- public void requestIsimAuthentication(String nonce, Message response) {
- RILRequest rr = RILRequest.obtain(RIL_REQUEST_ISIM_AUTHENTICATION, response);
-
- rr.mp.writeString(nonce);
-
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- send(rr);
- }
-
- /* (non-Javadoc)
- * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall()
- */
- @Override
- public void testingEmergencyCall() {
- if (RILJ_LOGD) riljLog("testingEmergencyCall");
- mTestingEmergencyCall.set(true);
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("RIL:");
- pw.println(" mSocket=" + mSocket);
- pw.println(" mSenderThread=" + mSenderThread);
- pw.println(" mSender=" + mSender);
- pw.println(" mReceiverThread=" + mReceiverThread);
- pw.println(" mReceiver=" + mReceiver);
- pw.println(" mWakeLock=" + mWakeLock);
- pw.println(" mWakeLockTimeout=" + mWakeLockTimeout);
- synchronized (mRequestsList) {
- pw.println(" mRequestMessagesPending=" + mRequestMessagesPending);
- pw.println(" mRequestMessagesWaiting=" + mRequestMessagesWaiting);
- int count = mRequestsList.size();
- pw.println(" mRequestList count=" + count);
- for (int i = 0; i < count; i++) {
- RILRequest rr = mRequestsList.get(i);
- pw.println(" [" + rr.mSerial + "] " + requestToString(rr.mRequest));
- }
- }
- pw.println(" mLastNITZTimeInfo=" + mLastNITZTimeInfo);
- pw.println(" mTestingEmergencyCall=" + mTestingEmergencyCall.get());
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/RestrictedState.java b/telephony/java/com/android/internal/telephony/RestrictedState.java
deleted file mode 100644
index ad2b88d..0000000
--- a/telephony/java/com/android/internal/telephony/RestrictedState.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.telephony.ServiceState;
-
-public class RestrictedState {
-
- /**
- * Set true to block packet data access due to restriction
- */
- private boolean mPsRestricted;
- /**
- * Set true to block all normal voice/SMS/USSD/SS/AV64 due to restriction
- */
- private boolean mCsNormalRestricted;
- /**
- * Set true to block emergency call due to restriction
- */
- private boolean mCsEmergencyRestricted;
-
- public RestrictedState() {
- setPsRestricted(false);
- setCsNormalRestricted(false);
- setCsEmergencyRestricted(false);
- }
-
- /**
- * @param csEmergencyRestricted the csEmergencyRestricted to set
- */
- public void setCsEmergencyRestricted(boolean csEmergencyRestricted) {
- mCsEmergencyRestricted = csEmergencyRestricted;
- }
-
- /**
- * @return the csEmergencyRestricted
- */
- public boolean isCsEmergencyRestricted() {
- return mCsEmergencyRestricted;
- }
-
- /**
- * @param csNormalRestricted the csNormalRestricted to set
- */
- public void setCsNormalRestricted(boolean csNormalRestricted) {
- mCsNormalRestricted = csNormalRestricted;
- }
-
- /**
- * @return the csNormalRestricted
- */
- public boolean isCsNormalRestricted() {
- return mCsNormalRestricted;
- }
-
- /**
- * @param psRestricted the psRestricted to set
- */
- public void setPsRestricted(boolean psRestricted) {
- mPsRestricted = psRestricted;
- }
-
- /**
- * @return the psRestricted
- */
- public boolean isPsRestricted() {
- return mPsRestricted;
- }
-
- public boolean isCsRestricted() {
- return mCsNormalRestricted && mCsEmergencyRestricted;
- }
-
- @Override
- public boolean equals (Object o) {
- RestrictedState s;
-
- try {
- s = (RestrictedState) o;
- } catch (ClassCastException ex) {
- return false;
- }
-
- if (o == null) {
- return false;
- }
-
- return mPsRestricted == s.mPsRestricted
- && mCsNormalRestricted == s.mCsNormalRestricted
- && mCsEmergencyRestricted == s.mCsEmergencyRestricted;
- }
-
- @Override
- public String toString() {
- String csString = "none";
-
- if (mCsEmergencyRestricted && mCsNormalRestricted) {
- csString = "all";
- } else if (mCsEmergencyRestricted && !mCsNormalRestricted) {
- csString = "emergency";
- } else if (!mCsEmergencyRestricted && mCsNormalRestricted) {
- csString = "normal call";
- }
-
- return "Restricted State CS: " + csString + " PS:" + mPsRestricted;
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/RetryManager.java b/telephony/java/com/android/internal/telephony/RetryManager.java
deleted file mode 100644
index 250d99e..0000000
--- a/telephony/java/com/android/internal/telephony/RetryManager.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/**
- * Copyright (C) 2009 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.util.Log;
-import android.util.Pair;
-import android.text.TextUtils;
-
-import java.util.Random;
-import java.util.ArrayList;
-
-/**
- * Retry manager allows a simple way to declare a series of
- * retry timeouts. After creating a RetryManager the configure
- * method is used to define the sequence. A simple linear series
- * may be initialized using configure with three integer parameters
- * The other configure method allows a series to be declared using
- * a string.
- *<p>
- * The format of the configuration string is a series of parameters
- * separated by a comma. There are two name value pair parameters plus a series
- * of delay times. The units of of these delay times is unspecified.
- * The name value pairs which may be specified are:
- *<ul>
- *<li>max_retries=<value>
- *<li>default_randomizationTime=<value>
- *</ul>
- *<p>
- * max_retries is the number of times that incrementRetryCount
- * maybe called before isRetryNeeded will return false. if value
- * is infinite then isRetryNeeded will always return true.
- *
- * default_randomizationTime will be used as the randomizationTime
- * for delay times which have no supplied randomizationTime. If
- * default_randomizationTime is not defined it defaults to 0.
- *<p>
- * The other parameters define The series of delay times and each
- * may have an optional randomization value separated from the
- * delay time by a colon.
- *<p>
- * Examples:
- * <ul>
- * <li>3 retries with no randomization value which means its 0:
- * <ul><li><code>"1000, 2000, 3000"</code></ul>
- *
- * <li>10 retries with a 500 default randomization value for each and
- * the 4..10 retries all using 3000 as the delay:
- * <ul><li><code>"max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul>
- *
- * <li>4 retries with a 100 as the default randomization value for the first 2 values and
- * the other two having specified values of 500:
- * <ul><li><code>"default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul>
- *
- * <li>Infinite number of retries with the first one at 1000, the second at 2000 all
- * others will be at 3000.
- * <ul><li><code>"max_retries=infinite,1000,2000,3000</code></ul>
- * </ul>
- *
- * {@hide}
- */
-public class RetryManager {
- static public final String LOG_TAG = "GSM";
- static public final boolean DBG = true;
- static public final boolean VDBG = false;
-
- /**
- * Retry record with times in milli-seconds
- */
- private static class RetryRec {
- RetryRec(int delayTime, int randomizationTime) {
- mDelayTime = delayTime;
- mRandomizationTime = randomizationTime;
- }
-
- int mDelayTime;
- int mRandomizationTime;
- }
-
- /** The array of retry records */
- private ArrayList<RetryRec> mRetryArray = new ArrayList<RetryRec>();
-
- /** When true isRetryNeeded() will always return true */
- private boolean mRetryForever;
-
- /**
- * The maximum number of retries to attempt before
- * isRetryNeeded returns false
- */
- private int mMaxRetryCount;
-
- /** The current number of retries */
- private int mRetryCount;
-
- /** Random number generator */
- private Random rng = new Random();
-
- private String mConfig;
-
- /** Constructor */
- public RetryManager() {
- if (VDBG) log("constructor");
- }
-
- public String toString() {
- String ret = "RetryManager: forever=" + mRetryForever + ", maxRetry=" + mMaxRetryCount +
- ", retry=" + mRetryCount + ",\n " + mConfig;
- for (RetryRec r : mRetryArray) {
- ret += "\n " + r.mDelayTime + ":" + r.mRandomizationTime;
- }
- return ret;
- }
-
- /**
- * Configure for a simple linear sequence of times plus
- * a random value.
- *
- * @param maxRetryCount is the maximum number of retries
- * before isRetryNeeded returns false.
- * @param retryTime is a time that will be returned by getRetryTime.
- * @param randomizationTime a random value between 0 and
- * randomizationTime will be added to retryTime. this
- * parameter may be 0.
- * @return true if successful
- */
- public boolean configure(int maxRetryCount, int retryTime, int randomizationTime) {
- Pair<Boolean, Integer> value;
-
- if (VDBG) log("configure: " + maxRetryCount + ", " + retryTime + "," + randomizationTime);
-
- if (!validateNonNegativeInt("maxRetryCount", maxRetryCount)) {
- return false;
- }
-
- if (!validateNonNegativeInt("retryTime", retryTime)) {
- return false;
- }
-
- if (!validateNonNegativeInt("randomizationTime", randomizationTime)) {
- return false;
- }
-
- mMaxRetryCount = maxRetryCount;
- resetRetryCount();
- mRetryArray.clear();
- mRetryArray.add(new RetryRec(retryTime, randomizationTime));
-
- return true;
- }
-
- /**
- * Configure for using string which allow arbitrary
- * sequences of times. See class comments for the
- * string format.
- *
- * @return true if successful
- */
- public boolean configure(String configStr) {
- // Strip quotes if present.
- if ((configStr.startsWith("\"") && configStr.endsWith("\""))) {
- configStr = configStr.substring(1, configStr.length()-1);
- }
- if (VDBG) log("configure: '" + configStr + "'");
- mConfig = configStr;
-
- if (!TextUtils.isEmpty(configStr)) {
- int defaultRandomization = 0;
-
- if (VDBG) log("configure: not empty");
-
- mMaxRetryCount = 0;
- resetRetryCount();
- mRetryArray.clear();
-
- String strArray[] = configStr.split(",");
- for (int i = 0; i < strArray.length; i++) {
- if (VDBG) log("configure: strArray[" + i + "]='" + strArray[i] + "'");
- Pair<Boolean, Integer> value;
- String splitStr[] = strArray[i].split("=", 2);
- splitStr[0] = splitStr[0].trim();
- if (VDBG) log("configure: splitStr[0]='" + splitStr[0] + "'");
- if (splitStr.length > 1) {
- splitStr[1] = splitStr[1].trim();
- if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
- if (TextUtils.equals(splitStr[0], "default_randomization")) {
- value = parseNonNegativeInt(splitStr[0], splitStr[1]);
- if (!value.first) return false;
- defaultRandomization = value.second;
- } else if (TextUtils.equals(splitStr[0], "max_retries")) {
- if (TextUtils.equals("infinite",splitStr[1])) {
- mRetryForever = true;
- } else {
- value = parseNonNegativeInt(splitStr[0], splitStr[1]);
- if (!value.first) return false;
- mMaxRetryCount = value.second;
- }
- } else {
- Log.e(LOG_TAG, "Unrecognized configuration name value pair: "
- + strArray[i]);
- return false;
- }
- } else {
- /**
- * Assume a retry time with an optional randomization value
- * following a ":"
- */
- splitStr = strArray[i].split(":", 2);
- splitStr[0] = splitStr[0].trim();
- RetryRec rr = new RetryRec(0, 0);
- value = parseNonNegativeInt("delayTime", splitStr[0]);
- if (!value.first) return false;
- rr.mDelayTime = value.second;
-
- // Check if optional randomization value present
- if (splitStr.length > 1) {
- splitStr[1] = splitStr[1].trim();
- if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
- value = parseNonNegativeInt("randomizationTime", splitStr[1]);
- if (!value.first) return false;
- rr.mRandomizationTime = value.second;
- } else {
- rr.mRandomizationTime = defaultRandomization;
- }
- mRetryArray.add(rr);
- }
- }
- if (mRetryArray.size() > mMaxRetryCount) {
- mMaxRetryCount = mRetryArray.size();
- if (VDBG) log("configure: setting mMaxRetryCount=" + mMaxRetryCount);
- }
- if (VDBG) log("configure: true");
- return true;
- } else {
- if (VDBG) log("configure: false it's empty");
- return false;
- }
- }
-
- /**
- * Report whether data reconnection should be retried
- *
- * @return {@code true} if the max retries has not been reached. {@code
- * false} otherwise.
- */
- public boolean isRetryNeeded() {
- boolean retVal = mRetryForever || (mRetryCount < mMaxRetryCount);
- if (DBG) log("isRetryNeeded: " + retVal);
- return retVal;
- }
-
- /**
- * Return the timer that should be used to trigger the data reconnection
- */
- public int getRetryTimer() {
- int index;
- if (mRetryCount < mRetryArray.size()) {
- index = mRetryCount;
- } else {
- index = mRetryArray.size() - 1;
- }
-
- int retVal;
- if ((index >= 0) && (index < mRetryArray.size())) {
- retVal = mRetryArray.get(index).mDelayTime + nextRandomizationTime(index);
- } else {
- retVal = 0;
- }
-
- if (DBG) log("getRetryTimer: " + retVal);
- return retVal;
- }
-
- /**
- * @return retry count
- */
- public int getRetryCount() {
- if (DBG) log("getRetryCount: " + mRetryCount);
- return mRetryCount;
- }
-
- /**
- * Increase the retry counter, does not change retry forever.
- */
- public void increaseRetryCount() {
- mRetryCount++;
- if (mRetryCount > mMaxRetryCount) {
- mRetryCount = mMaxRetryCount;
- }
- if (DBG) log("increaseRetryCount: " + mRetryCount);
- }
-
- /**
- * Set retry count to the specified value
- */
- public void setRetryCount(int count) {
- mRetryCount = count;
- if (mRetryCount > mMaxRetryCount) {
- mRetryCount = mMaxRetryCount;
- }
-
- if (mRetryCount < 0) {
- mRetryCount = 0;
- }
-
- if (DBG) log("setRetryCount: " + mRetryCount);
- }
-
- /**
- * Set retry forever to the specified value
- */
- public void setRetryForever(boolean retryForever) {
- mRetryForever = retryForever;
- if (DBG) log("setRetryForever: " + mRetryForever);
- }
-
- /**
- * Clear the data-retry counter
- */
- public void resetRetryCount() {
- mRetryCount = 0;
- if (DBG) log("resetRetryCount: " + mRetryCount);
- }
-
- /**
- * Retry forever using last timeout time.
- */
- public void retryForeverUsingLastTimeout() {
- mRetryCount = mMaxRetryCount;
- mRetryForever = true;
- if (DBG) log("retryForeverUsingLastTimeout: " + mRetryForever + ", " + mRetryCount);
- }
-
- /**
- * @return true if retrying forever
- */
- public boolean isRetryForever() {
- if (DBG) log("isRetryForever: " + mRetryForever);
- return mRetryForever;
- }
-
- /**
- * Parse an integer validating the value is not negative.
- *
- * @param name
- * @param stringValue
- * @return Pair.first == true if stringValue an integer >= 0
- */
- private Pair<Boolean, Integer> parseNonNegativeInt(String name, String stringValue) {
- int value;
- Pair<Boolean, Integer> retVal;
- try {
- value = Integer.parseInt(stringValue);
- retVal = new Pair<Boolean, Integer>(validateNonNegativeInt(name, value), value);
- } catch (NumberFormatException e) {
- Log.e(LOG_TAG, name + " bad value: " + stringValue, e);
- retVal = new Pair<Boolean, Integer>(false, 0);
- }
- if (VDBG) log("parseNonNetativeInt: " + name + ", " + stringValue + ", "
- + retVal.first + ", " + retVal.second);
- return retVal;
- }
-
- /**
- * Validate an integer is >= 0 and logs an error if not
- *
- * @param name
- * @param value
- * @return Pair.first
- */
- private boolean validateNonNegativeInt(String name, int value) {
- boolean retVal;
- if (value < 0) {
- Log.e(LOG_TAG, name + " bad value: is < 0");
- retVal = false;
- } else {
- retVal = true;
- }
- if (VDBG) log("validateNonNegative: " + name + ", " + value + ", " + retVal);
- return retVal;
- }
-
- /**
- * Return next random number for the index
- */
- private int nextRandomizationTime(int index) {
- int randomTime = mRetryArray.get(index).mRandomizationTime;
- if (randomTime == 0) {
- return 0;
- } else {
- return rng.nextInt(randomTime);
- }
- }
-
- private void log(String s) {
- Log.d(LOG_TAG, "[RM] " + s);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
deleted file mode 100644
index 40c22a7..0000000
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ /dev/null
@@ -1,1169 +0,0 @@
-/*
- * 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.Activity;
-import android.app.AlertDialog;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.provider.Telephony;
-import android.provider.Telephony.Sms.Intents;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.SmsCbMessage;
-import android.telephony.SmsMessage;
-import android.telephony.TelephonyManager;
-import android.text.Html;
-import android.text.Spanned;
-import android.util.Log;
-import android.view.WindowManager;
-
-import com.android.internal.R;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.util.HexDump;
-
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Random;
-
-import static android.telephony.SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE;
-import static android.telephony.SmsManager.RESULT_ERROR_GENERIC_FAILURE;
-import static android.telephony.SmsManager.RESULT_ERROR_LIMIT_EXCEEDED;
-import static android.telephony.SmsManager.RESULT_ERROR_NO_SERVICE;
-import static android.telephony.SmsManager.RESULT_ERROR_NULL_PDU;
-import static android.telephony.SmsManager.RESULT_ERROR_RADIO_OFF;
-
-public abstract class SMSDispatcher extends Handler {
- static final String TAG = "SMS"; // accessed from inner class
- private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg";
-
- /** Permission required to receive SMS and SMS-CB messages. */
- public static final String RECEIVE_SMS_PERMISSION = "android.permission.RECEIVE_SMS";
-
- /** Permission required to receive ETWS and CMAS emergency broadcasts. */
- public static final String RECEIVE_EMERGENCY_BROADCAST_PERMISSION =
- "android.permission.RECEIVE_EMERGENCY_BROADCAST";
-
- /** Permission required to send SMS to short codes without user confirmation. */
- private static final String SEND_SMS_NO_CONFIRMATION_PERMISSION =
- "android.permission.SEND_SMS_NO_CONFIRMATION";
-
- /** Query projection for checking for duplicate message segments. */
- private static final String[] PDU_PROJECTION = new String[] {
- "pdu"
- };
-
- /** Query projection for combining concatenated message segments. */
- private static final String[] PDU_SEQUENCE_PORT_PROJECTION = new String[] {
- "pdu",
- "sequence",
- "destination_port"
- };
-
- private static final int PDU_COLUMN = 0;
- private static final int SEQUENCE_COLUMN = 1;
- private static final int DESTINATION_PORT_COLUMN = 2;
-
- /** New SMS received. */
- protected static final int EVENT_NEW_SMS = 1;
-
- /** SMS send complete. */
- protected static final int EVENT_SEND_SMS_COMPLETE = 2;
-
- /** Retry sending a previously failed SMS message */
- private static final int EVENT_SEND_RETRY = 3;
-
- /** Confirmation required for sending a large number of messages. */
- private static final int EVENT_SEND_LIMIT_REACHED_CONFIRMATION = 4;
-
- /** Send the user confirmed SMS */
- static final int EVENT_SEND_CONFIRMED_SMS = 5; // accessed from inner class
-
- /** Don't send SMS (user did not confirm). */
- static final int EVENT_STOP_SENDING = 7; // accessed from inner class
-
- protected final Phone mPhone;
- protected final Context mContext;
- protected final ContentResolver mResolver;
- protected final CommandsInterface mCm;
- protected final SmsStorageMonitor mStorageMonitor;
- protected final TelephonyManager mTelephonyManager;
-
- protected final WapPushOverSms mWapPush;
-
- protected static final Uri mRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw");
-
- /** Maximum number of times to retry sending a failed SMS. */
- private static final int MAX_SEND_RETRIES = 3;
- /** Delay before next send attempt on a failed SMS, in milliseconds. */
- private static final int SEND_RETRY_DELAY = 2000;
- /** single part SMS */
- private static final int SINGLE_PART_SMS = 1;
- /** Message sending queue limit */
- private static final int MO_MSG_QUEUE_LIMIT = 5;
-
- /**
- * Message reference for a CONCATENATED_8_BIT_REFERENCE or
- * CONCATENATED_16_BIT_REFERENCE message set. Should be
- * incremented for each set of concatenated messages.
- * Static field shared by all dispatcher objects.
- */
- private static int sConcatenatedRef = new Random().nextInt(256);
-
- /** Outgoing message counter. Shared by all dispatchers. */
- private final SmsUsageMonitor mUsageMonitor;
-
- /** Number of outgoing SmsTrackers waiting for user confirmation. */
- private int mPendingTrackerCount;
-
- /** Wake lock to ensure device stays awake while dispatching the SMS intent. */
- private PowerManager.WakeLock mWakeLock;
-
- /**
- * Hold the wake lock for 5 seconds, which should be enough time for
- * any receiver(s) to grab its own wake lock.
- */
- private static final int WAKE_LOCK_TIMEOUT = 5000;
-
- /* Flags indicating whether the current device allows sms service */
- protected boolean mSmsCapable = true;
- protected boolean mSmsReceiveDisabled;
- protected boolean mSmsSendDisabled;
-
- protected int mRemainingMessages = -1;
-
- protected static int getNextConcatenatedRef() {
- sConcatenatedRef += 1;
- return sConcatenatedRef;
- }
-
- /**
- * Create a new SMS dispatcher.
- * @param phone the Phone to use
- * @param storageMonitor the SmsStorageMonitor to use
- * @param usageMonitor the SmsUsageMonitor to use
- */
- protected SMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor,
- SmsUsageMonitor usageMonitor) {
- mPhone = phone;
- mWapPush = new WapPushOverSms(phone, this);
- mContext = phone.getContext();
- mResolver = mContext.getContentResolver();
- mCm = phone.mCM;
- mStorageMonitor = storageMonitor;
- mUsageMonitor = usageMonitor;
- mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-
- createWakelock();
-
- mSmsCapable = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_sms_capable);
- mSmsReceiveDisabled = !SystemProperties.getBoolean(
- TelephonyProperties.PROPERTY_SMS_RECEIVE, mSmsCapable);
- mSmsSendDisabled = !SystemProperties.getBoolean(
- TelephonyProperties.PROPERTY_SMS_SEND, mSmsCapable);
- Log.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat()
- + " mSmsReceiveDisabled=" + mSmsReceiveDisabled
- + " mSmsSendDisabled=" + mSmsSendDisabled);
- }
-
- /** Unregister for incoming SMS events. */
- public abstract void dispose();
-
- /**
- * The format of the message PDU in the associated broadcast intent.
- * This will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format
- * or "3gpp2" for CDMA/LTE messages in 3GPP2 format.
- *
- * Note: All applications which handle incoming SMS messages by processing the
- * SMS_RECEIVED_ACTION broadcast intent MUST pass the "format" extra from the intent
- * into the new methods in {@link android.telephony.SmsMessage} which take an
- * extra format parameter. This is required in order to correctly decode the PDU on
- * devices which require support for both 3GPP and 3GPP2 formats at the same time,
- * such as CDMA/LTE devices and GSM/CDMA world phones.
- *
- * @return the format of the message PDU
- */
- protected abstract String getFormat();
-
- @Override
- protected void finalize() {
- Log.d(TAG, "SMSDispatcher finalized");
- }
-
-
- /* TODO: Need to figure out how to keep track of status report routing in a
- * persistent manner. If the phone process restarts (reboot or crash),
- * we will lose this list and any status reports that come in after
- * will be dropped.
- */
- /** Sent messages awaiting a delivery status report. */
- protected final ArrayList<SmsTracker> deliveryPendingList = new ArrayList<SmsTracker>();
-
- /**
- * Handles events coming from the phone stack. Overridden from handler.
- *
- * @param msg the message to handle
- */
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_NEW_SMS:
- // A new SMS has been received by the device
- if (false) {
- Log.d(TAG, "New SMS Message Received");
- }
-
- SmsMessage sms;
-
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception != null) {
- Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception);
- return;
- }
-
- sms = (SmsMessage) ar.result;
- try {
- int result = dispatchMessage(sms.mWrappedSmsMessage);
- if (result != Activity.RESULT_OK) {
- // RESULT_OK means that message was broadcast for app(s) to handle.
- // Any other result, we should ack here.
- boolean handled = (result == Intents.RESULT_SMS_HANDLED);
- notifyAndAcknowledgeLastIncomingSms(handled, result, null);
- }
- } catch (RuntimeException ex) {
- Log.e(TAG, "Exception dispatching message", ex);
- notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
- }
-
- break;
-
- case EVENT_SEND_SMS_COMPLETE:
- // An outbound SMS has been successfully transferred, or failed.
- handleSendComplete((AsyncResult) msg.obj);
- break;
-
- case EVENT_SEND_RETRY:
- sendSms((SmsTracker) msg.obj);
- break;
-
- case EVENT_SEND_LIMIT_REACHED_CONFIRMATION:
- handleReachSentLimit((SmsTracker)(msg.obj));
- break;
-
- case EVENT_SEND_CONFIRMED_SMS:
- {
- SmsTracker tracker = (SmsTracker) msg.obj;
- if (tracker.isMultipart()) {
- sendMultipartSms(tracker);
- } else {
- sendSms(tracker);
- }
- mPendingTrackerCount--;
- break;
- }
-
- case EVENT_STOP_SENDING:
- {
- SmsTracker tracker = (SmsTracker) msg.obj;
- if (tracker.mSentIntent != null) {
- try {
- tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED);
- } catch (CanceledException ex) {
- Log.e(TAG, "failed to send RESULT_ERROR_LIMIT_EXCEEDED");
- }
- }
- mPendingTrackerCount--;
- break;
- }
- }
- }
-
- private void createWakelock() {
- PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SMSDispatcher");
- mWakeLock.setReferenceCounted(true);
- }
-
- /**
- * Grabs a wake lock and sends intent as an ordered broadcast.
- * The resultReceiver will check for errors and ACK/NACK back
- * to the RIL.
- *
- * @param intent intent to broadcast
- * @param permission Receivers are required to have this permission
- */
- public void dispatch(Intent intent, String permission) {
- // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
- // receivers time to take their own wake locks.
- mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
- mContext.sendOrderedBroadcast(intent, permission, mResultReceiver,
- this, Activity.RESULT_OK, null, null);
- }
-
- /**
- * Grabs a wake lock and sends intent as an ordered broadcast.
- * Used for setting a custom result receiver for CDMA SCPD.
- *
- * @param intent intent to broadcast
- * @param permission Receivers are required to have this permission
- * @param resultReceiver the result receiver to use
- */
- public void dispatch(Intent intent, String permission, BroadcastReceiver resultReceiver) {
- // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
- // receivers time to take their own wake locks.
- mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
- mContext.sendOrderedBroadcast(intent, permission, resultReceiver,
- this, Activity.RESULT_OK, null, null);
- }
-
- /**
- * Called when SMS send completes. Broadcasts a sentIntent on success.
- * On failure, either sets up retries or broadcasts a sentIntent with
- * the failure in the result code.
- *
- * @param ar AsyncResult passed into the message handler. ar.result should
- * an SmsResponse instance if send was successful. ar.userObj
- * should be an SmsTracker instance.
- */
- protected void handleSendComplete(AsyncResult ar) {
- SmsTracker tracker = (SmsTracker) ar.userObj;
- PendingIntent sentIntent = tracker.mSentIntent;
-
- if (ar.exception == null) {
- if (false) {
- Log.d(TAG, "SMS send complete. Broadcasting "
- + "intent: " + sentIntent);
- }
-
- if (tracker.mDeliveryIntent != null) {
- // Expecting a status report. Add it to the list.
- int messageRef = ((SmsResponse)ar.result).messageRef;
- tracker.mMessageRef = messageRef;
- deliveryPendingList.add(tracker);
- }
-
- if (sentIntent != null) {
- try {
- if (mRemainingMessages > -1) {
- mRemainingMessages--;
- }
-
- if (mRemainingMessages == 0) {
- Intent sendNext = new Intent();
- sendNext.putExtra(SEND_NEXT_MSG_EXTRA, true);
- sentIntent.send(mContext, Activity.RESULT_OK, sendNext);
- } else {
- sentIntent.send(Activity.RESULT_OK);
- }
- } catch (CanceledException ex) {}
- }
- } else {
- if (false) {
- Log.d(TAG, "SMS send failed");
- }
-
- int ss = mPhone.getServiceState().getState();
-
- if (ss != ServiceState.STATE_IN_SERVICE) {
- handleNotInService(ss, tracker.mSentIntent);
- } else if ((((CommandException)(ar.exception)).getCommandError()
- == CommandException.Error.SMS_FAIL_RETRY) &&
- tracker.mRetryCount < MAX_SEND_RETRIES) {
- // Retry after a delay if needed.
- // TODO: According to TS 23.040, 9.2.3.6, we should resend
- // with the same TP-MR as the failed message, and
- // TP-RD set to 1. However, we don't have a means of
- // knowing the MR for the failed message (EF_SMSstatus
- // may or may not have the MR corresponding to this
- // message, depending on the failure). Also, in some
- // implementations this retry is handled by the baseband.
- tracker.mRetryCount++;
- Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker);
- sendMessageDelayed(retryMsg, SEND_RETRY_DELAY);
- } else if (tracker.mSentIntent != null) {
- int error = RESULT_ERROR_GENERIC_FAILURE;
-
- if (((CommandException)(ar.exception)).getCommandError()
- == CommandException.Error.FDN_CHECK_FAILURE) {
- error = RESULT_ERROR_FDN_CHECK_FAILURE;
- }
- // Done retrying; return an error to the app.
- try {
- Intent fillIn = new Intent();
- if (ar.result != null) {
- fillIn.putExtra("errorCode", ((SmsResponse)ar.result).errorCode);
- }
- if (mRemainingMessages > -1) {
- mRemainingMessages--;
- }
-
- if (mRemainingMessages == 0) {
- fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true);
- }
-
- tracker.mSentIntent.send(mContext, error, fillIn);
- } catch (CanceledException ex) {}
- }
- }
- }
-
- /**
- * Handles outbound message when the phone is not in service.
- *
- * @param ss Current service state. Valid values are:
- * OUT_OF_SERVICE
- * EMERGENCY_ONLY
- * POWER_OFF
- * @param sentIntent the PendingIntent to send the error to
- */
- protected static void handleNotInService(int ss, PendingIntent sentIntent) {
- if (sentIntent != null) {
- try {
- if (ss == ServiceState.STATE_POWER_OFF) {
- sentIntent.send(RESULT_ERROR_RADIO_OFF);
- } else {
- sentIntent.send(RESULT_ERROR_NO_SERVICE);
- }
- } catch (CanceledException ex) {}
- }
- }
-
- /**
- * Dispatches an incoming SMS messages.
- *
- * @param sms the incoming message from the phone
- * @return a result code from {@link Telephony.Sms.Intents}, or
- * {@link Activity#RESULT_OK} if the message has been broadcast
- * to applications
- */
- public abstract int dispatchMessage(SmsMessageBase sms);
-
- /**
- * Dispatch a normal incoming SMS. This is called from the format-specific
- * {@link #dispatchMessage(SmsMessageBase)} if no format-specific handling is required.
- *
- * @param sms
- * @return
- */
- protected int dispatchNormalMessage(SmsMessageBase sms) {
- SmsHeader smsHeader = sms.getUserDataHeader();
-
- // See if message is partial or port addressed.
- if ((smsHeader == null) || (smsHeader.concatRef == null)) {
- // Message is not partial (not part of concatenated sequence).
- byte[][] pdus = new byte[1][];
- pdus[0] = sms.getPdu();
-
- if (smsHeader != null && smsHeader.portAddrs != null) {
- if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
- // GSM-style WAP indication
- return mWapPush.dispatchWapPdu(sms.getUserData());
- } else {
- // The message was sent to a port, so concoct a URI for it.
- dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort);
- }
- } else {
- // Normal short and non-port-addressed message, dispatch it.
- dispatchPdus(pdus);
- }
- return Activity.RESULT_OK;
- } else {
- // Process the message part.
- SmsHeader.ConcatRef concatRef = smsHeader.concatRef;
- SmsHeader.PortAddrs portAddrs = smsHeader.portAddrs;
- return processMessagePart(sms.getPdu(), sms.getOriginatingAddress(),
- concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount,
- sms.getTimestampMillis(), (portAddrs != null ? portAddrs.destPort : -1), false);
- }
- }
-
- /**
- * If this is the last part send the parts out to the application, otherwise
- * the part is stored for later processing. Handles both 3GPP concatenated messages
- * as well as 3GPP2 format WAP push messages processed by
- * {@link com.android.internal.telephony.cdma.CdmaSMSDispatcher#processCdmaWapPdu}.
- *
- * @param pdu the message PDU, or the datagram portion of a CDMA WDP datagram segment
- * @param address the originating address
- * @param referenceNumber distinguishes concatenated messages from the same sender
- * @param sequenceNumber the order of this segment in the message
- * (starting at 0 for CDMA WDP datagrams and 1 for concatenated messages).
- * @param messageCount the number of segments in the message
- * @param timestamp the service center timestamp in millis
- * @param destPort the destination port for the message, or -1 for no destination port
- * @param isCdmaWapPush true if pdu is a CDMA WDP datagram segment and not an SM PDU
- *
- * @return a result code from {@link Telephony.Sms.Intents}, or
- * {@link Activity#RESULT_OK} if the message has been broadcast
- * to applications
- */
- protected int processMessagePart(byte[] pdu, String address, int referenceNumber,
- int sequenceNumber, int messageCount, long timestamp, int destPort,
- boolean isCdmaWapPush) {
- byte[][] pdus = null;
- Cursor cursor = null;
- try {
- // used by several query selection arguments
- String refNumber = Integer.toString(referenceNumber);
- String seqNumber = Integer.toString(sequenceNumber);
-
- // Check for duplicate message segment
- cursor = mResolver.query(mRawUri, PDU_PROJECTION,
- "address=? AND reference_number=? AND sequence=?",
- new String[] {address, refNumber, seqNumber}, null);
-
- // moveToNext() returns false if no duplicates were found
- if (cursor.moveToNext()) {
- Log.w(TAG, "Discarding duplicate message segment from address=" + address
- + " refNumber=" + refNumber + " seqNumber=" + seqNumber);
- String oldPduString = cursor.getString(PDU_COLUMN);
- byte[] oldPdu = HexDump.hexStringToByteArray(oldPduString);
- if (!Arrays.equals(oldPdu, pdu)) {
- Log.e(TAG, "Warning: dup message segment PDU of length " + pdu.length
- + " is different from existing PDU of length " + oldPdu.length);
- }
- return Intents.RESULT_SMS_HANDLED;
- }
- cursor.close();
-
- // not a dup, query for all other segments of this concatenated message
- String where = "address=? AND reference_number=?";
- String[] whereArgs = new String[] {address, refNumber};
- cursor = mResolver.query(mRawUri, PDU_SEQUENCE_PORT_PROJECTION, where, whereArgs, null);
-
- int cursorCount = cursor.getCount();
- if (cursorCount != messageCount - 1) {
- // We don't have all the parts yet, store this one away
- ContentValues values = new ContentValues();
- values.put("date", timestamp);
- values.put("pdu", HexDump.toHexString(pdu));
- values.put("address", address);
- values.put("reference_number", referenceNumber);
- values.put("count", messageCount);
- values.put("sequence", sequenceNumber);
- if (destPort != -1) {
- values.put("destination_port", destPort);
- }
- mResolver.insert(mRawUri, values);
- return Intents.RESULT_SMS_HANDLED;
- }
-
- // All the parts are in place, deal with them
- pdus = new byte[messageCount][];
- for (int i = 0; i < cursorCount; i++) {
- cursor.moveToNext();
- int cursorSequence = cursor.getInt(SEQUENCE_COLUMN);
- // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
- if (!isCdmaWapPush) {
- cursorSequence--;
- }
- pdus[cursorSequence] = HexDump.hexStringToByteArray(
- cursor.getString(PDU_COLUMN));
-
- // Read the destination port from the first segment (needed for CDMA WAP PDU).
- // It's not a bad idea to prefer the port from the first segment for 3GPP as well.
- if (cursorSequence == 0 && !cursor.isNull(DESTINATION_PORT_COLUMN)) {
- destPort = cursor.getInt(DESTINATION_PORT_COLUMN);
- }
- }
- // This one isn't in the DB, so add it
- // GSM sequence numbers start at 1; CDMA WDP datagram sequence numbers start at 0
- if (isCdmaWapPush) {
- pdus[sequenceNumber] = pdu;
- } else {
- pdus[sequenceNumber - 1] = pdu;
- }
-
- // Remove the parts from the database
- mResolver.delete(mRawUri, where, whereArgs);
- } catch (SQLException e) {
- Log.e(TAG, "Can't access multipart SMS database", e);
- return Intents.RESULT_SMS_GENERIC_ERROR;
- } finally {
- if (cursor != null) cursor.close();
- }
-
- // Special handling for CDMA WDP datagrams
- if (isCdmaWapPush) {
- // Build up the data stream
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- for (int i = 0; i < messageCount; i++) {
- // reassemble the (WSP-)pdu
- output.write(pdus[i], 0, pdus[i].length);
- }
- byte[] datagram = output.toByteArray();
-
- // Dispatch the PDU to applications
- if (destPort == SmsHeader.PORT_WAP_PUSH) {
- // Handle the PUSH
- return mWapPush.dispatchWapPdu(datagram);
- } else {
- pdus = new byte[1][];
- pdus[0] = datagram;
- // The messages were sent to any other WAP port
- dispatchPortAddressedPdus(pdus, destPort);
- return Activity.RESULT_OK;
- }
- }
-
- // Dispatch the PDUs to applications
- if (destPort != -1) {
- if (destPort == SmsHeader.PORT_WAP_PUSH) {
- // Build up the data stream
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- for (int i = 0; i < messageCount; i++) {
- SmsMessage msg = SmsMessage.createFromPdu(pdus[i], getFormat());
- byte[] data = msg.getUserData();
- output.write(data, 0, data.length);
- }
- // Handle the PUSH
- return mWapPush.dispatchWapPdu(output.toByteArray());
- } else {
- // The messages were sent to a port, so concoct a URI for it
- dispatchPortAddressedPdus(pdus, destPort);
- }
- } else {
- // The messages were not sent to a port
- dispatchPdus(pdus);
- }
- return Activity.RESULT_OK;
- }
-
- /**
- * Dispatches standard PDUs to interested applications
- *
- * @param pdus The raw PDUs making up the message
- */
- protected void dispatchPdus(byte[][] pdus) {
- Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
- intent.putExtra("pdus", pdus);
- intent.putExtra("format", getFormat());
- dispatch(intent, RECEIVE_SMS_PERMISSION);
- }
-
- /**
- * Dispatches port addressed PDUs to interested applications
- *
- * @param pdus The raw PDUs making up the message
- * @param port The destination port of the messages
- */
- protected void dispatchPortAddressedPdus(byte[][] pdus, int port) {
- Uri uri = Uri.parse("sms://localhost:" + port);
- Intent intent = new Intent(Intents.DATA_SMS_RECEIVED_ACTION, uri);
- intent.putExtra("pdus", pdus);
- intent.putExtra("format", getFormat());
- dispatch(intent, RECEIVE_SMS_PERMISSION);
- }
-
- /**
- * Send a data based SMS to a specific application port.
- *
- * @param destAddr the address to send the message to
- * @param scAddr is the service center address or null to use
- * the current default SMSC
- * @param destPort 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 successfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * <code>RESULT_ERROR_NO_SERVICE</code><br>.
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- */
- protected abstract void sendData(String destAddr, String scAddr, int destPort,
- byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent);
-
- /**
- * Send a text based SMS.
- *
- * @param destAddr the address to send the message to
- * @param scAddr is the service center address or null to use
- * the current default SMSC
- * @param text the body of the message to send
- * @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is successfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * <code>RESULT_ERROR_NO_SERVICE</code><br>.
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- */
- protected abstract void sendText(String destAddr, String scAddr,
- String text, PendingIntent sentIntent, PendingIntent deliveryIntent);
-
- /**
- * Calculate the number of septets needed to encode the message.
- *
- * @param messageBody the message to encode
- * @param use7bitOnly ignore (but still count) illegal characters if true
- * @return TextEncodingDetails
- */
- protected abstract TextEncodingDetails calculateLength(CharSequence messageBody,
- boolean use7bitOnly);
-
- /**
- * Send a multi-part text based SMS.
- *
- * @param destAddr the address to send the message to
- * @param scAddr 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>
- * <code>RESULT_ERROR_NO_SERVICE</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 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").
- */
- protected void sendMultipartText(String destAddr, String scAddr,
- ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
- ArrayList<PendingIntent> deliveryIntents) {
-
- int refNumber = getNextConcatenatedRef() & 0x00FF;
- int msgCount = parts.size();
- int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN;
-
- mRemainingMessages = msgCount;
-
- TextEncodingDetails[] encodingForParts = new TextEncodingDetails[msgCount];
- for (int i = 0; i < msgCount; i++) {
- TextEncodingDetails details = calculateLength(parts.get(i), false);
- if (encoding != details.codeUnitSize
- && (encoding == android.telephony.SmsMessage.ENCODING_UNKNOWN
- || encoding == android.telephony.SmsMessage.ENCODING_7BIT)) {
- encoding = details.codeUnitSize;
- }
- encodingForParts[i] = details;
- }
-
- for (int i = 0; i < msgCount; i++) {
- SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
- concatRef.refNumber = refNumber;
- concatRef.seqNumber = i + 1; // 1-based sequence
- concatRef.msgCount = msgCount;
- // TODO: We currently set this to true since our messaging app will never
- // send more than 255 parts (it converts the message to MMS well before that).
- // However, we should support 3rd party messaging apps that might need 16-bit
- // references
- // Note: It's not sufficient to just flip this bit to true; it will have
- // ripple effects (several calculations assume 8-bit ref).
- concatRef.isEightBits = true;
- SmsHeader smsHeader = new SmsHeader();
- smsHeader.concatRef = concatRef;
-
- // Set the national language tables for 3GPP 7-bit encoding, if enabled.
- if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
- smsHeader.languageTable = encodingForParts[i].languageTable;
- smsHeader.languageShiftTable = encodingForParts[i].languageShiftTable;
- }
-
- PendingIntent sentIntent = null;
- if (sentIntents != null && sentIntents.size() > i) {
- sentIntent = sentIntents.get(i);
- }
-
- PendingIntent deliveryIntent = null;
- if (deliveryIntents != null && deliveryIntents.size() > i) {
- deliveryIntent = deliveryIntents.get(i);
- }
-
- sendNewSubmitPdu(destAddr, scAddr, parts.get(i), smsHeader, encoding,
- sentIntent, deliveryIntent, (i == (msgCount - 1)));
- }
-
- }
-
- /**
- * Create a new SubmitPdu and send it.
- */
- protected abstract void sendNewSubmitPdu(String destinationAddress, String scAddress,
- String message, SmsHeader smsHeader, int encoding,
- PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart);
-
- /**
- * Send a SMS
- *
- * @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>Intent</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>
- * <code>RESULT_ERROR_NO_SERVICE</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>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").
- * @param destAddr the destination phone number (for short code confirmation)
- */
- protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent, String destAddr) {
- if (mSmsSendDisabled) {
- if (sentIntent != null) {
- try {
- sentIntent.send(RESULT_ERROR_NO_SERVICE);
- } catch (CanceledException ex) {}
- }
- Log.d(TAG, "Device does not support sending sms.");
- return;
- }
-
- if (pdu == null) {
- if (sentIntent != null) {
- try {
- sentIntent.send(RESULT_ERROR_NULL_PDU);
- } catch (CanceledException ex) {}
- }
- return;
- }
-
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("smsc", smsc);
- map.put("pdu", pdu);
-
- // Get calling app package name via UID from Binder call
- PackageManager pm = mContext.getPackageManager();
- String[] packageNames = pm.getPackagesForUid(Binder.getCallingUid());
-
- if (packageNames == null || packageNames.length == 0) {
- // Refuse to send SMS if we can't get the calling package name.
- Log.e(TAG, "Can't get calling app package name: refusing to send SMS");
- if (sentIntent != null) {
- try {
- sentIntent.send(RESULT_ERROR_GENERIC_FAILURE);
- } catch (CanceledException ex) {
- Log.e(TAG, "failed to send error result");
- }
- }
- return;
- }
-
- String appPackage = packageNames[0];
-
- // Strip non-digits from destination phone number before checking for short codes
- // and before displaying the number to the user if confirmation is required.
- SmsTracker tracker = new SmsTracker(map, sentIntent, deliveryIntent, appPackage,
- PhoneNumberUtils.extractNetworkPortion(destAddr));
-
- // check for excessive outgoing SMS usage by this app
- if (!mUsageMonitor.check(appPackage, SINGLE_PART_SMS)) {
- sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, tracker));
- return;
- }
-
- int ss = mPhone.getServiceState().getState();
-
- if (ss != ServiceState.STATE_IN_SERVICE) {
- handleNotInService(ss, tracker.mSentIntent);
- } else {
- sendSms(tracker);
- }
- }
-
- /**
- * Deny sending an SMS if the outgoing queue limit is reached. Used when the message
- * must be confirmed by the user due to excessive usage or potential premium SMS detected.
- * @param tracker the SmsTracker for the message to send
- * @return true if the message was denied; false to continue with send confirmation
- */
- private boolean denyIfQueueLimitReached(SmsTracker tracker) {
- if (mPendingTrackerCount >= MO_MSG_QUEUE_LIMIT) {
- // Deny sending message when the queue limit is reached.
- try {
- tracker.mSentIntent.send(RESULT_ERROR_LIMIT_EXCEEDED);
- } catch (CanceledException ex) {
- Log.e(TAG, "failed to send back RESULT_ERROR_LIMIT_EXCEEDED");
- }
- return true;
- }
- mPendingTrackerCount++;
- return false;
- }
-
- /**
- * Returns the label for the specified app package name.
- * @param appPackage the package name of the app requesting to send an SMS
- * @return the label for the specified app, or the package name if getApplicationInfo() fails
- */
- private CharSequence getAppLabel(String appPackage) {
- PackageManager pm = mContext.getPackageManager();
- try {
- ApplicationInfo appInfo = pm.getApplicationInfo(appPackage, 0);
- return appInfo.loadLabel(pm);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "PackageManager Name Not Found for package " + appPackage);
- return appPackage; // fall back to package name if we can't get app label
- }
- }
-
- /**
- * Post an alert when SMS needs confirmation due to excessive usage.
- * @param tracker an SmsTracker for the current message.
- */
- protected void handleReachSentLimit(SmsTracker tracker) {
- if (denyIfQueueLimitReached(tracker)) {
- return; // queue limit reached; error was returned to caller
- }
-
- CharSequence appLabel = getAppLabel(tracker.mAppPackage);
- Resources r = Resources.getSystem();
- Spanned messageText = Html.fromHtml(r.getString(R.string.sms_control_message, appLabel));
-
- ConfirmDialogListener listener = new ConfirmDialogListener(tracker);
-
- AlertDialog d = new AlertDialog.Builder(mContext)
- .setTitle(R.string.sms_control_title)
- .setIcon(R.drawable.stat_sys_warning)
- .setMessage(messageText)
- .setPositiveButton(r.getString(R.string.sms_control_yes), listener)
- .setNegativeButton(r.getString(R.string.sms_control_no), listener)
- .setOnCancelListener(listener)
- .create();
-
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- d.show();
- }
-
- /**
- * Send the message along to the radio.
- *
- * @param tracker holds the SMS message to send
- */
- protected abstract void sendSms(SmsTracker tracker);
-
- /**
- * Send the multi-part SMS based on multipart Sms tracker
- *
- * @param tracker holds the multipart Sms tracker ready to be sent
- */
- private void sendMultipartSms(SmsTracker tracker) {
- ArrayList<String> parts;
- ArrayList<PendingIntent> sentIntents;
- ArrayList<PendingIntent> deliveryIntents;
-
- HashMap<String, Object> map = tracker.mData;
-
- String destinationAddress = (String) map.get("destination");
- String scAddress = (String) map.get("scaddress");
-
- parts = (ArrayList<String>) map.get("parts");
- sentIntents = (ArrayList<PendingIntent>) map.get("sentIntents");
- deliveryIntents = (ArrayList<PendingIntent>) map.get("deliveryIntents");
-
- // check if in service
- int ss = mPhone.getServiceState().getState();
- if (ss != ServiceState.STATE_IN_SERVICE) {
- for (int i = 0, count = parts.size(); i < count; i++) {
- PendingIntent sentIntent = null;
- if (sentIntents != null && sentIntents.size() > i) {
- sentIntent = sentIntents.get(i);
- }
- handleNotInService(ss, sentIntent);
- }
- return;
- }
-
- sendMultipartText(destinationAddress, scAddress, parts, sentIntents, deliveryIntents);
- }
-
- /**
- * Send an acknowledge message.
- * @param success indicates that last message was successfully received.
- * @param result result code indicating any error
- * @param response callback message sent when operation completes.
- */
- protected abstract void acknowledgeLastIncomingSms(boolean success,
- int result, Message response);
-
- /**
- * Notify interested apps if the framework has rejected an incoming SMS,
- * and send an acknowledge message to the network.
- * @param success indicates that last message was successfully received.
- * @param result result code indicating any error
- * @param response callback message sent when operation completes.
- */
- private void notifyAndAcknowledgeLastIncomingSms(boolean success,
- int result, Message response) {
- if (!success) {
- // broadcast SMS_REJECTED_ACTION intent
- Intent intent = new Intent(Intents.SMS_REJECTED_ACTION);
- intent.putExtra("result", result);
- mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
- mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS");
- }
- acknowledgeLastIncomingSms(success, result, response);
- }
-
- /**
- * Keeps track of an SMS that has been sent to the RIL, until it has
- * successfully been sent, or we're done trying.
- *
- */
- protected static final class SmsTracker {
- // fields need to be public for derived SmsDispatchers
- public final HashMap<String, Object> mData;
- public int mRetryCount;
- public int mMessageRef;
-
- public final PendingIntent mSentIntent;
- public final PendingIntent mDeliveryIntent;
-
- public final String mAppPackage;
- public final String mDestAddress;
-
- public SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
- PendingIntent deliveryIntent, String appPackage, String destAddr) {
- mData = data;
- mSentIntent = sentIntent;
- mDeliveryIntent = deliveryIntent;
- mRetryCount = 0;
- mAppPackage = appPackage;
- mDestAddress = destAddr;
- }
-
- /**
- * Returns whether this tracker holds a multi-part SMS.
- * @return true if the tracker holds a multi-part SMS; false otherwise
- */
- protected boolean isMultipart() {
- HashMap map = mData;
- return map.containsKey("parts");
- }
- }
-
- /**
- * Dialog listener for SMS confirmation dialog.
- */
- private final class ConfirmDialogListener
- implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
-
- private final SmsTracker mTracker;
-
- ConfirmDialogListener(SmsTracker tracker) {
- mTracker = tracker;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (which == DialogInterface.BUTTON_POSITIVE) {
- Log.d(TAG, "CONFIRM sending SMS");
- sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS, mTracker));
- } else if (which == DialogInterface.BUTTON_NEGATIVE) {
- Log.d(TAG, "DENY sending SMS");
- sendMessage(obtainMessage(EVENT_STOP_SENDING, mTracker));
- }
- }
-
- @Override
- public void onCancel(DialogInterface dialog) {
- Log.d(TAG, "dialog dismissed: don't send SMS");
- sendMessage(obtainMessage(EVENT_STOP_SENDING, mTracker));
- }
- }
-
- private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // Assume the intent is one of the SMS receive intents that
- // was sent as an ordered broadcast. Check result and ACK.
- int rc = getResultCode();
- boolean success = (rc == Activity.RESULT_OK)
- || (rc == Intents.RESULT_SMS_HANDLED);
-
- // For a multi-part message, this only ACKs the last part.
- // Previous parts were ACK'd as they were received.
- acknowledgeLastIncomingSms(success, rc, null);
- }
- };
-
- protected void dispatchBroadcastMessage(SmsCbMessage message) {
- if (message.isEmergencyMessage()) {
- Intent intent = new Intent(Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION);
- intent.putExtra("message", message);
- Log.d(TAG, "Dispatching emergency SMS CB");
- dispatch(intent, RECEIVE_EMERGENCY_BROADCAST_PERMISSION);
- } else {
- Intent intent = new Intent(Intents.SMS_CB_RECEIVED_ACTION);
- intent.putExtra("message", message);
- Log.d(TAG, "Dispatching SMS CB");
- dispatch(intent, RECEIVE_SMS_PERMISSION);
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
deleted file mode 100644
index e4cfb23..0000000
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * 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.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.util.TimeUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * {@hide}
- */
-public abstract class ServiceStateTracker extends Handler {
-
- protected CommandsInterface cm;
-
- public ServiceState ss;
- protected ServiceState newSS;
-
- public SignalStrength mSignalStrength;
-
- // TODO - this should not be public
- public RestrictedState mRestrictedState = new RestrictedState();
-
- /* The otaspMode passed to PhoneStateListener#onOtaspChanged */
- static public final int OTASP_UNINITIALIZED = 0;
- static public final int OTASP_UNKNOWN = 1;
- static public final int OTASP_NEEDED = 2;
- static public final int OTASP_NOT_NEEDED = 3;
-
- /**
- * A unique identifier to track requests associated with a poll
- * and ignore stale responses. The value is a count-down of
- * expected responses in this pollingContext.
- */
- protected int[] pollingContext;
- protected boolean mDesiredPowerState;
-
- /**
- * Values correspond to ServiceState.RIL_RADIO_TECHNOLOGY_ definitions.
- */
- protected int mRilRadioTechnology = 0;
- protected int mNewRilRadioTechnology = 0;
-
- /**
- * By default, strength polling is enabled. However, if we're
- * getting unsolicited signal strength updates from the radio, set
- * value to true and don't bother polling any more.
- */
- protected boolean dontPollSignalStrength = false;
-
- protected RegistrantList mRoamingOnRegistrants = new RegistrantList();
- protected RegistrantList mRoamingOffRegistrants = new RegistrantList();
- protected RegistrantList mAttachedRegistrants = new RegistrantList();
- protected RegistrantList mDetachedRegistrants = new RegistrantList();
- protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
- protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
- protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
-
- /* Radio power off pending flag and tag counter */
- private boolean mPendingRadioPowerOffAfterDataOff = false;
- private int mPendingRadioPowerOffAfterDataOffTag = 0;
-
- protected static final boolean DBG = true;
-
- /** Signal strength poll rate. */
- protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
-
- /** Waiting period before recheck gprs and voice registration. */
- public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
-
- /** GSM events */
- protected static final int EVENT_RADIO_STATE_CHANGED = 1;
- protected static final int EVENT_NETWORK_STATE_CHANGED = 2;
- protected static final int EVENT_GET_SIGNAL_STRENGTH = 3;
- protected static final int EVENT_POLL_STATE_REGISTRATION = 4;
- protected static final int EVENT_POLL_STATE_GPRS = 5;
- protected static final int EVENT_POLL_STATE_OPERATOR = 6;
- protected static final int EVENT_POLL_SIGNAL_STRENGTH = 10;
- protected static final int EVENT_NITZ_TIME = 11;
- protected static final int EVENT_SIGNAL_STRENGTH_UPDATE = 12;
- protected static final int EVENT_RADIO_AVAILABLE = 13;
- protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14;
- protected static final int EVENT_GET_LOC_DONE = 15;
- protected static final int EVENT_SIM_RECORDS_LOADED = 16;
- protected static final int EVENT_SIM_READY = 17;
- protected static final int EVENT_LOCATION_UPDATES_ENABLED = 18;
- protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE = 19;
- protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE = 20;
- protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE = 21;
- protected static final int EVENT_CHECK_REPORT_GPRS = 22;
- protected static final int EVENT_RESTRICTED_STATE_CHANGED = 23;
-
- /** CDMA events */
- protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA = 24;
- protected static final int EVENT_POLL_STATE_OPERATOR_CDMA = 25;
- protected static final int EVENT_RUIM_READY = 26;
- protected static final int EVENT_RUIM_RECORDS_LOADED = 27;
- protected static final int EVENT_POLL_SIGNAL_STRENGTH_CDMA = 28;
- protected static final int EVENT_GET_SIGNAL_STRENGTH_CDMA = 29;
- protected static final int EVENT_NETWORK_STATE_CHANGED_CDMA = 30;
- protected static final int EVENT_GET_LOC_DONE_CDMA = 31;
- protected static final int EVENT_SIGNAL_STRENGTH_UPDATE_CDMA = 32;
- protected static final int EVENT_NV_LOADED = 33;
- protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION = 34;
- protected static final int EVENT_NV_READY = 35;
- protected static final int EVENT_ERI_FILE_LOADED = 36;
- protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE = 37;
- protected static final int EVENT_SET_RADIO_POWER_OFF = 38;
- protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 39;
- protected static final int EVENT_CDMA_PRL_VERSION_CHANGED = 40;
- protected static final int EVENT_RADIO_ON = 41;
-
-
- protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
-
- /**
- * List of ISO codes for countries that can have an offset of
- * GMT+0 when not in daylight savings time. This ignores some
- * small places such as the Canary Islands (Spain) and
- * Danmarkshavn (Denmark). The list must be sorted by code.
- */
- protected static final String[] GMT_COUNTRY_CODES = {
- "bf", // Burkina Faso
- "ci", // Cote d'Ivoire
- "eh", // Western Sahara
- "fo", // Faroe Islands, Denmark
- "gb", // United Kingdom of Great Britain and Northern Ireland
- "gh", // Ghana
- "gm", // Gambia
- "gn", // Guinea
- "gw", // Guinea Bissau
- "ie", // Ireland
- "lr", // Liberia
- "is", // Iceland
- "ma", // Morocco
- "ml", // Mali
- "mr", // Mauritania
- "pt", // Portugal
- "sl", // Sierra Leone
- "sn", // Senegal
- "st", // Sao Tome and Principe
- "tg", // Togo
- };
-
- /** Reason for registration denial. */
- protected static final String REGISTRATION_DENIED_GEN = "General";
- protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
-
- public ServiceStateTracker() {
- }
-
- public boolean getDesiredPowerState() {
- return mDesiredPowerState;
- }
-
- /**
- * Registration point for combined roaming on
- * combined roaming is true when roaming is true and ONS differs SPN
- *
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForRoamingOn(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- mRoamingOnRegistrants.add(r);
-
- if (ss.getRoaming()) {
- r.notifyRegistrant();
- }
- }
-
- public void unregisterForRoamingOn(Handler h) {
- mRoamingOnRegistrants.remove(h);
- }
-
- /**
- * Registration point for combined roaming off
- * combined roaming is true when roaming is true and ONS differs SPN
- *
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForRoamingOff(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- mRoamingOffRegistrants.add(r);
-
- if (!ss.getRoaming()) {
- r.notifyRegistrant();
- }
- }
-
- public void unregisterForRoamingOff(Handler h) {
- mRoamingOffRegistrants.remove(h);
- }
-
- /**
- * Re-register network by toggling preferred network type.
- * This is a work-around to deregister and register network since there is
- * no ril api to set COPS=2 (deregister) only.
- *
- * @param onComplete is dispatched when this is complete. it will be
- * an AsyncResult, and onComplete.obj.exception will be non-null
- * on failure.
- */
- public void reRegisterNetwork(Message onComplete) {
- cm.getPreferredNetworkType(
- obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
- }
-
- public void
- setRadioPower(boolean power) {
- mDesiredPowerState = power;
-
- setPowerStateToDesired();
- }
-
- /**
- * These two flags manage the behavior of the cell lock -- the
- * lock should be held if either flag is true. The intention is
- * to allow temporary acquisition of the lock to get a single
- * update. Such a lock grab and release can thus be made to not
- * interfere with more permanent lock holds -- in other words, the
- * lock will only be released if both flags are false, and so
- * releases by temporary users will only affect the lock state if
- * there is no continuous user.
- */
- private boolean mWantContinuousLocationUpdates;
- private boolean mWantSingleLocationUpdate;
-
- public void enableSingleLocationUpdate() {
- if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
- mWantSingleLocationUpdate = true;
- cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
- }
-
- public void enableLocationUpdates() {
- if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return;
- mWantContinuousLocationUpdates = true;
- cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
- }
-
- protected void disableSingleLocationUpdate() {
- mWantSingleLocationUpdate = false;
- if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
- cm.setLocationUpdates(false, null);
- }
- }
-
- public void disableLocationUpdates() {
- mWantContinuousLocationUpdates = false;
- if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) {
- cm.setLocationUpdates(false, null);
- }
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_SET_RADIO_POWER_OFF:
- synchronized(this) {
- if (mPendingRadioPowerOffAfterDataOff &&
- (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
- if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
- hangupAndPowerOff();
- mPendingRadioPowerOffAfterDataOffTag += 1;
- mPendingRadioPowerOffAfterDataOff = false;
- } else {
- log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
- "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
- }
- }
- break;
-
- default:
- log("Unhandled message with number: " + msg.what);
- break;
- }
- }
-
- protected abstract Phone getPhone();
- protected abstract void handlePollStateResult(int what, AsyncResult ar);
- protected abstract void updateSpnDisplay();
- protected abstract void setPowerStateToDesired();
- protected abstract void log(String s);
- protected abstract void loge(String s);
-
- public abstract int getCurrentDataConnectionState();
- public abstract boolean isConcurrentVoiceAndDataAllowed();
-
- /**
- * Registration point for transition into DataConnection attached.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- mAttachedRegistrants.add(r);
-
- if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
- }
- }
- public void unregisterForDataConnectionAttached(Handler h) {
- mAttachedRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition into DataConnection detached.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- mDetachedRegistrants.add(r);
-
- if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
- }
- }
- public void unregisterForDataConnectionDetached(Handler h) {
- mDetachedRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition into network attached.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj in Message.obj
- */
- public void registerForNetworkAttached(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
-
- mNetworkAttachedRegistrants.add(r);
- if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
- }
- }
- public void unregisterForNetworkAttached(Handler h) {
- mNetworkAttachedRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition into packet service restricted zone.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- mPsRestrictEnabledRegistrants.add(r);
-
- if (mRestrictedState.isPsRestricted()) {
- r.notifyRegistrant();
- }
- }
-
- public void unregisterForPsRestrictedEnabled(Handler h) {
- mPsRestrictEnabledRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition out of packet service restricted zone.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- mPsRestrictDisabledRegistrants.add(r);
-
- if (mRestrictedState.isPsRestricted()) {
- r.notifyRegistrant();
- }
- }
-
- public void unregisterForPsRestrictedDisabled(Handler h) {
- mPsRestrictDisabledRegistrants.remove(h);
- }
-
- /**
- * Clean up existing voice and data connection then turn off radio power.
- *
- * Hang up the existing voice calls to decrease call drop rate.
- */
- public void powerOffRadioSafely(DataConnectionTracker dcTracker) {
- synchronized (this) {
- if (!mPendingRadioPowerOffAfterDataOff) {
- // To minimize race conditions we call cleanUpAllConnections on
- // both if else paths instead of before this isDisconnected test.
- if (dcTracker.isDisconnected()) {
- // To minimize race conditions we do this after isDisconnected
- dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
- if (DBG) log("Data disconnected, turn off radio right away.");
- hangupAndPowerOff();
- } else {
- dcTracker.cleanUpAllConnections(Phone.REASON_RADIO_TURNED_OFF);
- Message msg = Message.obtain(this);
- msg.what = EVENT_SET_RADIO_POWER_OFF;
- msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
- if (sendMessageDelayed(msg, 30000)) {
- if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
- mPendingRadioPowerOffAfterDataOff = true;
- } else {
- log("Cannot send delayed Msg, turn off radio right away.");
- hangupAndPowerOff();
- }
- }
- }
- }
- }
-
- /**
- * process the pending request to turn radio off after data is disconnected
- *
- * return true if there is pending request to process; false otherwise.
- */
- public boolean processPendingRadioPowerOffAfterDataOff() {
- synchronized(this) {
- if (mPendingRadioPowerOffAfterDataOff) {
- if (DBG) log("Process pending request to turn radio off.");
- mPendingRadioPowerOffAfterDataOffTag += 1;
- hangupAndPowerOff();
- mPendingRadioPowerOffAfterDataOff = false;
- return true;
- }
- return false;
- }
- }
-
- /**
- * Hang up all voice call and turn off radio. Implemented by derived class.
- */
- protected abstract void hangupAndPowerOff();
-
- /** Cancel a pending (if any) pollState() operation */
- protected void cancelPollState() {
- // This will effectively cancel the rest of the poll requests.
- pollingContext = new int[1];
- }
-
- /**
- * Return true if time zone needs fixing.
- *
- * @param phoneBase
- * @param operatorNumeric
- * @param prevOperatorNumeric
- * @param needToFixTimeZone
- * @return true if time zone needs to be fixed
- */
- protected boolean shouldFixTimeZoneNow(PhoneBase phoneBase, String operatorNumeric,
- String prevOperatorNumeric, boolean needToFixTimeZone) {
- // Return false if the mcc isn't valid as we don't know where we are.
- // Return true if we have an IccCard and the mcc changed or we
- // need to fix it because when the NITZ time came in we didn't
- // know the country code.
-
- // If mcc is invalid then we'll return false
- int mcc;
- try {
- mcc = Integer.parseInt(operatorNumeric.substring(0, 3));
- } catch (Exception e) {
- if (DBG) {
- log("shouldFixTimeZoneNow: no mcc, operatorNumeric=" + operatorNumeric +
- " retVal=false");
- }
- return false;
- }
-
- // If prevMcc is invalid will make it different from mcc
- // so we'll return true if the card exists.
- int prevMcc;
- try {
- prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3));
- } catch (Exception e) {
- prevMcc = mcc + 1;
- }
-
- // Determine if the Icc card exists
- IccCard iccCard = phoneBase.getIccCard();
- boolean iccCardExist = (iccCard != null) && iccCard.getState().iccCardExist();
-
- // Determine retVal
- boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone);
- if (DBG) {
- long ctm = System.currentTimeMillis();
- log("shouldFixTimeZoneNow: retVal=" + retVal +
- " iccCard=" + iccCard +
- " iccCard.state=" + (iccCard == null ? "null" : iccCard.getState().toString()) +
- " iccCardExist=" + iccCardExist +
- " operatorNumeric=" + operatorNumeric + " mcc=" + mcc +
- " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc +
- " needToFixTimeZone=" + needToFixTimeZone +
- " ltod=" + TimeUtils.logTimeOfDay(ctm));
- }
- return retVal;
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("ServiceStateTracker:");
- pw.println(" ss=" + ss);
- pw.println(" newSS=" + newSS);
- pw.println(" mSignalStrength=" + mSignalStrength);
- pw.println(" mRestrictedState=" + mRestrictedState);
- pw.println(" pollingContext=" + pollingContext);
- pw.println(" mDesiredPowerState=" + mDesiredPowerState);
- pw.println(" mRilRadioTechnology=" + mRilRadioTechnology);
- pw.println(" mNewRilRadioTechnology=" + mNewRilRadioTechnology);
- pw.println(" dontPollSignalStrength=" + dontPollSignalStrength);
- pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
- pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsAddress.java b/telephony/java/com/android/internal/telephony/SmsAddress.java
deleted file mode 100644
index b3892cb..0000000
--- a/telephony/java/com/android/internal/telephony/SmsAddress.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-public abstract class SmsAddress {
- // From TS 23.040 9.1.2.5 and TS 24.008 table 10.5.118
- // and C.S0005-D table 2.7.1.3.2.4-2
- public static final int TON_UNKNOWN = 0;
- public static final int TON_INTERNATIONAL = 1;
- public static final int TON_NATIONAL = 2;
- public static final int TON_NETWORK = 3;
- public static final int TON_SUBSCRIBER = 4;
- public static final int TON_ALPHANUMERIC = 5;
- public static final int TON_ABBREVIATED = 6;
-
- public int ton;
- public String address;
- public byte[] origBytes;
-
- /**
- * Returns the address of the SMS message in String form or null if unavailable
- */
- public String getAddressString() {
- return address;
- }
-
- /**
- * Returns true if this is an alphanumeric address
- */
- public boolean isAlphanumeric() {
- return ton == TON_ALPHANUMERIC;
- }
-
- /**
- * Returns true if this is a network address
- */
- public boolean isNetworkSpecific() {
- return ton == TON_NETWORK;
- }
-
- public boolean couldBeEmailGateway() {
- // Some carriers seems to send email gateway messages in this form:
- // from: an UNKNOWN TON, 3 or 4 digits long, beginning with a 5
- // PID: 0x00, Data coding scheme 0x03
- // So we just attempt to treat any message from an address length <= 4
- // as an email gateway
-
- return address.length() <= 4;
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsConstants.java b/telephony/java/com/android/internal/telephony/SmsConstants.java
new file mode 100644
index 0000000..1ccdc3b
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SmsConstants.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.telephony;
+
+/**
+ * SMS Constants and must be the same as the corresponding
+ * deprecated version in SmsMessage.
+ *
+ * @hide
+ */
+public class SmsConstants {
+ /** User data text encoding code unit size */
+ public static final int ENCODING_UNKNOWN = 0;
+ public static final int ENCODING_7BIT = 1;
+ public static final int ENCODING_8BIT = 2;
+ public static final int ENCODING_16BIT = 3;
+
+ /** 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;
+
+ /**
+ * This value is not defined in global standard. Only in Korea, this is used.
+ */
+ public static final int ENCODING_KSC5601 = 4;
+
+ /** 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.
+ */
+ public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
+
+ /**
+ * SMS Class enumeration.
+ * See TS 23.038.
+ */
+ public enum MessageClass{
+ UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
+ }
+
+ /**
+ * Indicates a 3GPP format SMS message.
+ * @hide pending API council approval
+ */
+ public static final String FORMAT_3GPP = "3gpp";
+
+ /**
+ * Indicates a 3GPP2 format SMS message.
+ * @hide pending API council approval
+ */
+ public static final String FORMAT_3GPP2 = "3gpp2";
+}
diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java
deleted file mode 100644
index c32388f..0000000
--- a/telephony/java/com/android/internal/telephony/SmsHeader.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * 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.telephony.SmsMessage;
-
-import com.android.internal.util.HexDump;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
-import java.util.ArrayList;
-
-/**
- * SMS user data header, as specified in TS 23.040 9.2.3.24.
- */
-public class SmsHeader {
-
- // TODO(cleanup): this data structure is generally referred to as
- // the 'user data header' or UDH, and so the class name should
- // change to reflect this...
-
- /** SMS user data header information element identifiers.
- * (see TS 23.040 9.2.3.24)
- */
- public static final int ELT_ID_CONCATENATED_8_BIT_REFERENCE = 0x00;
- public static final int ELT_ID_SPECIAL_SMS_MESSAGE_INDICATION = 0x01;
- public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT = 0x04;
- public static final int ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT = 0x05;
- public static final int ELT_ID_SMSC_CONTROL_PARAMS = 0x06;
- public static final int ELT_ID_UDH_SOURCE_INDICATION = 0x07;
- public static final int ELT_ID_CONCATENATED_16_BIT_REFERENCE = 0x08;
- public static final int ELT_ID_WIRELESS_CTRL_MSG_PROTOCOL = 0x09;
- public static final int ELT_ID_TEXT_FORMATTING = 0x0A;
- public static final int ELT_ID_PREDEFINED_SOUND = 0x0B;
- public static final int ELT_ID_USER_DEFINED_SOUND = 0x0C;
- public static final int ELT_ID_PREDEFINED_ANIMATION = 0x0D;
- public static final int ELT_ID_LARGE_ANIMATION = 0x0E;
- public static final int ELT_ID_SMALL_ANIMATION = 0x0F;
- public static final int ELT_ID_LARGE_PICTURE = 0x10;
- public static final int ELT_ID_SMALL_PICTURE = 0x11;
- public static final int ELT_ID_VARIABLE_PICTURE = 0x12;
- public static final int ELT_ID_USER_PROMPT_INDICATOR = 0x13;
- public static final int ELT_ID_EXTENDED_OBJECT = 0x14;
- public static final int ELT_ID_REUSED_EXTENDED_OBJECT = 0x15;
- public static final int ELT_ID_COMPRESSION_CONTROL = 0x16;
- public static final int ELT_ID_OBJECT_DISTR_INDICATOR = 0x17;
- public static final int ELT_ID_STANDARD_WVG_OBJECT = 0x18;
- public static final int ELT_ID_CHARACTER_SIZE_WVG_OBJECT = 0x19;
- public static final int ELT_ID_EXTENDED_OBJECT_DATA_REQUEST_CMD = 0x1A;
- public static final int ELT_ID_RFC_822_EMAIL_HEADER = 0x20;
- public static final int ELT_ID_HYPERLINK_FORMAT_ELEMENT = 0x21;
- public static final int ELT_ID_REPLY_ADDRESS_ELEMENT = 0x22;
- public static final int ELT_ID_ENHANCED_VOICE_MAIL_INFORMATION = 0x23;
- public static final int ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT = 0x24;
- public static final int ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT = 0x25;
-
- public static final int PORT_WAP_PUSH = 2948;
- public static final int PORT_WAP_WSP = 9200;
-
- public static class PortAddrs {
- public int destPort;
- public int origPort;
- public boolean areEightBits;
- }
-
- public static class ConcatRef {
- public int refNumber;
- public int seqNumber;
- public int msgCount;
- public boolean isEightBits;
- }
-
- /**
- * A header element that is not explicitly parsed, meaning not
- * PortAddrs or ConcatRef.
- */
- public static class MiscElt {
- public int id;
- public byte[] data;
- }
-
- public PortAddrs portAddrs;
- public ConcatRef concatRef;
- public ArrayList<MiscElt> miscEltList = new ArrayList<MiscElt>();
-
- /** 7 bit national language locking shift table, or 0 for GSM default 7 bit alphabet. */
- public int languageTable;
-
- /** 7 bit national language single shift table, or 0 for GSM default 7 bit extension table. */
- public int languageShiftTable;
-
- public SmsHeader() {}
-
- /**
- * Create structured SmsHeader object from serialized byte array representation.
- * (see TS 23.040 9.2.3.24)
- * @param data is user data header bytes
- * @return SmsHeader object
- */
- public static SmsHeader fromByteArray(byte[] data) {
- ByteArrayInputStream inStream = new ByteArrayInputStream(data);
- SmsHeader smsHeader = new SmsHeader();
- while (inStream.available() > 0) {
- /**
- * NOTE: as defined in the spec, ConcatRef and PortAddr
- * fields should not reoccur, but if they do the last
- * occurrence is to be used. Also, for ConcatRef
- * elements, if the count is zero, sequence is zero, or
- * sequence is larger than count, the entire element is to
- * be ignored.
- */
- int id = inStream.read();
- int length = inStream.read();
- ConcatRef concatRef;
- PortAddrs portAddrs;
- switch (id) {
- case ELT_ID_CONCATENATED_8_BIT_REFERENCE:
- concatRef = new ConcatRef();
- concatRef.refNumber = inStream.read();
- concatRef.msgCount = inStream.read();
- concatRef.seqNumber = inStream.read();
- concatRef.isEightBits = true;
- if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 &&
- concatRef.seqNumber <= concatRef.msgCount) {
- smsHeader.concatRef = concatRef;
- }
- break;
- case ELT_ID_CONCATENATED_16_BIT_REFERENCE:
- concatRef = new ConcatRef();
- concatRef.refNumber = (inStream.read() << 8) | inStream.read();
- concatRef.msgCount = inStream.read();
- concatRef.seqNumber = inStream.read();
- concatRef.isEightBits = false;
- if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 &&
- concatRef.seqNumber <= concatRef.msgCount) {
- smsHeader.concatRef = concatRef;
- }
- break;
- case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT:
- portAddrs = new PortAddrs();
- portAddrs.destPort = inStream.read();
- portAddrs.origPort = inStream.read();
- portAddrs.areEightBits = true;
- smsHeader.portAddrs = portAddrs;
- break;
- case ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT:
- portAddrs = new PortAddrs();
- portAddrs.destPort = (inStream.read() << 8) | inStream.read();
- portAddrs.origPort = (inStream.read() << 8) | inStream.read();
- portAddrs.areEightBits = false;
- smsHeader.portAddrs = portAddrs;
- break;
- case ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT:
- smsHeader.languageShiftTable = inStream.read();
- break;
- case ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT:
- smsHeader.languageTable = inStream.read();
- break;
- default:
- MiscElt miscElt = new MiscElt();
- miscElt.id = id;
- miscElt.data = new byte[length];
- inStream.read(miscElt.data, 0, length);
- smsHeader.miscEltList.add(miscElt);
- }
- }
- return smsHeader;
- }
-
- /**
- * Create serialized byte array representation from structured SmsHeader object.
- * (see TS 23.040 9.2.3.24)
- * @return Byte array representing the SmsHeader
- */
- public static byte[] toByteArray(SmsHeader smsHeader) {
- if ((smsHeader.portAddrs == null) &&
- (smsHeader.concatRef == null) &&
- (smsHeader.miscEltList.isEmpty()) &&
- (smsHeader.languageShiftTable == 0) &&
- (smsHeader.languageTable == 0)) {
- return null;
- }
-
- ByteArrayOutputStream outStream = new ByteArrayOutputStream(SmsMessage.MAX_USER_DATA_BYTES);
- ConcatRef concatRef = smsHeader.concatRef;
- if (concatRef != null) {
- if (concatRef.isEightBits) {
- outStream.write(ELT_ID_CONCATENATED_8_BIT_REFERENCE);
- outStream.write(3);
- outStream.write(concatRef.refNumber);
- } else {
- outStream.write(ELT_ID_CONCATENATED_16_BIT_REFERENCE);
- outStream.write(4);
- outStream.write(concatRef.refNumber >>> 8);
- outStream.write(concatRef.refNumber & 0x00FF);
- }
- outStream.write(concatRef.msgCount);
- outStream.write(concatRef.seqNumber);
- }
- PortAddrs portAddrs = smsHeader.portAddrs;
- if (portAddrs != null) {
- if (portAddrs.areEightBits) {
- outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT);
- outStream.write(2);
- outStream.write(portAddrs.destPort);
- outStream.write(portAddrs.origPort);
- } else {
- outStream.write(ELT_ID_APPLICATION_PORT_ADDRESSING_16_BIT);
- outStream.write(4);
- outStream.write(portAddrs.destPort >>> 8);
- outStream.write(portAddrs.destPort & 0x00FF);
- outStream.write(portAddrs.origPort >>> 8);
- outStream.write(portAddrs.origPort & 0x00FF);
- }
- }
- if (smsHeader.languageShiftTable != 0) {
- outStream.write(ELT_ID_NATIONAL_LANGUAGE_SINGLE_SHIFT);
- outStream.write(1);
- outStream.write(smsHeader.languageShiftTable);
- }
- if (smsHeader.languageTable != 0) {
- outStream.write(ELT_ID_NATIONAL_LANGUAGE_LOCKING_SHIFT);
- outStream.write(1);
- outStream.write(smsHeader.languageTable);
- }
- for (MiscElt miscElt : smsHeader.miscEltList) {
- outStream.write(miscElt.id);
- outStream.write(miscElt.data.length);
- outStream.write(miscElt.data, 0, miscElt.data.length);
- }
- return outStream.toByteArray();
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("UserDataHeader ");
- builder.append("{ ConcatRef ");
- if (concatRef == null) {
- builder.append("unset");
- } else {
- builder.append("{ refNumber=" + concatRef.refNumber);
- builder.append(", msgCount=" + concatRef.msgCount);
- builder.append(", seqNumber=" + concatRef.seqNumber);
- builder.append(", isEightBits=" + concatRef.isEightBits);
- builder.append(" }");
- }
- builder.append(", PortAddrs ");
- if (portAddrs == null) {
- builder.append("unset");
- } else {
- builder.append("{ destPort=" + portAddrs.destPort);
- builder.append(", origPort=" + portAddrs.origPort);
- builder.append(", areEightBits=" + portAddrs.areEightBits);
- builder.append(" }");
- }
- if (languageShiftTable != 0) {
- builder.append(", languageShiftTable=" + languageShiftTable);
- }
- if (languageTable != 0) {
- builder.append(", languageTable=" + languageTable);
- }
- for (MiscElt miscElt : miscEltList) {
- builder.append(", MiscElt ");
- builder.append("{ id=" + miscElt.id);
- builder.append(", length=" + miscElt.data.length);
- builder.append(", data=" + HexDump.toHexString(miscElt.data));
- builder.append(" }");
- }
- builder.append(" }");
- return builder.toString();
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
deleted file mode 100644
index fcd038c..0000000
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import com.android.internal.telephony.SmsHeader;
-import java.util.Arrays;
-
-import static android.telephony.SmsMessage.MessageClass;
-import android.provider.Telephony;
-
-/**
- * Base class declaring the specific methods and members for SmsMessage.
- * {@hide}
- */
-public abstract class SmsMessageBase {
- private static final String LOG_TAG = "SMS";
-
- /** {@hide} The address of the SMSC. May be null */
- protected String scAddress;
-
- /** {@hide} The address of the sender */
- protected SmsAddress originatingAddress;
-
- /** {@hide} The message body as a string. May be null if the message isn't text */
- protected String messageBody;
-
- /** {@hide} */
- protected String pseudoSubject;
-
- /** {@hide} Non-null if this is an email gateway message */
- protected String emailFrom;
-
- /** {@hide} Non-null if this is an email gateway message */
- protected String emailBody;
-
- /** {@hide} */
- protected boolean isEmail;
-
- /** {@hide} */
- protected long scTimeMillis;
-
- /** {@hide} The raw PDU of the message */
- protected byte[] mPdu;
-
- /** {@hide} The raw bytes for the user data section of the message */
- protected byte[] userData;
-
- /** {@hide} */
- protected SmsHeader userDataHeader;
-
- // "Message Waiting Indication Group"
- // 23.038 Section 4
- /** {@hide} */
- protected boolean isMwi;
-
- /** {@hide} */
- protected boolean mwiSense;
-
- /** {@hide} */
- protected boolean mwiDontStore;
-
- /**
- * Indicates status for messages stored on the ICC.
- */
- protected int statusOnIcc = -1;
-
- /**
- * Record index of message in the EF.
- */
- protected int indexOnIcc = -1;
-
- /** TP-Message-Reference - Message Reference of sent message. @hide */
- public int messageRef;
-
- /**
- * For a specific text string, this object describes protocol
- * properties of encoding it for transmission as message user
- * data.
- */
- public static class TextEncodingDetails {
- /**
- *The number of SMS's required to encode the text.
- */
- public int msgCount;
-
- /**
- * The number of code units consumed so far, where code units
- * are basically characters in the encoding -- for example,
- * septets for the standard ASCII and GSM encodings, and 16
- * bits for Unicode.
- */
- public int codeUnitCount;
-
- /**
- * How many code units are still available without spilling
- * into an additional message.
- */
- public int codeUnitsRemaining;
-
- /**
- * The encoding code unit size (specified using
- * android.telephony.SmsMessage ENCODING_*).
- */
- public int codeUnitSize;
-
- /**
- * The GSM national language table to use, or 0 for the default 7-bit alphabet.
- */
- public int languageTable;
-
- /**
- * The GSM national language shift table to use, or 0 for the default 7-bit extension table.
- */
- public int languageShiftTable;
-
- @Override
- public String toString() {
- return "TextEncodingDetails " +
- "{ msgCount=" + msgCount +
- ", codeUnitCount=" + codeUnitCount +
- ", codeUnitsRemaining=" + codeUnitsRemaining +
- ", codeUnitSize=" + codeUnitSize +
- ", languageTable=" + languageTable +
- ", languageShiftTable=" + languageShiftTable +
- " }";
- }
- }
-
- // TODO(): This class is duplicated in SmsMessage.java. Refactor accordingly.
- public static abstract class SubmitPduBase {
- public byte[] encodedScAddress; // Null if not applicable.
- public byte[] encodedMessage;
-
- public String toString() {
- return "SubmitPdu: encodedScAddress = "
- + Arrays.toString(encodedScAddress)
- + ", encodedMessage = "
- + Arrays.toString(encodedMessage);
- }
- }
-
- /**
- * Returns the address of the SMS service center that relayed this message
- * or null if there is none.
- */
- public String getServiceCenterAddress() {
- return scAddress;
- }
-
- /**
- * Returns the originating address (sender) of this SMS message in String
- * form or null if unavailable
- */
- public String getOriginatingAddress() {
- if (originatingAddress == null) {
- return null;
- }
-
- return originatingAddress.getAddressString();
- }
-
- /**
- * 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() {
- if (isEmail) {
- return emailFrom;
- } else {
- return getOriginatingAddress();
- }
- }
-
- /**
- * 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 messageBody;
- }
-
- /**
- * Returns the class of this message.
- */
- public abstract MessageClass 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() {
- if (isEmail) {
- return emailBody;
- } else {
- return getMessageBody();
- }
- }
-
- /**
- * Unofficial convention of a subject line enclosed in parens empty string
- * if not present
- */
- public String getPseudoSubject() {
- return pseudoSubject == null ? "" : pseudoSubject;
- }
-
- /**
- * Returns the service centre timestamp in currentTimeMillis() format
- */
- public long getTimestampMillis() {
- return scTimeMillis;
- }
-
- /**
- * 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 isEmail;
- }
-
- /**
- * @return if isEmail() is true, body of the email sent through the gateway.
- * null otherwise
- */
- public String getEmailBody() {
- return emailBody;
- }
-
- /**
- * @return if isEmail() is true, email from address of email sent through
- * the gateway. null otherwise
- */
- public String getEmailFrom() {
- return emailFrom;
- }
-
- /**
- * Get protocol identifier.
- */
- public abstract int getProtocolIdentifier();
-
- /**
- * See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
- * SMS
- */
- public abstract boolean 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 abstract boolean isCphsMwiMessage();
-
- /**
- * returns true if this message is a CPHS voicemail / message waiting
- * indicator (MWI) clear message
- */
- public abstract boolean isMWIClearMessage();
-
- /**
- * returns true if this message is a CPHS voicemail / message waiting
- * indicator (MWI) set message
- */
- public abstract boolean isMWISetMessage();
-
- /**
- * returns true if this message is a "Message Waiting Indication Group:
- * Discard Message" notification and should not be stored.
- */
- public abstract boolean isMwiDontStore();
-
- /**
- * returns the user data section minus the user data header if one was
- * present.
- */
- public byte[] getUserData() {
- return userData;
- }
-
- /**
- * Returns an object representing the user data header
- *
- * {@hide}
- */
- public SmsHeader getUserDataHeader() {
- return userDataHeader;
- }
-
- /**
- * TODO(cleanup): The term PDU is used in a seemingly non-unique
- * manner -- for example, what is the difference between this byte
- * array and the contents of SubmitPdu objects. Maybe a more
- * illustrative term would be appropriate.
- */
-
- /**
- * Returns the raw PDU for the message.
- */
- public byte[] getPdu() {
- return mPdu;
- }
-
- /**
- * 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.
- *
- * @return 0 indicates the previously sent message was received.
- * See TS 23.040, 9.9.2.3.15 for a description of other possible
- * values.
- */
- public abstract int getStatus();
-
- /**
- * Return true iff the message is a SMS-STATUS-REPORT message.
- */
- public abstract boolean isStatusReportMessage();
-
- /**
- * Returns true iff the <code>TP-Reply-Path</code> bit is set in
- * this message.
- */
- public abstract boolean isReplyPathPresent();
-
- /**
- * 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 statusOnIcc;
- }
-
- /**
- * 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 indexOnIcc;
- }
-
- protected void parseMessageBody() {
- // originatingAddress could be null if this message is from a status
- // report.
- if (originatingAddress != null && originatingAddress.couldBeEmailGateway()) {
- extractEmailAddressFromMessageBody();
- }
- }
-
- /**
- * Try to parse this message as an email gateway message
- * There are two ways specified in TS 23.040 Section 3.8 :
- * - SMS message "may have its TP-PID set for Internet electronic mail - MT
- * SMS format: [<from-address><space>]<message> - "Depending on the
- * nature of the gateway, the destination/origination address is either
- * derived from the content of the SMS TP-OA or TP-DA field, or the
- * TP-OA/TP-DA field contains a generic gateway address and the to/from
- * address is added at the beginning as shown above." (which is supported here)
- * - Multiple addresses separated by commas, no spaces, Subject field delimited
- * by '()' or '##' and '#' Section 9.2.3.24.11 (which are NOT supported here)
- */
- protected void extractEmailAddressFromMessageBody() {
-
- /* Some carriers may use " /" delimiter as below
- *
- * 1. [x@y][ ]/[subject][ ]/[body]
- * -or-
- * 2. [x@y][ ]/[body]
- */
- String[] parts = messageBody.split("( /)|( )", 2);
- if (parts.length < 2) return;
- emailFrom = parts[0];
- emailBody = parts[1];
- isEmail = Telephony.Mms.isEmailAddress(emailFrom);
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsRawData.java b/telephony/java/com/android/internal/telephony/SmsRawData.java
deleted file mode 100644
index 891d942..0000000
--- a/telephony/java/com/android/internal/telephony/SmsRawData.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-** 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
-**
-** 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;
-
-/**
- * A parcelable holder class of byte[] for ISms aidl implementation
- */
-public class SmsRawData implements Parcelable {
- byte[] data;
-
- //Static Methods
- public static final Parcelable.Creator<SmsRawData> CREATOR
- = new Parcelable.Creator<SmsRawData> (){
- public SmsRawData createFromParcel(Parcel source) {
- int size;
- size = source.readInt();
- byte[] data = new byte[size];
- source.readByteArray(data);
- return new SmsRawData(data);
- }
-
- public SmsRawData[] newArray(int size) {
- return new SmsRawData[size];
- }
- };
-
- // Constructor
- public SmsRawData(byte[] data) {
- this.data = data;
- }
-
- public byte[] getBytes() {
- return data;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(data.length);
- dest.writeByteArray(data);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsResponse.java b/telephony/java/com/android/internal/telephony/SmsResponse.java
deleted file mode 100644
index a7c2840..0000000
--- a/telephony/java/com/android/internal/telephony/SmsResponse.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-/**
- * Object returned by the RIL upon successful completion of sendSMS.
- * Contains message reference and ackPdu.
- *
- */
-public class SmsResponse {
- /** Message reference of the just-sent SMS. */
- int messageRef;
- /** ackPdu for the just-sent SMS. */
- String ackPdu;
- /**
- * errorCode: See 3GPP 27.005, 3.2.5 for GSM/UMTS,
- * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
- */
- int errorCode;
-
- public SmsResponse(int messageRef, String ackPdu, int errorCode) {
- this.messageRef = messageRef;
- this.ackPdu = ackPdu;
- this.errorCode = errorCode;
- }
-
- public String toString() {
- String ret = "{ messageRef = " + messageRef
- + ", errorCode = " + errorCode
- + ", ackPdu = " + ackPdu
- + "}";
- return ret;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java b/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java
deleted file mode 100644
index 0c06ffc..0000000
--- a/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2011 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.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.provider.Telephony.Sms.Intents;
-import android.util.Log;
-
-/**
- * Monitors the device and ICC storage, and sends the appropriate events.
- *
- * This code was formerly part of {@link SMSDispatcher}, and has been moved
- * into a separate class to support instantiation of multiple SMSDispatchers on
- * dual-mode devices that require support for both 3GPP and 3GPP2 format messages.
- */
-public final class SmsStorageMonitor extends Handler {
- private static final String TAG = "SmsStorageMonitor";
-
- /** SIM/RUIM storage is full */
- private static final int EVENT_ICC_FULL = 1;
-
- /** Memory status reporting is acknowledged by RIL */
- private static final int EVENT_REPORT_MEMORY_STATUS_DONE = 2;
-
- /** Radio is ON */
- private static final int EVENT_RADIO_ON = 3;
-
- /** Context from phone object passed to constructor. */
- private final Context mContext;
-
- /** Wake lock to ensure device stays awake while dispatching the SMS intent. */
- private PowerManager.WakeLock mWakeLock;
-
- private boolean mReportMemoryStatusPending;
-
- final CommandsInterface mCm; // accessed from inner class
- boolean mStorageAvailable = true; // accessed from inner class
-
- /**
- * Hold the wake lock for 5 seconds, which should be enough time for
- * any receiver(s) to grab its own wake lock.
- */
- private static final int WAKE_LOCK_TIMEOUT = 5000;
-
- /**
- * Creates an SmsStorageMonitor and registers for events.
- * @param phone the Phone to use
- */
- public SmsStorageMonitor(PhoneBase phone) {
- mContext = phone.getContext();
- mCm = phone.mCM;
-
- createWakelock();
-
- mCm.setOnIccSmsFull(this, EVENT_ICC_FULL, null);
- mCm.registerForOn(this, EVENT_RADIO_ON, null);
-
- // Register for device storage intents. Use these to notify the RIL
- // that storage for SMS is or is not available.
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_DEVICE_STORAGE_FULL);
- filter.addAction(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
- mContext.registerReceiver(mResultReceiver, filter);
- }
-
- public void dispose() {
- mCm.unSetOnIccSmsFull(this);
- mCm.unregisterForOn(this);
- mContext.unregisterReceiver(mResultReceiver);
- }
-
- /**
- * Handles events coming from the phone stack. Overridden from handler.
- * @param msg the message to handle
- */
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_ICC_FULL:
- handleIccFull();
- break;
-
- case EVENT_REPORT_MEMORY_STATUS_DONE:
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- mReportMemoryStatusPending = true;
- Log.v(TAG, "Memory status report to modem pending : mStorageAvailable = "
- + mStorageAvailable);
- } else {
- mReportMemoryStatusPending = false;
- }
- break;
-
- case EVENT_RADIO_ON:
- if (mReportMemoryStatusPending) {
- Log.v(TAG, "Sending pending memory status report : mStorageAvailable = "
- + mStorageAvailable);
- mCm.reportSmsMemoryStatus(mStorageAvailable,
- obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
- }
- break;
- }
- }
-
- private void createWakelock() {
- PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SmsStorageMonitor");
- mWakeLock.setReferenceCounted(true);
- }
-
- /**
- * Called when SIM_FULL message is received from the RIL. Notifies interested
- * parties that SIM storage for SMS messages is full.
- */
- private void handleIccFull() {
- // broadcast SIM_FULL intent
- Intent intent = new Intent(Intents.SIM_FULL_ACTION);
- mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
- mContext.sendBroadcast(intent, SMSDispatcher.RECEIVE_SMS_PERMISSION);
- }
-
- /** Returns whether or not there is storage available for an incoming SMS. */
- public boolean isStorageAvailable() {
- return mStorageAvailable;
- }
-
- private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) {
- mStorageAvailable = false;
- mCm.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
- } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) {
- mStorageAvailable = true;
- mCm.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
- }
- }
- };
-}
diff --git a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
deleted file mode 100644
index 4a4485d..0000000
--- a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2011 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.ContentResolver;
-import android.content.Context;
-import android.content.res.XmlResourceParser;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-/**
- * Implement the per-application based SMS control, which limits the number of
- * SMS/MMS messages an app can send in the checking period.
- *
- * This code was formerly part of {@link SMSDispatcher}, and has been moved
- * into a separate class to support instantiation of multiple SMSDispatchers on
- * dual-mode devices that require support for both 3GPP and 3GPP2 format messages.
- */
-public class SmsUsageMonitor {
- private static final String TAG = "SmsUsageMonitor";
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
-
- /** Default checking period for SMS sent without user permission. */
- private static final int DEFAULT_SMS_CHECK_PERIOD = 1800000; // 30 minutes
-
- /** Default number of SMS sent in checking period without user permission. */
- private static final int DEFAULT_SMS_MAX_COUNT = 30;
-
- private final int mCheckPeriod;
- private final int mMaxAllowed;
-
- private final HashMap<String, ArrayList<Long>> mSmsStamp =
- new HashMap<String, ArrayList<Long>>();
-
- /**
- * Create SMS usage monitor.
- * @param context the context to use to load resources and get TelephonyManager service
- */
- public SmsUsageMonitor(Context context) {
- ContentResolver resolver = context.getContentResolver();
-
- mMaxAllowed = Settings.Secure.getInt(resolver,
- Settings.Secure.SMS_OUTGOING_CHECK_MAX_COUNT,
- DEFAULT_SMS_MAX_COUNT);
-
- mCheckPeriod = Settings.Secure.getInt(resolver,
- Settings.Secure.SMS_OUTGOING_CHECK_INTERVAL_MS,
- DEFAULT_SMS_CHECK_PERIOD);
- }
-
- /** Clear the SMS application list for disposal. */
- void dispose() {
- mSmsStamp.clear();
- }
-
- /**
- * Check to see if an application is allowed to send new SMS messages, and confirm with
- * user if the send limit was reached or if a non-system app is potentially sending to a
- * premium SMS short code or number.
- *
- * @param appName the package name of the app requesting to send an SMS
- * @param smsWaiting the number of new messages desired to send
- * @return true if application is allowed to send the requested number
- * of new sms messages
- */
- public boolean check(String appName, int smsWaiting) {
- synchronized (mSmsStamp) {
- removeExpiredTimestamps();
-
- ArrayList<Long> sentList = mSmsStamp.get(appName);
- if (sentList == null) {
- sentList = new ArrayList<Long>();
- mSmsStamp.put(appName, sentList);
- }
-
- return isUnderLimit(sentList, smsWaiting);
- }
- }
-
- /**
- * Remove keys containing only old timestamps. This can happen if an SMS app is used
- * to send messages and then uninstalled.
- */
- private void removeExpiredTimestamps() {
- long beginCheckPeriod = System.currentTimeMillis() - mCheckPeriod;
-
- synchronized (mSmsStamp) {
- Iterator<Map.Entry<String, ArrayList<Long>>> iter = mSmsStamp.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry<String, ArrayList<Long>> entry = iter.next();
- ArrayList<Long> oldList = entry.getValue();
- if (oldList.isEmpty() || oldList.get(oldList.size() - 1) < beginCheckPeriod) {
- iter.remove();
- }
- }
- }
- }
-
- private boolean isUnderLimit(ArrayList<Long> sent, int smsWaiting) {
- Long ct = System.currentTimeMillis();
- long beginCheckPeriod = ct - mCheckPeriod;
-
- if (VDBG) log("SMS send size=" + sent.size() + " time=" + ct);
-
- while (!sent.isEmpty() && sent.get(0) < beginCheckPeriod) {
- sent.remove(0);
- }
-
- if ((sent.size() + smsWaiting) <= mMaxAllowed) {
- for (int i = 0; i < smsWaiting; i++ ) {
- sent.add(ct);
- }
- return true;
- }
- return false;
- }
-
- private static void log(String msg) {
- Log.d(TAG, msg);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java b/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java
deleted file mode 100644
index bd94de2..0000000
--- a/telephony/java/com/android/internal/telephony/TelephonyCapabilities.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2010 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.util.Log;
-
-import com.android.internal.telephony.Phone;
-
-/**
- * Utilities that check if the phone supports specified capabilities.
- */
-public class TelephonyCapabilities {
- private static final String LOG_TAG = "TelephonyCapabilities";
-
- /** This class is never instantiated. */
- private TelephonyCapabilities() {
- }
-
- /**
- * Return true if the current phone supports ECM ("Emergency Callback
- * Mode"), which is a feature where the device goes into a special
- * state for a short period of time after making an outgoing emergency
- * call.
- *
- * (On current devices, that state lasts 5 minutes. It prevents data
- * usage by other apps, to avoid conflicts with any possible incoming
- * calls. It also puts up a notification in the status bar, showing a
- * countdown while ECM is active, and allowing the user to exit ECM.)
- *
- * Currently this is assumed to be true for CDMA phones, and false
- * otherwise.
- */
- public static boolean supportsEcm(Phone phone) {
- return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
- }
-
- /**
- * Return true if the current phone supports Over The Air Service
- * Provisioning (OTASP)
- *
- * Currently this is assumed to be true for CDMA phones, and false
- * otherwise.
- *
- * TODO: Watch out: this is also highly carrier-specific, since the
- * OTASP procedure is different from one carrier to the next, *and* the
- * different carriers may want very different onscreen UI as well.
- * The procedure may even be different for different devices with the
- * same carrier.
- *
- * So we eventually will need a much more flexible, pluggable design.
- * This method here is just a placeholder to reduce hardcoded
- * "if (CDMA)" checks sprinkled throughout the phone app.
- */
- public static boolean supportsOtasp(Phone phone) {
- return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
- }
-
- /**
- * Return true if the current phone can retrieve the voice message count.
- *
- * Currently this is assumed to be true on CDMA phones and false otherwise.
- */
- public static boolean supportsVoiceMessageCount(Phone phone) {
- return (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
- }
-
- /**
- * Return true if this phone allows the user to select which
- * network to use.
- *
- * Currently this is assumed to be true only on GSM phones.
- *
- * TODO: Should CDMA phones allow this as well?
- */
- public static boolean supportsNetworkSelection(Phone phone) {
- return (phone.getPhoneType() == Phone.PHONE_TYPE_GSM);
- }
-
- /**
- * Returns a resource ID for a label to use when displaying the
- * "device id" of the current device. (This is currently used as the
- * title of the "device id" dialog.)
- *
- * This is specific to the device's telephony technology: the device
- * id is called "IMEI" on GSM phones and "MEID" on CDMA phones.
- */
- public static int getDeviceIdLabel(Phone phone) {
- if (phone.getPhoneType() == Phone.PHONE_TYPE_GSM) {
- return com.android.internal.R.string.imei;
- } else if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
- return com.android.internal.R.string.meid;
- } else {
- Log.w(LOG_TAG, "getDeviceIdLabel: no known label for phone "
- + phone.getPhoneName());
- return 0;
- }
- }
-
- /**
- * Return true if the current phone supports the ability to explicitly
- * manage the state of a conference call (i.e. view the participants,
- * and hangup or separate individual callers.)
- *
- * The in-call screen's "Manage conference" UI is available only on
- * devices that support this feature.
- *
- * Currently this is assumed to be true on GSM phones and false otherwise.
- */
- public static boolean supportsConferenceCallManagement(Phone phone) {
- return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM)
- || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP));
- }
-
- /**
- * Return true if the current phone supports explicit "Hold" and
- * "Unhold" actions for an active call. (If so, the in-call UI will
- * provide onscreen "Hold" / "Unhold" buttons.)
- *
- * Currently this is assumed to be true on GSM phones and false
- * otherwise. (In particular, CDMA has no concept of "putting a call
- * on hold.")
- */
- public static boolean supportsHoldAndUnhold(Phone phone) {
- return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM)
- || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP));
- }
-
- /**
- * Return true if the current phone supports distinct "Answer & Hold"
- * and "Answer & End" behaviors in the call-waiting scenario. If so,
- * the in-call UI may provide separate buttons or menu items for these
- * two actions.
- *
- * Currently this is assumed to be true on GSM phones and false
- * otherwise. (In particular, CDMA has no concept of explicitly
- * managing the background call, or "putting a call on hold.")
- *
- * TODO: It might be better to expose this capability in a more
- * generic form, like maybe "supportsExplicitMultipleLineManagement()"
- * rather than focusing specifically on call-waiting behavior.
- */
- public static boolean supportsAnswerAndHold(Phone phone) {
- return ((phone.getPhoneType() == Phone.PHONE_TYPE_GSM)
- || (phone.getPhoneType() == Phone.PHONE_TYPE_SIP));
- }
-
- /**
- * Return true if phones with the given phone type support ADN
- * (Abbreviated Dialing Numbers).
- *
- * Currently this returns true when the phone type is GSM
- * ({@link Phone#PHONE_TYPE_GSM}).
- *
- * This is using int for an argument for letting apps outside
- * Phone process access to it, while other methods in this class is
- * using Phone object.
- *
- * TODO: Theoretically phones other than GSM may have the ADN capability.
- * Consider having better check here, or have better capability as part
- * of public API, with which the argument should be replaced with
- * something more appropriate.
- */
- public static boolean supportsAdn(int phoneType) {
- return phoneType == Phone.PHONE_TYPE_GSM;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 3355e8a..3cfd0bf 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -230,10 +230,49 @@
* <p class="note">.
* This is to pop up a notice to show user that the phone is in emergency callback mode
* and atacalls and outgoing sms are blocked.
- *
+ *
* <p class="note">This is a protected intent that can only be sent
* by the system.
*/
public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS
= "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS";
+
+
+ /**
+ * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are
+ * of the form *#*#<code>#*#*. The intent will have the data URI:</p>
+ *
+ * <p><code>android_secret_code://<code></code></p>
+ */
+ public static final String SECRET_CODE_ACTION =
+ "android.provider.Telephony.SECRET_CODE";
+
+ /**
+ * Broadcast Action: The Service Provider string(s) have been updated. Activities or
+ * services that use these strings should update their display.
+ * The intent will have the following extra values:</p>
+ * <ul>
+ * <li><em>showPlmn</em> - Boolean that indicates whether the PLMN should be shown.</li>
+ * <li><em>plmn</em> - The operator name of the registered network, as a string.</li>
+ * <li><em>showSpn</em> - Boolean that indicates whether the SPN should be shown.</li>
+ * <li><em>spn</em> - The service provider name, as a string.</li>
+ * </ul>
+ * Note that <em>showPlmn</em> may indicate that <em>plmn</em> should be displayed, even
+ * though the value for <em>plmn</em> is null. This can happen, for example, if the phone
+ * has not registered to a network yet. In this case the receiver may substitute an
+ * appropriate placeholder string (eg, "No service").
+ *
+ * It is recommended to display <em>plmn</em> before / above <em>spn</em> if
+ * both are displayed.
+ *
+ * <p>Note this is a protected intent that can only be sent
+ * by the system.
+ */
+ public static final String SPN_STRINGS_UPDATED_ACTION =
+ "android.provider.Telephony.SPN_STRINGS_UPDATED";
+
+ public static final String EXTRA_SHOW_PLMN = "showPlmn";
+ public static final String EXTRA_PLMN = "plmn";
+ public static final String EXTRA_SHOW_SPN = "showSpn";
+ public static final String EXTRA_SPN = "spn";
}
diff --git a/telephony/java/com/android/internal/telephony/UUSInfo.java b/telephony/java/com/android/internal/telephony/UUSInfo.java
deleted file mode 100644
index 801b845..0000000
--- a/telephony/java/com/android/internal/telephony/UUSInfo.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-public class UUSInfo {
-
- /*
- * User-to-User signaling Info activation types derived from 3GPP 23.087
- * v8.0
- */
-
- public static final int UUS_TYPE1_IMPLICIT = 0;
-
- public static final int UUS_TYPE1_REQUIRED = 1;
-
- public static final int UUS_TYPE1_NOT_REQUIRED = 2;
-
- public static final int UUS_TYPE2_REQUIRED = 3;
-
- public static final int UUS_TYPE2_NOT_REQUIRED = 4;
-
- public static final int UUS_TYPE3_REQUIRED = 5;
-
- public static final int UUS_TYPE3_NOT_REQUIRED = 6;
-
- /*
- * User-to-User Signaling Information data coding schemes. Possible values
- * for Octet 3 (Protocol Discriminator field) in the UUIE. The values have
- * been specified in section 10.5.4.25 of 3GPP TS 24.008
- */
-
- public static final int UUS_DCS_USP = 0; /* User specified protocol */
-
- public static final int UUS_DCS_OSIHLP = 1; /* OSI higher layer protocol */
-
- public static final int UUS_DCS_X244 = 2; /* X.244 */
-
- public static final int UUS_DCS_RMCF = 3; /*
- * Reserved for system management
- * convergence function
- */
-
- public static final int UUS_DCS_IA5c = 4; /* IA5 characters */
-
- private int uusType;
-
- private int uusDcs;
-
- private byte[] uusData;
-
- public UUSInfo() {
- this.uusType = UUS_TYPE1_IMPLICIT;
- this.uusDcs = UUS_DCS_IA5c;
- this.uusData = null;
- }
-
- public UUSInfo(int uusType, int uusDcs, byte[] uusData) {
- this.uusType = uusType;
- this.uusDcs = uusDcs;
- this.uusData = uusData;
- }
-
- public int getDcs() {
- return uusDcs;
- }
-
- public void setDcs(int uusDcs) {
- this.uusDcs = uusDcs;
- }
-
- public int getType() {
- return uusType;
- }
-
- public void setType(int uusType) {
- this.uusType = uusType;
- }
-
- public byte[] getUserData() {
- return uusData;
- }
-
- public void setUserData(byte[] uusData) {
- this.uusData = uusData;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java
deleted file mode 100644
index 11e5ff9..0000000
--- a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-/**
- * WapPushManager constant value definitions
- */
-public class WapPushManagerParams {
- /**
- * Application type activity
- */
- public static final int APP_TYPE_ACTIVITY = 0;
-
- /**
- * Application type service
- */
- public static final int APP_TYPE_SERVICE = 1;
-
- /**
- * Process Message return value
- * Message is handled
- */
- public static final int MESSAGE_HANDLED = 0x1;
-
- /**
- * Process Message return value
- * Application ID or content type was not found in the application ID table
- */
- public static final int APP_QUERY_FAILED = 0x2;
-
- /**
- * Process Message return value
- * Receiver application signature check failed
- */
- public static final int SIGNATURE_NO_MATCH = 0x4;
-
- /**
- * Process Message return value
- * Receiver application was not found
- */
- public static final int INVALID_RECEIVER_NAME = 0x8;
-
- /**
- * Process Message return value
- * Unknown exception
- */
- public static final int EXCEPTION_CAUGHT = 0x10;
-
- /**
- * Process Message return value
- * Need further processing after WapPushManager message processing
- */
- public static final int FURTHER_PROCESSING = 0x8000;
-
-}
-
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
deleted file mode 100755
index e2779dc..0000000
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.internal.telephony;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.provider.Telephony;
-import android.provider.Telephony.Sms.Intents;
-import android.util.Log;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-/**
- * WAP push handler class.
- *
- * @hide
- */
-public class WapPushOverSms {
- private static final String LOG_TAG = "WAP PUSH";
-
- private final Context mContext;
- private WspTypeDecoder pduDecoder;
- private SMSDispatcher mSmsDispatcher;
-
- /**
- * Hold the wake lock for 5 seconds, which should be enough time for
- * any receiver(s) to grab its own wake lock.
- */
- private final int WAKE_LOCK_TIMEOUT = 5000;
-
- private final int BIND_RETRY_INTERVAL = 1000;
- /**
- * A handle to WapPushManager interface
- */
- private WapPushConnection mWapConn = null;
- private class WapPushConnection implements ServiceConnection {
- private IWapPushManager mWapPushMan;
- private Context mOwner;
-
- public WapPushConnection(Context ownerContext) {
- mOwner = ownerContext;
- }
-
- public void onServiceConnected(ComponentName name, IBinder service) {
- mWapPushMan = IWapPushManager.Stub.asInterface(service);
- if (false) Log.v(LOG_TAG, "wappush manager connected to " +
- mOwner.hashCode());
- }
-
- public void onServiceDisconnected(ComponentName name) {
- mWapPushMan = null;
- if (false) Log.v(LOG_TAG, "wappush manager disconnected.");
- // WapPushManager must be always attached.
- rebindWapPushManager();
- }
-
- /**
- * bind WapPushManager
- */
- public void bindWapPushManager() {
- if (mWapPushMan != null) return;
-
- final ServiceConnection wapPushConnection = this;
-
- mOwner.bindService(new Intent(IWapPushManager.class.getName()),
- wapPushConnection, Context.BIND_AUTO_CREATE);
- }
-
- /**
- * rebind WapPushManager
- * This method is called when WapPushManager is disconnected unexpectedly.
- */
- private void rebindWapPushManager() {
- if (mWapPushMan != null) return;
-
- final ServiceConnection wapPushConnection = this;
- new Thread() {
- public void run() {
- while (mWapPushMan == null) {
- mOwner.bindService(new Intent(IWapPushManager.class.getName()),
- wapPushConnection, Context.BIND_AUTO_CREATE);
- try {
- Thread.sleep(BIND_RETRY_INTERVAL);
- } catch (InterruptedException e) {
- if (false) Log.v(LOG_TAG, "sleep interrupted.");
- }
- }
- }
- }.start();
- }
-
- /**
- * Returns interface to WapPushManager
- */
- public IWapPushManager getWapPushManager() {
- return mWapPushMan;
- }
- }
-
- public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) {
- mSmsDispatcher = smsDispatcher;
- mContext = phone.getContext();
- mWapConn = new WapPushConnection(mContext);
- mWapConn.bindWapPushManager();
- }
-
-
- /**
- * Dispatches inbound messages that are in the WAP PDU format. See
- * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
- *
- * @param pdu The WAP PDU, made up of one or more SMS PDUs
- * @return a result code from {@link Telephony.Sms.Intents}, or
- * {@link Activity#RESULT_OK} if the message has been broadcast
- * to applications
- */
- public int dispatchWapPdu(byte[] pdu) {
-
- if (false) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
-
- int index = 0;
- int transactionId = pdu[index++] & 0xFF;
- int pduType = pdu[index++] & 0xFF;
- int headerLength = 0;
-
- if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
- (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
- if (false) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
- return Intents.RESULT_SMS_HANDLED;
- }
-
- pduDecoder = new WspTypeDecoder(pdu);
-
- /**
- * Parse HeaderLen(unsigned integer).
- * From wap-230-wsp-20010705-a section 8.1.2
- * The maximum size of a uintvar is 32 bits.
- * So it will be encoded in no more than 5 octets.
- */
- if (pduDecoder.decodeUintvarInteger(index) == false) {
- if (false) Log.w(LOG_TAG, "Received PDU. Header Length error.");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
- headerLength = (int)pduDecoder.getValue32();
- index += pduDecoder.getDecodedDataLength();
-
- int headerStartIndex = index;
-
- /**
- * Parse Content-Type.
- * From wap-230-wsp-20010705-a section 8.4.2.24
- *
- * Content-type-value = Constrained-media | Content-general-form
- * Content-general-form = Value-length Media-type
- * Media-type = (Well-known-media | Extension-Media) *(Parameter)
- * Value-length = Short-length | (Length-quote Length)
- * Short-length = <Any octet 0-30> (octet <= WAP_PDU_SHORT_LENGTH_MAX)
- * Length-quote = <Octet 31> (WAP_PDU_LENGTH_QUOTE)
- * Length = Uintvar-integer
- */
- if (pduDecoder.decodeContentType(index) == false) {
- if (false) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
-
- String mimeType = pduDecoder.getValueString();
- long binaryContentType = pduDecoder.getValue32();
- index += pduDecoder.getDecodedDataLength();
-
- byte[] header = new byte[headerLength];
- System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
-
- byte[] intentData;
-
- if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
- intentData = pdu;
- } else {
- int dataIndex = headerStartIndex + headerLength;
- intentData = new byte[pdu.length - dataIndex];
- System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
- }
-
- /**
- * Seek for application ID field in WSP header.
- * If application ID is found, WapPushManager substitute the message
- * processing. Since WapPushManager is optional module, if WapPushManager
- * is not found, legacy message processing will be continued.
- */
- if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
- index = (int) pduDecoder.getValue32();
- pduDecoder.decodeXWapApplicationId(index);
- String wapAppId = pduDecoder.getValueString();
- if (wapAppId == null) {
- wapAppId = Integer.toString((int) pduDecoder.getValue32());
- }
-
- String contentType = ((mimeType == null) ?
- Long.toString(binaryContentType) : mimeType);
- if (false) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);
-
- try {
- boolean processFurther = true;
- IWapPushManager wapPushMan = mWapConn.getWapPushManager();
-
- if (wapPushMan == null) {
- if (false) Log.w(LOG_TAG, "wap push manager not found!");
- } else {
- Intent intent = new Intent();
- intent.putExtra("transactionId", transactionId);
- intent.putExtra("pduType", pduType);
- intent.putExtra("header", header);
- intent.putExtra("data", intentData);
- intent.putExtra("contentTypeParameters",
- pduDecoder.getContentParameters());
-
- int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
- if (false) Log.v(LOG_TAG, "procRet:" + procRet);
- if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
- && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
- processFurther = false;
- }
- }
- if (!processFurther) {
- return Intents.RESULT_SMS_HANDLED;
- }
- } catch (RemoteException e) {
- if (false) Log.w(LOG_TAG, "remote func failed...");
- }
- }
- if (false) Log.v(LOG_TAG, "fall back to existing handler");
-
- if (mimeType == null) {
- if (false) Log.w(LOG_TAG, "Header Content-Type error.");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
-
- String permission;
-
- if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
- permission = "android.permission.RECEIVE_MMS";
- } else {
- permission = "android.permission.RECEIVE_WAP_PUSH";
- }
-
- Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
- intent.setType(mimeType);
- intent.putExtra("transactionId", transactionId);
- intent.putExtra("pduType", pduType);
- intent.putExtra("header", header);
- intent.putExtra("data", intentData);
- intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters());
-
- mSmsDispatcher.dispatch(intent, permission);
-
- return Activity.RESULT_OK;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
deleted file mode 100755
index 73260fb..0000000
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import java.util.HashMap;
-
-/**
- * Implement the WSP data type decoder.
- *
- * @hide
- */
-public class WspTypeDecoder {
-
- private static final int WAP_PDU_SHORT_LENGTH_MAX = 30;
- private static final int WAP_PDU_LENGTH_QUOTE = 31;
-
- public static final int PDU_TYPE_PUSH = 0x06;
- public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07;
-
- private final static HashMap<Integer, String> WELL_KNOWN_MIME_TYPES =
- new HashMap<Integer, String>();
-
- private final static HashMap<Integer, String> WELL_KNOWN_PARAMETERS =
- new HashMap<Integer, String>();
-
- public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
- private static final int Q_VALUE = 0x00;
-
- static {
- WELL_KNOWN_MIME_TYPES.put(0x00, "*/*");
- WELL_KNOWN_MIME_TYPES.put(0x01, "text/*");
- WELL_KNOWN_MIME_TYPES.put(0x02, "text/html");
- WELL_KNOWN_MIME_TYPES.put(0x03, "text/plain");
- WELL_KNOWN_MIME_TYPES.put(0x04, "text/x-hdml");
- WELL_KNOWN_MIME_TYPES.put(0x05, "text/x-ttml");
- WELL_KNOWN_MIME_TYPES.put(0x06, "text/x-vCalendar");
- WELL_KNOWN_MIME_TYPES.put(0x07, "text/x-vCard");
- WELL_KNOWN_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
- WELL_KNOWN_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
- WELL_KNOWN_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
- WELL_KNOWN_MIME_TYPES.put(0x0B, "multipart/*");
- WELL_KNOWN_MIME_TYPES.put(0x0C, "multipart/mixed");
- WELL_KNOWN_MIME_TYPES.put(0x0D, "multipart/form-data");
- WELL_KNOWN_MIME_TYPES.put(0x0E, "multipart/byterantes");
- WELL_KNOWN_MIME_TYPES.put(0x0F, "multipart/alternative");
- WELL_KNOWN_MIME_TYPES.put(0x10, "application/*");
- WELL_KNOWN_MIME_TYPES.put(0x11, "application/java-vm");
- WELL_KNOWN_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
- WELL_KNOWN_MIME_TYPES.put(0x13, "application/x-hdmlc");
- WELL_KNOWN_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
- WELL_KNOWN_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
- WELL_KNOWN_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
- WELL_KNOWN_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
- WELL_KNOWN_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
- WELL_KNOWN_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
- WELL_KNOWN_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
- WELL_KNOWN_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
- WELL_KNOWN_MIME_TYPES.put(0x1C, "image/*");
- WELL_KNOWN_MIME_TYPES.put(0x1D, "image/gif");
- WELL_KNOWN_MIME_TYPES.put(0x1E, "image/jpeg");
- WELL_KNOWN_MIME_TYPES.put(0x1F, "image/tiff");
- WELL_KNOWN_MIME_TYPES.put(0x20, "image/png");
- WELL_KNOWN_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
- WELL_KNOWN_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
- WELL_KNOWN_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
- WELL_KNOWN_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
- WELL_KNOWN_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
- WELL_KNOWN_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
- WELL_KNOWN_MIME_TYPES.put(0x27, "application/xml");
- WELL_KNOWN_MIME_TYPES.put(0x28, "text/xml");
- WELL_KNOWN_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
- WELL_KNOWN_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
- WELL_KNOWN_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
- WELL_KNOWN_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
- WELL_KNOWN_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
- WELL_KNOWN_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
- WELL_KNOWN_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
- WELL_KNOWN_MIME_TYPES.put(0x31, "text/vnd.wap.co");
- WELL_KNOWN_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
- WELL_KNOWN_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
- WELL_KNOWN_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
- WELL_KNOWN_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
- WELL_KNOWN_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x37, "application/pkcs7-mime");
- WELL_KNOWN_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
- WELL_KNOWN_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
- WELL_KNOWN_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
- WELL_KNOWN_MIME_TYPES.put(0x3B, "application/xhtml+xml");
- WELL_KNOWN_MIME_TYPES.put(0x3C, "application/wml+xml");
- WELL_KNOWN_MIME_TYPES.put(0x3D, "text/css");
- WELL_KNOWN_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
- WELL_KNOWN_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
- WELL_KNOWN_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
- WELL_KNOWN_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
- WELL_KNOWN_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
- WELL_KNOWN_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
- WELL_KNOWN_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
- WELL_KNOWN_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
- WELL_KNOWN_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
- WELL_KNOWN_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
- WELL_KNOWN_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
- WELL_KNOWN_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
- WELL_KNOWN_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
- WELL_KNOWN_MIME_TYPES.put(0x4F, "audio/*");
- WELL_KNOWN_MIME_TYPES.put(0x50, "video/*");
- WELL_KNOWN_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
- WELL_KNOWN_MIME_TYPES.put(0x52, "application/mikey");
- WELL_KNOWN_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
- WELL_KNOWN_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
-
- WELL_KNOWN_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
- WELL_KNOWN_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
- WELL_KNOWN_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
- WELL_KNOWN_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x020C, "image/x-up-wpng");
- WELL_KNOWN_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
- WELL_KNOWN_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
- WELL_KNOWN_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
- WELL_KNOWN_MIME_TYPES.put(0x0305, "text/calendar");
- WELL_KNOWN_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
- WELL_KNOWN_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
- WELL_KNOWN_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
- WELL_KNOWN_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
- WELL_KNOWN_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
- WELL_KNOWN_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
- WELL_KNOWN_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
- WELL_KNOWN_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
- WELL_KNOWN_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
- WELL_KNOWN_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
- WELL_KNOWN_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
- WELL_KNOWN_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
- WELL_KNOWN_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
- WELL_KNOWN_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
- WELL_KNOWN_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
- WELL_KNOWN_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
- WELL_KNOWN_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
- WELL_KNOWN_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
- WELL_KNOWN_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
-
- WELL_KNOWN_PARAMETERS.put(0x00, "Q");
- WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
- WELL_KNOWN_PARAMETERS.put(0x02, "Level");
- WELL_KNOWN_PARAMETERS.put(0x03, "Type");
- WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
- WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
- WELL_KNOWN_PARAMETERS.put(0x09, "Type");
- WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
- WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
- WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
- WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
- WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
- WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
- WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
- WELL_KNOWN_PARAMETERS.put(0x16, "Size");
- WELL_KNOWN_PARAMETERS.put(0x17, "Name");
- WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
- WELL_KNOWN_PARAMETERS.put(0x19, "Start");
- WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
- WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
- WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
- WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
- }
-
- public static final String CONTENT_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
- public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message";
- public static final String CONTENT_TYPE_B_PUSH_SYNCML_NOTI = "application/vnd.syncml.notification";
-
- byte[] wspData;
- int dataLength;
- long unsigned32bit;
- String stringValue;
-
- HashMap<String, String> contentParameters;
-
- public WspTypeDecoder(byte[] pdu) {
- wspData = pdu;
- }
-
- /**
- * Decode the "Text-string" type for WSP pdu
- *
- * @param startIndex The starting position of the "Text-string" in this pdu
- *
- * @return false when error(not a Text-string) occur
- * return value can be retrieved by getValueString() method length of data in pdu can be
- * retrieved by getDecodedDataLength() method
- */
- public boolean decodeTextString(int startIndex) {
- int index = startIndex;
- while (wspData[index] != 0) {
- index++;
- }
- dataLength = index - startIndex + 1;
- if (wspData[startIndex] == 127) {
- stringValue = new String(wspData, startIndex + 1, dataLength - 2);
- } else {
- stringValue = new String(wspData, startIndex, dataLength - 1);
- }
- return true;
- }
-
- /**
- * Decode the "Token-text" type for WSP pdu
- *
- * @param startIndex The starting position of the "Token-text" in this pdu
- *
- * @return always true
- * return value can be retrieved by getValueString() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeTokenText(int startIndex) {
- int index = startIndex;
- while (wspData[index] != 0) {
- index++;
- }
- dataLength = index - startIndex + 1;
- stringValue = new String(wspData, startIndex, dataLength - 1);
-
- return true;
- }
-
- /**
- * Decode the "Short-integer" type for WSP pdu
- *
- * @param startIndex The starting position of the "Short-integer" in this pdu
- *
- * @return false when error(not a Short-integer) occur
- * return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeShortInteger(int startIndex) {
- if ((wspData[startIndex] & 0x80) == 0) {
- return false;
- }
- unsigned32bit = wspData[startIndex] & 0x7f;
- dataLength = 1;
- return true;
- }
-
- /**
- * Decode the "Long-integer" type for WSP pdu
- *
- * @param startIndex The starting position of the "Long-integer" in this pdu
- *
- * @return false when error(not a Long-integer) occur
- * return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeLongInteger(int startIndex) {
- int lengthMultiOctet = wspData[startIndex] & 0xff;
-
- if (lengthMultiOctet > WAP_PDU_SHORT_LENGTH_MAX) {
- return false;
- }
- unsigned32bit = 0;
- for (int i = 1; i <= lengthMultiOctet; i++) {
- unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex + i] & 0xff);
- }
- dataLength = 1 + lengthMultiOctet;
- return true;
- }
-
- /**
- * Decode the "Integer-Value" type for WSP pdu
- *
- * @param startIndex The starting position of the "Integer-Value" in this pdu
- *
- * @return false when error(not a Integer-Value) occur
- * return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeIntegerValue(int startIndex) {
- if (decodeShortInteger(startIndex) == true) {
- return true;
- }
- return decodeLongInteger(startIndex);
- }
-
- /**
- * Decode the "Uintvar-integer" type for WSP pdu
- *
- * @param startIndex The starting position of the "Uintvar-integer" in this pdu
- *
- * @return false when error(not a Uintvar-integer) occur
- * return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeUintvarInteger(int startIndex) {
- int index = startIndex;
-
- unsigned32bit = 0;
- while ((wspData[index] & 0x80) != 0) {
- if ((index - startIndex) >= 4) {
- return false;
- }
- unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f);
- index++;
- }
- unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f);
- dataLength = index - startIndex + 1;
- return true;
- }
-
- /**
- * Decode the "Value-length" type for WSP pdu
- *
- * @param startIndex The starting position of the "Value-length" in this pdu
- *
- * @return false when error(not a Value-length) occur
- * return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeValueLength(int startIndex) {
- if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) {
- return false;
- }
- if (wspData[startIndex] < WAP_PDU_LENGTH_QUOTE) {
- unsigned32bit = wspData[startIndex];
- dataLength = 1;
- } else {
- decodeUintvarInteger(startIndex + 1);
- dataLength++;
- }
- return true;
- }
-
- /**
- * Decode the "Extension-media" type for WSP PDU.
- *
- * @param startIndex The starting position of the "Extension-media" in this PDU.
- *
- * @return false on error, such as if there is no Extension-media at startIndex.
- * Side-effects: updates stringValue (available with
- * getValueString()), which will be null on error. The length of the
- * data in the PDU is available with getValue32(), 0 on error.
- */
- public boolean decodeExtensionMedia(int startIndex) {
- int index = startIndex;
- dataLength = 0;
- stringValue = null;
- int length = wspData.length;
- boolean rtrn = index < length;
-
- while (index < length && wspData[index] != 0) {
- index++;
- }
-
- dataLength = index - startIndex + 1;
- stringValue = new String(wspData, startIndex, dataLength - 1);
-
- return rtrn;
- }
-
- /**
- * Decode the "Constrained-encoding" type for WSP pdu
- *
- * @param startIndex The starting position of the "Constrained-encoding" in this pdu
- *
- * @return false when error(not a Constrained-encoding) occur
- * return value can be retrieved first by getValueString() and second by getValue32() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeConstrainedEncoding(int startIndex) {
- if (decodeShortInteger(startIndex) == true) {
- stringValue = null;
- return true;
- }
- return decodeExtensionMedia(startIndex);
- }
-
- /**
- * Decode the "Content-type" type for WSP pdu
- *
- * @param startIndex The starting position of the "Content-type" in this pdu
- *
- * @return false when error(not a Content-type) occurs
- * If a content type exists in the headers (either as inline string, or as well-known
- * value), getValueString() will return it. If a 'well known value' is encountered that
- * cannot be mapped to a string mime type, getValueString() will return null, and
- * getValue32() will return the unknown content type value.
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- * Any content type parameters will be accessible via getContentParameters()
- */
- public boolean decodeContentType(int startIndex) {
- int mediaPrefixLength;
- contentParameters = new HashMap<String, String>();
-
- try {
- if (decodeValueLength(startIndex) == false) {
- boolean found = decodeConstrainedEncoding(startIndex);
- if (found) {
- expandWellKnownMimeType();
- }
- return found;
- }
- int headersLength = (int) unsigned32bit;
- mediaPrefixLength = getDecodedDataLength();
- if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
- dataLength += mediaPrefixLength;
- int readLength = dataLength;
- stringValue = null;
- expandWellKnownMimeType();
- long wellKnownValue = unsigned32bit;
- String mimeType = stringValue;
- if (readContentParameters(startIndex + dataLength,
- (headersLength - (dataLength - mediaPrefixLength)), 0)) {
- dataLength += readLength;
- unsigned32bit = wellKnownValue;
- stringValue = mimeType;
- return true;
- }
- return false;
- }
- if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
- dataLength += mediaPrefixLength;
- int readLength = dataLength;
- expandWellKnownMimeType();
- long wellKnownValue = unsigned32bit;
- String mimeType = stringValue;
- if (readContentParameters(startIndex + dataLength,
- (headersLength - (dataLength - mediaPrefixLength)), 0)) {
- dataLength += readLength;
- unsigned32bit = wellKnownValue;
- stringValue = mimeType;
- return true;
- }
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- //something doesn't add up
- return false;
- }
- return false;
- }
-
- private boolean readContentParameters(int startIndex, int leftToRead, int accumulator) {
-
- int totalRead = 0;
-
- if (leftToRead > 0) {
- byte nextByte = wspData[startIndex];
- String value = null;
- String param = null;
- if ((nextByte & 0x80) == 0x00 && nextByte > 31) { // untyped
- decodeTokenText(startIndex);
- param = stringValue;
- totalRead += dataLength;
- } else { // typed
- if (decodeIntegerValue(startIndex)) {
- totalRead += dataLength;
- int wellKnownParameterValue = (int) unsigned32bit;
- param = WELL_KNOWN_PARAMETERS.get(wellKnownParameterValue);
- if (param == null) {
- param = "unassigned/0x" + Long.toHexString(wellKnownParameterValue);
- }
- // special case for the "Q" parameter, value is a uintvar
- if (wellKnownParameterValue == Q_VALUE) {
- if (decodeUintvarInteger(startIndex + totalRead)) {
- totalRead += dataLength;
- value = String.valueOf(unsigned32bit);
- contentParameters.put(param, value);
- return readContentParameters(startIndex + totalRead, leftToRead
- - totalRead, accumulator + totalRead);
- } else {
- return false;
- }
- }
- } else {
- return false;
- }
- }
-
- if (decodeNoValue(startIndex + totalRead)) {
- totalRead += dataLength;
- value = null;
- } else if (decodeIntegerValue(startIndex + totalRead)) {
- totalRead += dataLength;
- int intValue = (int) unsigned32bit;
- if (intValue == 0) {
- value = "";
- } else {
- value = String.valueOf(intValue);
- }
- } else {
- decodeTokenText(startIndex + totalRead);
- totalRead += dataLength;
- value = stringValue;
- if (value.startsWith("\"")) {
- // quoted string, so remove the quote
- value = value.substring(1);
- }
- }
- contentParameters.put(param, value);
- return readContentParameters(startIndex + totalRead, leftToRead - totalRead,
- accumulator + totalRead);
-
- } else {
- dataLength = accumulator;
- return true;
- }
- }
-
- /**
- * Check if the next byte is No-Value
- *
- * @param startIndex The starting position of the "Content length" in this pdu
- *
- * @return true if and only if the next byte is 0x00
- */
- private boolean decodeNoValue(int startIndex) {
- if (wspData[startIndex] == 0) {
- dataLength = 1;
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Populate stringValue with the mime type corresponding to the value in unsigned32bit
- *
- * Sets unsigned32bit to -1 if stringValue is already populated
- */
- private void expandWellKnownMimeType() {
- if (stringValue == null) {
- int binaryContentType = (int) unsigned32bit;
- stringValue = WELL_KNOWN_MIME_TYPES.get(binaryContentType);
- } else {
- unsigned32bit = -1;
- }
- }
-
- /**
- * Decode the "Content length" type for WSP pdu
- *
- * @param startIndex The starting position of the "Content length" in this pdu
- *
- * @return false when error(not a Content length) occur
- * return value can be retrieved by getValue32() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeContentLength(int startIndex) {
- return decodeIntegerValue(startIndex);
- }
-
- /**
- * Decode the "Content location" type for WSP pdu
- *
- * @param startIndex The starting position of the "Content location" in this pdu
- *
- * @return false when error(not a Content location) occur
- * return value can be retrieved by getValueString() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeContentLocation(int startIndex) {
- return decodeTextString(startIndex);
- }
-
- /**
- * Decode the "X-Wap-Application-Id" type for WSP pdu
- *
- * @param startIndex The starting position of the "X-Wap-Application-Id" in this pdu
- *
- * @return false when error(not a X-Wap-Application-Id) occur
- * return value can be retrieved first by getValueString() and second by getValue32()
- * method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeXWapApplicationId(int startIndex) {
- if (decodeIntegerValue(startIndex) == true) {
- stringValue = null;
- return true;
- }
- return decodeTextString(startIndex);
- }
-
- /**
- * Seek for the "X-Wap-Application-Id" field for WSP pdu
- *
- * @param startIndex The starting position of seek pointer
- * @param endIndex Valid seek area end point
- *
- * @return false when error(not a X-Wap-Application-Id) occur
- * return value can be retrieved by getValue32()
- */
- public boolean seekXWapApplicationId(int startIndex, int endIndex) {
- int index = startIndex;
-
- try {
- for (index = startIndex; index <= endIndex; ) {
- /**
- * 8.4.1.1 Field name
- * Field name is integer or text.
- */
- if (decodeIntegerValue(index)) {
- int fieldValue = (int) getValue32();
-
- if (fieldValue == PARAMETER_ID_X_WAP_APPLICATION_ID) {
- unsigned32bit = index + 1;
- return true;
- }
- } else {
- if (!decodeTextString(index)) return false;
- }
- index += getDecodedDataLength();
- if (index > endIndex) return false;
-
- /**
- * 8.4.1.2 Field values
- * Value Interpretation of First Octet
- * 0 - 30 This octet is followed by the indicated number (0 - 30)
- of data octets
- * 31 This octet is followed by a uintvar, which indicates the number
- * of data octets after it
- * 32 - 127 The value is a text string, terminated by a zero octet
- (NUL character)
- * 128 - 255 It is an encoded 7-bit value; this header has no more data
- */
- byte val = wspData[index];
- if (0 <= val && val <= WAP_PDU_SHORT_LENGTH_MAX) {
- index += wspData[index] + 1;
- } else if (val == WAP_PDU_LENGTH_QUOTE) {
- if (index + 1 >= endIndex) return false;
- index++;
- if (!decodeUintvarInteger(index)) return false;
- index += getDecodedDataLength();
- } else if (WAP_PDU_LENGTH_QUOTE < val && val <= 127) {
- if (!decodeTextString(index)) return false;
- index += getDecodedDataLength();
- } else {
- index++;
- }
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- //seek application ID failed. WSP header might be corrupted
- return false;
- }
- return false;
- }
-
- /**
- * Decode the "X-Wap-Content-URI" type for WSP pdu
- *
- * @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu
- *
- * @return false when error(not a X-Wap-Content-URI) occur
- * return value can be retrieved by getValueString() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeXWapContentURI(int startIndex) {
- return decodeTextString(startIndex);
- }
-
- /**
- * Decode the "X-Wap-Initiator-URI" type for WSP pdu
- *
- * @param startIndex The starting position of the "X-Wap-Initiator-URI" in this pdu
- *
- * @return false when error(not a X-Wap-Initiator-URI) occur
- * return value can be retrieved by getValueString() method
- * length of data in pdu can be retrieved by getDecodedDataLength() method
- */
- public boolean decodeXWapInitiatorURI(int startIndex) {
- return decodeTextString(startIndex);
- }
-
- /**
- * The data length of latest operation.
- */
- public int getDecodedDataLength() {
- return dataLength;
- }
-
- /**
- * The 32-bits result of latest operation.
- */
- public long getValue32() {
- return unsigned32bit;
- }
-
- /**
- * The String result of latest operation.
- */
- public String getValueString() {
- return stringValue;
- }
-
- /**
- * Any parameters encountered as part of a decodeContentType() invocation.
- *
- * @return a map of content parameters keyed by their names, or null if
- * decodeContentType() has not been called If any unassigned
- * well-known parameters are encountered, the key of the map will be
- * 'unassigned/0x...', where '...' is the hex value of the
- * unassigned parameter. If a parameter has No-Value the value will be null.
- *
- */
- public HashMap<String, String> getContentParameters() {
- return contentParameters;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
deleted file mode 100644
index 299e140..0000000
--- a/telephony/java/com/android/internal/telephony/cat/AppInterface.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.cat;
-
-/**
- * Interface for communication between STK App and CAT Telephony
- *
- * {@hide}
- */
-public interface AppInterface {
-
- /*
- * Intent's actions which are broadcasted by the Telephony once a new CAT
- * proactive command, session end arrive.
- */
- public static final String CAT_CMD_ACTION =
- "android.intent.action.stk.command";
- public static final String CAT_SESSION_END_ACTION =
- "android.intent.action.stk.session_end";
-
- /*
- * Callback function from app to telephony to pass a result code and user's
- * input back to the ICC.
- */
- void onCmdResponse(CatResponseMessage resMsg);
-
- /*
- * Enumeration for representing "Type of Command" of proactive commands.
- * Those are the only commands which are supported by the Telephony. Any app
- * implementation should support those.
- * Refer to ETSI TS 102.223 section 9.4
- */
- public static enum CommandType {
- DISPLAY_TEXT(0x21),
- GET_INKEY(0x22),
- GET_INPUT(0x23),
- LAUNCH_BROWSER(0x15),
- PLAY_TONE(0x20),
- REFRESH(0x01),
- SELECT_ITEM(0x24),
- SEND_SS(0x11),
- SEND_USSD(0x12),
- SEND_SMS(0x13),
- SEND_DTMF(0x14),
- SET_UP_EVENT_LIST(0x05),
- SET_UP_IDLE_MODE_TEXT(0x28),
- SET_UP_MENU(0x25),
- SET_UP_CALL(0x10),
- PROVIDE_LOCAL_INFORMATION(0x26),
- OPEN_CHANNEL(0x40),
- CLOSE_CHANNEL(0x41),
- RECEIVE_DATA(0x42),
- SEND_DATA(0x43);
-
- private int mValue;
-
- CommandType(int value) {
- mValue = value;
- }
-
- public int value() {
- return mValue;
- }
-
- /**
- * Create a CommandType object.
- *
- * @param value Integer value to be converted to a CommandType object.
- * @return CommandType object whose "Type of Command" value is {@code
- * value}. If no CommandType object has that value, null is
- * returned.
- */
- public static CommandType fromInt(int value) {
- for (CommandType e : CommandType.values()) {
- if (e.mValue == value) {
- return e;
- }
- }
- return null;
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/BerTlv.java b/telephony/java/com/android/internal/telephony/cat/BerTlv.java
deleted file mode 100644
index 095e65b..0000000
--- a/telephony/java/com/android/internal/telephony/cat/BerTlv.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.cat;
-
-import java.util.List;
-
-/**
- * Class for representing BER-TLV objects.
- *
- * @see "ETSI TS 102 223 Annex C" for more information.
- *
- * {@hide}
- */
-class BerTlv {
- private int mTag = BER_UNKNOWN_TAG;
- private List<ComprehensionTlv> mCompTlvs = null;
-
- public static final int BER_UNKNOWN_TAG = 0x00;
- public static final int BER_PROACTIVE_COMMAND_TAG = 0xd0;
- public static final int BER_MENU_SELECTION_TAG = 0xd3;
- public static final int BER_EVENT_DOWNLOAD_TAG = 0xd6;
-
- private BerTlv(int tag, List<ComprehensionTlv> ctlvs) {
- mTag = tag;
- mCompTlvs = ctlvs;
- }
-
- /**
- * Gets a list of ComprehensionTlv objects contained in this BER-TLV object.
- *
- * @return A list of COMPREHENSION-TLV object
- */
- public List<ComprehensionTlv> getComprehensionTlvs() {
- return mCompTlvs;
- }
-
- /**
- * Gets a tag id of the BER-TLV object.
- *
- * @return A tag integer.
- */
- public int getTag() {
- return mTag;
- }
-
- /**
- * Decodes a BER-TLV object from a byte array.
- *
- * @param data A byte array to decode from
- * @return A BER-TLV object decoded
- * @throws ResultException
- */
- public static BerTlv decode(byte[] data) throws ResultException {
- int curIndex = 0;
- int endIndex = data.length;
- int tag, length = 0;
-
- try {
- /* tag */
- tag = data[curIndex++] & 0xff;
- if (tag == BER_PROACTIVE_COMMAND_TAG) {
- /* length */
- int temp = data[curIndex++] & 0xff;
- if (temp < 0x80) {
- length = temp;
- } else if (temp == 0x81) {
- temp = data[curIndex++] & 0xff;
- if (temp < 0x80) {
- throw new ResultException(
- ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- "length < 0x80 length=" + Integer.toHexString(length) +
- " curIndex=" + curIndex + " endIndex=" + endIndex);
-
- }
- length = temp;
- } else {
- throw new ResultException(
- ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- "Expected first byte to be length or a length tag and < 0x81" +
- " byte= " + Integer.toHexString(temp) + " curIndex=" + curIndex +
- " endIndex=" + endIndex);
- }
- } else {
- if (ComprehensionTlvTag.COMMAND_DETAILS.value() == (tag & ~0x80)) {
- tag = BER_UNKNOWN_TAG;
- curIndex = 0;
- }
- }
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING,
- "IndexOutOfBoundsException " +
- " curIndex=" + curIndex + " endIndex=" + endIndex);
- } catch (ResultException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD, e.explanation());
- }
-
- /* COMPREHENSION-TLVs */
- if (endIndex - curIndex < length) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- "Command had extra data endIndex=" + endIndex + " curIndex=" + curIndex +
- " length=" + length);
- }
-
- List<ComprehensionTlv> ctlvs = ComprehensionTlv.decodeMany(data,
- curIndex);
-
- return new BerTlv(tag, ctlvs);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
deleted file mode 100644
index 48c2e2b..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Class used to pass CAT messages from telephony to application. Application
- * should call getXXX() to get commands's specific values.
- *
- */
-public class CatCmdMessage implements Parcelable {
- // members
- CommandDetails mCmdDet;
- private TextMessage mTextMsg;
- private Menu mMenu;
- private Input mInput;
- private BrowserSettings mBrowserSettings = null;
- private ToneSettings mToneSettings = null;
- private CallSettings mCallSettings = null;
-
- /*
- * Container for Launch Browser command settings.
- */
- public class BrowserSettings {
- public String url;
- public LaunchBrowserMode mode;
- }
-
- /*
- * Container for Call Setup command settings.
- */
- public class CallSettings {
- public TextMessage confirmMsg;
- public TextMessage callMsg;
- }
-
- CatCmdMessage(CommandParams cmdParams) {
- mCmdDet = cmdParams.cmdDet;
- switch(getCmdType()) {
- case SET_UP_MENU:
- case SELECT_ITEM:
- mMenu = ((SelectItemParams) cmdParams).menu;
- break;
- case DISPLAY_TEXT:
- case SET_UP_IDLE_MODE_TEXT:
- case SEND_DTMF:
- case SEND_SMS:
- case SEND_SS:
- case SEND_USSD:
- mTextMsg = ((DisplayTextParams) cmdParams).textMsg;
- break;
- case GET_INPUT:
- case GET_INKEY:
- mInput = ((GetInputParams) cmdParams).input;
- break;
- case LAUNCH_BROWSER:
- mTextMsg = ((LaunchBrowserParams) cmdParams).confirmMsg;
- mBrowserSettings = new BrowserSettings();
- mBrowserSettings.url = ((LaunchBrowserParams) cmdParams).url;
- mBrowserSettings.mode = ((LaunchBrowserParams) cmdParams).mode;
- break;
- case PLAY_TONE:
- PlayToneParams params = (PlayToneParams) cmdParams;
- mToneSettings = params.settings;
- mTextMsg = params.textMsg;
- break;
- case SET_UP_CALL:
- mCallSettings = new CallSettings();
- mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg;
- mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg;
- break;
- case OPEN_CHANNEL:
- case CLOSE_CHANNEL:
- case RECEIVE_DATA:
- case SEND_DATA:
- BIPClientParams param = (BIPClientParams) cmdParams;
- mTextMsg = param.textMsg;
- break;
- }
- }
-
- public CatCmdMessage(Parcel in) {
- mCmdDet = in.readParcelable(null);
- mTextMsg = in.readParcelable(null);
- mMenu = in.readParcelable(null);
- mInput = in.readParcelable(null);
- switch (getCmdType()) {
- case LAUNCH_BROWSER:
- mBrowserSettings = new BrowserSettings();
- mBrowserSettings.url = in.readString();
- mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()];
- break;
- case PLAY_TONE:
- mToneSettings = in.readParcelable(null);
- break;
- case SET_UP_CALL:
- mCallSettings = new CallSettings();
- mCallSettings.confirmMsg = in.readParcelable(null);
- mCallSettings.callMsg = in.readParcelable(null);
- break;
- }
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(mCmdDet, 0);
- dest.writeParcelable(mTextMsg, 0);
- dest.writeParcelable(mMenu, 0);
- dest.writeParcelable(mInput, 0);
- switch(getCmdType()) {
- case LAUNCH_BROWSER:
- dest.writeString(mBrowserSettings.url);
- dest.writeInt(mBrowserSettings.mode.ordinal());
- break;
- case PLAY_TONE:
- dest.writeParcelable(mToneSettings, 0);
- break;
- case SET_UP_CALL:
- dest.writeParcelable(mCallSettings.confirmMsg, 0);
- dest.writeParcelable(mCallSettings.callMsg, 0);
- break;
- }
- }
-
- public static final Parcelable.Creator<CatCmdMessage> CREATOR = new Parcelable.Creator<CatCmdMessage>() {
- public CatCmdMessage createFromParcel(Parcel in) {
- return new CatCmdMessage(in);
- }
-
- public CatCmdMessage[] newArray(int size) {
- return new CatCmdMessage[size];
- }
- };
-
- public int describeContents() {
- return 0;
- }
-
- /* external API to be used by application */
- public AppInterface.CommandType getCmdType() {
- return AppInterface.CommandType.fromInt(mCmdDet.typeOfCommand);
- }
-
- public Menu getMenu() {
- return mMenu;
- }
-
- public Input geInput() {
- return mInput;
- }
-
- public TextMessage geTextMessage() {
- return mTextMsg;
- }
-
- public BrowserSettings getBrowserSettings() {
- return mBrowserSettings;
- }
-
- public ToneSettings getToneSettings() {
- return mToneSettings;
- }
-
- public CallSettings getCallSettings() {
- return mCallSettings;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatLog.java b/telephony/java/com/android/internal/telephony/cat/CatLog.java
deleted file mode 100644
index e19ff43..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatLog.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.util.Log;
-
-public abstract class CatLog {
- static final boolean DEBUG = true;
-
- public static void d(Object caller, String msg) {
- if (!DEBUG) {
- return;
- }
-
- String className = caller.getClass().getName();
- Log.d("CAT", className.substring(className.lastIndexOf('.') + 1) + ": "
- + msg);
- }
-
- public static void d(String caller, String msg) {
- if (!DEBUG) {
- return;
- }
-
- Log.d("CAT", caller + ": " + msg);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
deleted file mode 100644
index cfcac36..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-public class CatResponseMessage {
- CommandDetails cmdDet = null;
- ResultCode resCode = ResultCode.OK;
- int usersMenuSelection = 0;
- String usersInput = null;
- boolean usersYesNoSelection = false;
- boolean usersConfirm = false;
-
- public CatResponseMessage(CatCmdMessage cmdMsg) {
- this.cmdDet = cmdMsg.mCmdDet;
- }
-
- public void setResultCode(ResultCode resCode) {
- this.resCode = resCode;
- }
-
- public void setMenuSelection(int selection) {
- this.usersMenuSelection = selection;
- }
-
- public void setInput(String input) {
- this.usersInput = input;
- }
-
- public void setYesNo(boolean yesNo) {
- usersYesNoSelection = yesNo;
- }
-
- public void setConfirmation(boolean confirm) {
- usersConfirm = confirm;
- }
-
- CommandDetails getCmdDetails() {
- return cmdDet;
- }
- }
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/CatService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java
deleted file mode 100644
index 17574ce..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CatService.java
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.os.SystemProperties;
-
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccRecords;
-
-
-import java.io.ByteArrayOutputStream;
-import java.util.List;
-import java.util.Locale;
-
-class RilMessage {
- int mId;
- Object mData;
- ResultCode mResCode;
-
- RilMessage(int msgId, String rawData) {
- mId = msgId;
- mData = rawData;
- }
-
- RilMessage(RilMessage other) {
- this.mId = other.mId;
- this.mData = other.mData;
- this.mResCode = other.mResCode;
- }
-}
-
-/**
- * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL
- * and application.
- *
- * {@hide}
- */
-public class CatService extends Handler implements AppInterface {
-
- // Class members
- private static IccRecords mIccRecords;
-
- // Service members.
- // Protects singleton instance lazy initialization.
- private static final Object sInstanceLock = new Object();
- private static CatService sInstance;
- private CommandsInterface mCmdIf;
- private Context mContext;
- private CatCmdMessage mCurrntCmd = null;
- private CatCmdMessage mMenuCmd = null;
-
- private RilMessageDecoder mMsgDecoder = null;
- private boolean mStkAppInstalled = false;
-
- // Service constants.
- static final int MSG_ID_SESSION_END = 1;
- static final int MSG_ID_PROACTIVE_COMMAND = 2;
- static final int MSG_ID_EVENT_NOTIFY = 3;
- static final int MSG_ID_CALL_SETUP = 4;
- static final int MSG_ID_REFRESH = 5;
- static final int MSG_ID_RESPONSE = 6;
- static final int MSG_ID_SIM_READY = 7;
-
- static final int MSG_ID_RIL_MSG_DECODED = 10;
-
- // Events to signal SIM presence or absent in the device.
- private static final int MSG_ID_ICC_RECORDS_LOADED = 20;
-
- private static final int DEV_ID_KEYPAD = 0x01;
- private static final int DEV_ID_DISPLAY = 0x02;
- private static final int DEV_ID_EARPIECE = 0x03;
- private static final int DEV_ID_UICC = 0x81;
- private static final int DEV_ID_TERMINAL = 0x82;
- private static final int DEV_ID_NETWORK = 0x83;
-
- static final String STK_DEFAULT = "Defualt Message";
-
- /* Intentionally private for singleton */
- private CatService(CommandsInterface ci, IccRecords ir, Context context,
- IccFileHandler fh, IccCard ic) {
- if (ci == null || ir == null || context == null || fh == null
- || ic == null) {
- throw new NullPointerException(
- "Service: Input parameters must not be null");
- }
- mCmdIf = ci;
- mContext = context;
-
- // Get the RilMessagesDecoder for decoding the messages.
- mMsgDecoder = RilMessageDecoder.getInstance(this, fh);
-
- // Register ril events handling.
- mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null);
- mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
- mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null);
- mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null);
- //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null);
-
- mIccRecords = ir;
-
- // Register for SIM ready event.
- ic.registerForReady(this, MSG_ID_SIM_READY, null);
- mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
-
- // Check if STK application is availalbe
- mStkAppInstalled = isStkAppInstalled();
-
- CatLog.d(this, "Running CAT service. STK app installed:" + mStkAppInstalled);
- }
-
- public void dispose() {
- mIccRecords.unregisterForRecordsLoaded(this);
- mCmdIf.unSetOnCatSessionEnd(this);
- mCmdIf.unSetOnCatProactiveCmd(this);
- mCmdIf.unSetOnCatEvent(this);
- mCmdIf.unSetOnCatCallSetUp(this);
-
- this.removeCallbacksAndMessages(null);
- }
-
- protected void finalize() {
- CatLog.d(this, "Service finalized");
- }
-
- private void handleRilMsg(RilMessage rilMsg) {
- if (rilMsg == null) {
- return;
- }
-
- // dispatch messages
- CommandParams cmdParams = null;
- switch (rilMsg.mId) {
- case MSG_ID_EVENT_NOTIFY:
- if (rilMsg.mResCode == ResultCode.OK) {
- cmdParams = (CommandParams) rilMsg.mData;
- if (cmdParams != null) {
- handleCommand(cmdParams, false);
- }
- }
- break;
- case MSG_ID_PROACTIVE_COMMAND:
- try {
- cmdParams = (CommandParams) rilMsg.mData;
- } catch (ClassCastException e) {
- // for error handling : cast exception
- CatLog.d(this, "Fail to parse proactive command");
- // Don't send Terminal Resp if command detail is not available
- if (mCurrntCmd != null) {
- sendTerminalResponse(mCurrntCmd.mCmdDet, ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- false, 0x00, null);
- }
- break;
- }
- if (cmdParams != null) {
- if (rilMsg.mResCode == ResultCode.OK) {
- handleCommand(cmdParams, true);
- } else {
- // for proactive commands that couldn't be decoded
- // successfully respond with the code generated by the
- // message decoder.
- sendTerminalResponse(cmdParams.cmdDet, rilMsg.mResCode,
- false, 0, null);
- }
- }
- break;
- case MSG_ID_REFRESH:
- cmdParams = (CommandParams) rilMsg.mData;
- if (cmdParams != null) {
- handleCommand(cmdParams, false);
- }
- break;
- case MSG_ID_SESSION_END:
- handleSessionEnd();
- break;
- case MSG_ID_CALL_SETUP:
- // prior event notify command supplied all the information
- // needed for set up call processing.
- break;
- }
- }
-
- /**
- * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command
- * from RIL.
- * Sends valid proactive command data to the application using intents.
- * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is
- * from RIL_UNSOL_STK_PROACTIVE_COMMAND.
- */
- private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) {
- CatLog.d(this, cmdParams.getCommandType().name());
-
- CharSequence message;
- CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
- switch (cmdParams.getCommandType()) {
- case SET_UP_MENU:
- if (removeMenu(cmdMsg.getMenu())) {
- mMenuCmd = null;
- } else {
- mMenuCmd = cmdMsg;
- }
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
- break;
- case DISPLAY_TEXT:
- // when application is not required to respond, send an immediate response.
- if (!cmdMsg.geTextMessage().responseNeeded) {
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
- }
- break;
- case REFRESH:
- // ME side only handles refresh commands which meant to remove IDLE
- // MODE TEXT.
- cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
- break;
- case SET_UP_IDLE_MODE_TEXT:
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
- break;
- case PROVIDE_LOCAL_INFORMATION:
- ResponseData resp;
- switch (cmdParams.cmdDet.commandQualifier) {
- case CommandParamsFactory.DTTZ_SETTING:
- resp = new DTTZResponseData(null);
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp);
- break;
- case CommandParamsFactory.LANGUAGE_SETTING:
- resp = new LanguageResponseData(Locale.getDefault().getLanguage());
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp);
- break;
- default:
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
- }
- // No need to start STK app here.
- return;
- case LAUNCH_BROWSER:
- if ((((LaunchBrowserParams) cmdParams).confirmMsg.text != null)
- && (((LaunchBrowserParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) {
- message = mContext.getText(com.android.internal.R.string.launchBrowserDefault);
- ((LaunchBrowserParams) cmdParams).confirmMsg.text = message.toString();
- }
- break;
- case SELECT_ITEM:
- case GET_INPUT:
- case GET_INKEY:
- break;
- case SEND_DTMF:
- case SEND_SMS:
- case SEND_SS:
- case SEND_USSD:
- if ((((DisplayTextParams)cmdParams).textMsg.text != null)
- && (((DisplayTextParams)cmdParams).textMsg.text.equals(STK_DEFAULT))) {
- message = mContext.getText(com.android.internal.R.string.sending);
- ((DisplayTextParams)cmdParams).textMsg.text = message.toString();
- }
- break;
- case PLAY_TONE:
- break;
- case SET_UP_CALL:
- if ((((CallSetupParams) cmdParams).confirmMsg.text != null)
- && (((CallSetupParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) {
- message = mContext.getText(com.android.internal.R.string.SetupCallDefault);
- ((CallSetupParams) cmdParams).confirmMsg.text = message.toString();
- }
- break;
- case OPEN_CHANNEL:
- case CLOSE_CHANNEL:
- case RECEIVE_DATA:
- case SEND_DATA:
- BIPClientParams cmd = (BIPClientParams) cmdParams;
- if (cmd.bHasAlphaId && (cmd.textMsg.text == null)) {
- CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id");
- // If alpha length is zero, we just respond with OK.
- if (isProactiveCmd) {
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
- }
- return;
- }
- // Respond with permanent failure to avoid retry if STK app is not present.
- if (!mStkAppInstalled) {
- CatLog.d(this, "No STK application found.");
- if (isProactiveCmd) {
- sendTerminalResponse(cmdParams.cmdDet,
- ResultCode.BEYOND_TERMINAL_CAPABILITY,
- false, 0, null);
- return;
- }
- }
- /*
- * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by
- * either PROACTIVE_COMMAND or EVENT_NOTIFY.
- * If PROACTIVE_COMMAND is used for those commands, send terminal
- * response here.
- */
- if (isProactiveCmd &&
- ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) ||
- (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) ||
- (cmdParams.getCommandType() == CommandType.SEND_DATA))) {
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
- }
- break;
- default:
- CatLog.d(this, "Unsupported command");
- return;
- }
- mCurrntCmd = cmdMsg;
- Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
- intent.putExtra("STK CMD", cmdMsg);
- mContext.sendBroadcast(intent);
- }
-
- /**
- * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL.
- *
- */
- private void handleSessionEnd() {
- CatLog.d(this, "SESSION END");
-
- mCurrntCmd = mMenuCmd;
- Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
- mContext.sendBroadcast(intent);
- }
-
- private void sendTerminalResponse(CommandDetails cmdDet,
- ResultCode resultCode, boolean includeAdditionalInfo,
- int additionalInfo, ResponseData resp) {
-
- if (cmdDet == null) {
- return;
- }
- ByteArrayOutputStream buf = new ByteArrayOutputStream();
-
- Input cmdInput = null;
- if (mCurrntCmd != null) {
- cmdInput = mCurrntCmd.geInput();
- }
-
- // command details
- int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
- if (cmdDet.compRequired) {
- tag |= 0x80;
- }
- buf.write(tag);
- buf.write(0x03); // length
- buf.write(cmdDet.commandNumber);
- buf.write(cmdDet.typeOfCommand);
- buf.write(cmdDet.commandQualifier);
-
- // device identities
- // According to TS102.223/TS31.111 section 6.8 Structure of
- // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
- // the ME should set the CR(comprehension required) flag to
- // comprehension not required.(CR=0)"
- // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
- // the CR flag is not set.
- tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
- buf.write(tag);
- buf.write(0x02); // length
- buf.write(DEV_ID_TERMINAL); // source device id
- buf.write(DEV_ID_UICC); // destination device id
-
- // result
- tag = 0x80 | ComprehensionTlvTag.RESULT.value();
- buf.write(tag);
- int length = includeAdditionalInfo ? 2 : 1;
- buf.write(length);
- buf.write(resultCode.value());
-
- // additional info
- if (includeAdditionalInfo) {
- buf.write(additionalInfo);
- }
-
- // Fill optional data for each corresponding command
- if (resp != null) {
- resp.format(buf);
- } else {
- encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
- }
-
- byte[] rawData = buf.toByteArray();
- String hexString = IccUtils.bytesToHexString(rawData);
- if (false) {
- CatLog.d(this, "TERMINAL RESPONSE: " + hexString);
- }
-
- mCmdIf.sendTerminalResponse(hexString, null);
- }
-
- private void encodeOptionalTags(CommandDetails cmdDet,
- ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
- CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
- if (cmdType != null) {
- switch (cmdType) {
- case GET_INKEY:
- // ETSI TS 102 384,27.22.4.2.8.4.2.
- // If it is a response for GET_INKEY command and the response timeout
- // occured, then add DURATION TLV for variable timeout case.
- if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
- (cmdInput != null) && (cmdInput.duration != null)) {
- getInKeyResponse(buf, cmdInput);
- }
- break;
- case PROVIDE_LOCAL_INFORMATION:
- if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
- (resultCode.value() == ResultCode.OK.value())) {
- getPliResponse(buf);
- }
- break;
- default:
- CatLog.d(this, "encodeOptionalTags() Unsupported Cmd details=" + cmdDet);
- break;
- }
- } else {
- CatLog.d(this, "encodeOptionalTags() bad Cmd details=" + cmdDet);
- }
- }
-
- private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
- int tag = ComprehensionTlvTag.DURATION.value();
-
- buf.write(tag);
- buf.write(0x02); // length
- buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
- buf.write(cmdInput.duration.timeInterval); // Time Duration
- }
-
- private void getPliResponse(ByteArrayOutputStream buf) {
-
- // Locale Language Setting
- String lang = SystemProperties.get("persist.sys.language");
-
- if (lang != null) {
- // tag
- int tag = ComprehensionTlvTag.LANGUAGE.value();
- buf.write(tag);
- ResponseData.writeLength(buf, lang.length());
- buf.write(lang.getBytes(), 0, lang.length());
- }
- }
-
- private void sendMenuSelection(int menuId, boolean helpRequired) {
-
- ByteArrayOutputStream buf = new ByteArrayOutputStream();
-
- // tag
- int tag = BerTlv.BER_MENU_SELECTION_TAG;
- buf.write(tag);
-
- // length
- buf.write(0x00); // place holder
-
- // device identities
- tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
- buf.write(tag);
- buf.write(0x02); // length
- buf.write(DEV_ID_KEYPAD); // source device id
- buf.write(DEV_ID_UICC); // destination device id
-
- // item identifier
- tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value();
- buf.write(tag);
- buf.write(0x01); // length
- buf.write(menuId); // menu identifier chosen
-
- // help request
- if (helpRequired) {
- tag = ComprehensionTlvTag.HELP_REQUEST.value();
- buf.write(tag);
- buf.write(0x00); // length
- }
-
- byte[] rawData = buf.toByteArray();
-
- // write real length
- int len = rawData.length - 2; // minus (tag + length)
- rawData[1] = (byte) len;
-
- String hexString = IccUtils.bytesToHexString(rawData);
-
- mCmdIf.sendEnvelope(hexString, null);
- }
-
- private void eventDownload(int event, int sourceId, int destinationId,
- byte[] additionalInfo, boolean oneShot) {
-
- ByteArrayOutputStream buf = new ByteArrayOutputStream();
-
- // tag
- int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG;
- buf.write(tag);
-
- // length
- buf.write(0x00); // place holder, assume length < 128.
-
- // event list
- tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value();
- buf.write(tag);
- buf.write(0x01); // length
- buf.write(event); // event value
-
- // device identities
- tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
- buf.write(tag);
- buf.write(0x02); // length
- buf.write(sourceId); // source device id
- buf.write(destinationId); // destination device id
-
- // additional information
- if (additionalInfo != null) {
- for (byte b : additionalInfo) {
- buf.write(b);
- }
- }
-
- byte[] rawData = buf.toByteArray();
-
- // write real length
- int len = rawData.length - 2; // minus (tag + length)
- rawData[1] = (byte) len;
-
- String hexString = IccUtils.bytesToHexString(rawData);
-
- mCmdIf.sendEnvelope(hexString, null);
- }
-
- /**
- * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor.
- *
- * @param ci CommandsInterface object
- * @param ir IccRecords object
- * @param context phone app context
- * @param fh Icc file handler
- * @param ic Icc card
- * @return The only Service object in the system
- */
- public static CatService getInstance(CommandsInterface ci, IccRecords ir,
- Context context, IccFileHandler fh, IccCard ic) {
- synchronized (sInstanceLock) {
- if (sInstance == null) {
- if (ci == null || ir == null || context == null || fh == null
- || ic == null) {
- return null;
- }
- HandlerThread thread = new HandlerThread("Cat Telephony service");
- thread.start();
- sInstance = new CatService(ci, ir, context, fh, ic);
- CatLog.d(sInstance, "NEW sInstance");
- } else if ((ir != null) && (mIccRecords != ir)) {
- CatLog.d(sInstance, "Reinitialize the Service with SIMRecords");
- mIccRecords = ir;
-
- // re-Register for SIM ready event.
- mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null);
- CatLog.d(sInstance, "sr changed reinitialize and return current sInstance");
- } else {
- CatLog.d(sInstance, "Return current sInstance");
- }
- return sInstance;
- }
- }
-
- /**
- * Used by application to get an AppInterface object.
- *
- * @return The only Service object in the system
- */
- public static AppInterface getInstance() {
- return getInstance(null, null, null, null, null);
- }
-
- @Override
- public void handleMessage(Message msg) {
-
- switch (msg.what) {
- case MSG_ID_SESSION_END:
- case MSG_ID_PROACTIVE_COMMAND:
- case MSG_ID_EVENT_NOTIFY:
- case MSG_ID_REFRESH:
- CatLog.d(this, "ril message arrived");
- String data = null;
- if (msg.obj != null) {
- AsyncResult ar = (AsyncResult) msg.obj;
- if (ar != null && ar.result != null) {
- try {
- data = (String) ar.result;
- } catch (ClassCastException e) {
- break;
- }
- }
- }
- mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
- break;
- case MSG_ID_CALL_SETUP:
- mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
- break;
- case MSG_ID_ICC_RECORDS_LOADED:
- break;
- case MSG_ID_RIL_MSG_DECODED:
- handleRilMsg((RilMessage) msg.obj);
- break;
- case MSG_ID_RESPONSE:
- handleCmdResponse((CatResponseMessage) msg.obj);
- break;
- case MSG_ID_SIM_READY:
- CatLog.d(this, "SIM ready. Reporting STK service running now...");
- mCmdIf.reportStkServiceIsRunning(null);
- break;
- default:
- throw new AssertionError("Unrecognized CAT command: " + msg.what);
- }
- }
-
- public synchronized void onCmdResponse(CatResponseMessage resMsg) {
- if (resMsg == null) {
- return;
- }
- // queue a response message.
- Message msg = this.obtainMessage(MSG_ID_RESPONSE, resMsg);
- msg.sendToTarget();
- }
-
- private boolean validateResponse(CatResponseMessage resMsg) {
- if (mCurrntCmd != null) {
- return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet));
- }
- return false;
- }
-
- private boolean removeMenu(Menu menu) {
- try {
- if (menu.items.size() == 1 && menu.items.get(0) == null) {
- return true;
- }
- } catch (NullPointerException e) {
- CatLog.d(this, "Unable to get Menu's items size");
- return true;
- }
- return false;
- }
-
- private void handleCmdResponse(CatResponseMessage resMsg) {
- // Make sure the response details match the last valid command. An invalid
- // response is a one that doesn't have a corresponding proactive command
- // and sending it can "confuse" the baseband/ril.
- // One reason for out of order responses can be UI glitches. For example,
- // if the application launch an activity, and that activity is stored
- // by the framework inside the history stack. That activity will be
- // available for relaunch using the latest application dialog
- // (long press on the home button). Relaunching that activity can send
- // the same command's result again to the CatService and can cause it to
- // get out of sync with the SIM.
- if (!validateResponse(resMsg)) {
- return;
- }
- ResponseData resp = null;
- boolean helpRequired = false;
- CommandDetails cmdDet = resMsg.getCmdDetails();
-
- switch (resMsg.resCode) {
- case HELP_INFO_REQUIRED:
- helpRequired = true;
- // fall through
- case OK:
- case PRFRMD_WITH_PARTIAL_COMPREHENSION:
- case PRFRMD_WITH_MISSING_INFO:
- case PRFRMD_WITH_ADDITIONAL_EFS_READ:
- case PRFRMD_ICON_NOT_DISPLAYED:
- case PRFRMD_MODIFIED_BY_NAA:
- case PRFRMD_LIMITED_SERVICE:
- case PRFRMD_WITH_MODIFICATION:
- case PRFRMD_NAA_NOT_ACTIVE:
- case PRFRMD_TONE_NOT_PLAYED:
- switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) {
- case SET_UP_MENU:
- helpRequired = resMsg.resCode == ResultCode.HELP_INFO_REQUIRED;
- sendMenuSelection(resMsg.usersMenuSelection, helpRequired);
- return;
- case SELECT_ITEM:
- resp = new SelectItemResponseData(resMsg.usersMenuSelection);
- break;
- case GET_INPUT:
- case GET_INKEY:
- Input input = mCurrntCmd.geInput();
- if (!input.yesNo) {
- // when help is requested there is no need to send the text
- // string object.
- if (!helpRequired) {
- resp = new GetInkeyInputResponseData(resMsg.usersInput,
- input.ucs2, input.packed);
- }
- } else {
- resp = new GetInkeyInputResponseData(
- resMsg.usersYesNoSelection);
- }
- break;
- case DISPLAY_TEXT:
- case LAUNCH_BROWSER:
- break;
- case SET_UP_CALL:
- mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null);
- // No need to send terminal response for SET UP CALL. The user's
- // confirmation result is send back using a dedicated ril message
- // invoked by the CommandInterface call above.
- mCurrntCmd = null;
- return;
- }
- break;
- case NO_RESPONSE_FROM_USER:
- case UICC_SESSION_TERM_BY_USER:
- case BACKWARD_MOVE_BY_USER:
- case USER_NOT_ACCEPT:
- resp = null;
- break;
- default:
- return;
- }
- sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp);
- mCurrntCmd = null;
- }
-
- private boolean isStkAppInstalled() {
- Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
- PackageManager pm = mContext.getPackageManager();
- List<ResolveInfo> broadcastReceivers =
- pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA);
- int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size();
-
- return (numReceiver > 0);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
deleted file mode 100644
index 8579535..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-abstract class ValueObject {
- abstract ComprehensionTlvTag getTag();
-}
-
-/**
- * Class for Command Detailes object of proactive commands from SIM.
- * {@hide}
- */
-class CommandDetails extends ValueObject implements Parcelable {
- public boolean compRequired;
- public int commandNumber;
- public int typeOfCommand;
- public int commandQualifier;
-
- public ComprehensionTlvTag getTag() {
- return ComprehensionTlvTag.COMMAND_DETAILS;
- }
-
- CommandDetails() {
- }
-
- public boolean compareTo(CommandDetails other) {
- return (this.compRequired == other.compRequired &&
- this.commandNumber == other.commandNumber &&
- this.commandQualifier == other.commandQualifier &&
- this.typeOfCommand == other.typeOfCommand);
- }
-
- public CommandDetails(Parcel in) {
- compRequired = true;
- commandNumber = in.readInt();
- typeOfCommand = in.readInt();
- commandQualifier = in.readInt();
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(commandNumber);
- dest.writeInt(typeOfCommand);
- dest.writeInt(commandQualifier);
- }
-
- public static final Parcelable.Creator<CommandDetails> CREATOR =
- new Parcelable.Creator<CommandDetails>() {
- public CommandDetails createFromParcel(Parcel in) {
- return new CommandDetails(in);
- }
-
- public CommandDetails[] newArray(int size) {
- return new CommandDetails[size];
- }
- };
-
- public int describeContents() {
- return 0;
- }
-
- @Override
- public String toString() {
- return "CmdDetails: compRequired=" + compRequired +
- " commandNumber=" + commandNumber +
- " typeOfCommand=" + typeOfCommand +
- " commandQualifier=" + commandQualifier;
- }
-}
-
-class DeviceIdentities extends ValueObject {
- public int sourceId;
- public int destinationId;
-
- ComprehensionTlvTag getTag() {
- return ComprehensionTlvTag.DEVICE_IDENTITIES;
- }
-}
-
-// Container class to hold icon identifier value.
-class IconId extends ValueObject {
- int recordNumber;
- boolean selfExplanatory;
-
- ComprehensionTlvTag getTag() {
- return ComprehensionTlvTag.ICON_ID;
- }
-}
-
-// Container class to hold item icon identifier list value.
-class ItemsIconId extends ValueObject {
- int [] recordNumbers;
- boolean selfExplanatory;
-
- ComprehensionTlvTag getTag() {
- return ComprehensionTlvTag.ITEM_ICON_ID_LIST;
- }
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
deleted file mode 100644
index 79f6ad2..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CommandParams.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-
-/**
- * Container class for proactive command parameters.
- *
- */
-class CommandParams {
- CommandDetails cmdDet;
-
- CommandParams(CommandDetails cmdDet) {
- this.cmdDet = cmdDet;
- }
-
- AppInterface.CommandType getCommandType() {
- return AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
- }
-
- boolean setIcon(Bitmap icon) { return true; }
-
- @Override
- public String toString() {
- return cmdDet.toString();
- }
-}
-
-class DisplayTextParams extends CommandParams {
- TextMessage textMsg;
-
- DisplayTextParams(CommandDetails cmdDet, TextMessage textMsg) {
- super(cmdDet);
- this.textMsg = textMsg;
- }
-
- boolean setIcon(Bitmap icon) {
- if (icon != null && textMsg != null) {
- textMsg.icon = icon;
- return true;
- }
- return false;
- }
-}
-
-class LaunchBrowserParams extends CommandParams {
- TextMessage confirmMsg;
- LaunchBrowserMode mode;
- String url;
-
- LaunchBrowserParams(CommandDetails cmdDet, TextMessage confirmMsg,
- String url, LaunchBrowserMode mode) {
- super(cmdDet);
- this.confirmMsg = confirmMsg;
- this.mode = mode;
- this.url = url;
- }
-
- boolean setIcon(Bitmap icon) {
- if (icon != null && confirmMsg != null) {
- confirmMsg.icon = icon;
- return true;
- }
- return false;
- }
-}
-
-class PlayToneParams extends CommandParams {
- TextMessage textMsg;
- ToneSettings settings;
-
- PlayToneParams(CommandDetails cmdDet, TextMessage textMsg,
- Tone tone, Duration duration, boolean vibrate) {
- super(cmdDet);
- this.textMsg = textMsg;
- this.settings = new ToneSettings(duration, tone, vibrate);
- }
-
- boolean setIcon(Bitmap icon) {
- if (icon != null && textMsg != null) {
- textMsg.icon = icon;
- return true;
- }
- return false;
- }
-}
-
-class CallSetupParams extends CommandParams {
- TextMessage confirmMsg;
- TextMessage callMsg;
-
- CallSetupParams(CommandDetails cmdDet, TextMessage confirmMsg,
- TextMessage callMsg) {
- super(cmdDet);
- this.confirmMsg = confirmMsg;
- this.callMsg = callMsg;
- }
-
- boolean setIcon(Bitmap icon) {
- if (icon == null) {
- return false;
- }
- if (confirmMsg != null && confirmMsg.icon == null) {
- confirmMsg.icon = icon;
- return true;
- } else if (callMsg != null && callMsg.icon == null) {
- callMsg.icon = icon;
- return true;
- }
- return false;
- }
-}
-
-class SelectItemParams extends CommandParams {
- Menu menu = null;
- boolean loadTitleIcon = false;
-
- SelectItemParams(CommandDetails cmdDet, Menu menu, boolean loadTitleIcon) {
- super(cmdDet);
- this.menu = menu;
- this.loadTitleIcon = loadTitleIcon;
- }
-
- boolean setIcon(Bitmap icon) {
- if (icon != null && menu != null) {
- if (loadTitleIcon && menu.titleIcon == null) {
- menu.titleIcon = icon;
- } else {
- for (Item item : menu.items) {
- if (item.icon != null) {
- continue;
- }
- item.icon = icon;
- break;
- }
- }
- return true;
- }
- return false;
- }
-}
-
-class GetInputParams extends CommandParams {
- Input input = null;
-
- GetInputParams(CommandDetails cmdDet, Input input) {
- super(cmdDet);
- this.input = input;
- }
-
- boolean setIcon(Bitmap icon) {
- if (icon != null && input != null) {
- input.icon = icon;
- }
- return true;
- }
-}
-
-/*
- * BIP (Bearer Independent Protocol) is the mechanism for SIM card applications
- * to access data connection through the mobile device.
- *
- * SIM utilizes proactive commands (OPEN CHANNEL, CLOSE CHANNEL, SEND DATA and
- * RECEIVE DATA to control/read/write data for BIP. Refer to ETSI TS 102 223 for
- * the details of proactive commands procedures and their structures.
- */
-class BIPClientParams extends CommandParams {
- TextMessage textMsg;
- boolean bHasAlphaId;
-
- BIPClientParams(CommandDetails cmdDet, TextMessage textMsg, boolean has_alpha_id) {
- super(cmdDet);
- this.textMsg = textMsg;
- this.bHasAlphaId = has_alpha_id;
- }
-
- boolean setIcon(Bitmap icon) {
- if (icon != null && textMsg != null) {
- textMsg.icon = icon;
- return true;
- }
- return false;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
deleted file mode 100644
index a554012..0000000
--- a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
+++ /dev/null
@@ -1,943 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Handler;
-import android.os.Message;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccFileHandler;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Factory class, used for decoding raw byte arrays, received from baseband,
- * into a CommandParams object.
- *
- */
-class CommandParamsFactory extends Handler {
- private static CommandParamsFactory sInstance = null;
- private IconLoader mIconLoader;
- private CommandParams mCmdParams = null;
- private int mIconLoadState = LOAD_NO_ICON;
- private RilMessageDecoder mCaller = null;
-
- // constants
- static final int MSG_ID_LOAD_ICON_DONE = 1;
-
- // loading icons state parameters.
- static final int LOAD_NO_ICON = 0;
- static final int LOAD_SINGLE_ICON = 1;
- static final int LOAD_MULTI_ICONS = 2;
-
- // Command Qualifier values for refresh command
- static final int REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE = 0x00;
- static final int REFRESH_NAA_INIT_AND_FILE_CHANGE = 0x02;
- static final int REFRESH_NAA_INIT = 0x03;
- static final int REFRESH_UICC_RESET = 0x04;
-
- // Command Qualifier values for PLI command
- static final int DTTZ_SETTING = 0x03;
- static final int LANGUAGE_SETTING = 0x04;
-
- static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
- IccFileHandler fh) {
- if (sInstance != null) {
- return sInstance;
- }
- if (fh != null) {
- return new CommandParamsFactory(caller, fh);
- }
- return null;
- }
-
- private CommandParamsFactory(RilMessageDecoder caller, IccFileHandler fh) {
- mCaller = caller;
- mIconLoader = IconLoader.getInstance(this, fh);
- }
-
- private CommandDetails processCommandDetails(List<ComprehensionTlv> ctlvs) {
- CommandDetails cmdDet = null;
-
- if (ctlvs != null) {
- // Search for the Command Details object.
- ComprehensionTlv ctlvCmdDet = searchForTag(
- ComprehensionTlvTag.COMMAND_DETAILS, ctlvs);
- if (ctlvCmdDet != null) {
- try {
- cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet);
- } catch (ResultException e) {
- CatLog.d(this,
- "processCommandDetails: Failed to procees command details e=" + e);
- }
- }
- }
- return cmdDet;
- }
-
- void make(BerTlv berTlv) {
- if (berTlv == null) {
- return;
- }
- // reset global state parameters.
- mCmdParams = null;
- mIconLoadState = LOAD_NO_ICON;
- // only proactive command messages are processed.
- if (berTlv.getTag() != BerTlv.BER_PROACTIVE_COMMAND_TAG) {
- sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
- return;
- }
- boolean cmdPending = false;
- List<ComprehensionTlv> ctlvs = berTlv.getComprehensionTlvs();
- // process command dtails from the tlv list.
- CommandDetails cmdDet = processCommandDetails(ctlvs);
- if (cmdDet == null) {
- sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
- return;
- }
-
- // extract command type enumeration from the raw value stored inside
- // the Command Details object.
- AppInterface.CommandType cmdType = AppInterface.CommandType
- .fromInt(cmdDet.typeOfCommand);
- if (cmdType == null) {
- // This PROACTIVE COMMAND is presently not handled. Hence set
- // result code as BEYOND_TERMINAL_CAPABILITY in TR.
- mCmdParams = new CommandParams(cmdDet);
- sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
- return;
- }
-
- try {
- switch (cmdType) {
- case SET_UP_MENU:
- cmdPending = processSelectItem(cmdDet, ctlvs);
- break;
- case SELECT_ITEM:
- cmdPending = processSelectItem(cmdDet, ctlvs);
- break;
- case DISPLAY_TEXT:
- cmdPending = processDisplayText(cmdDet, ctlvs);
- break;
- case SET_UP_IDLE_MODE_TEXT:
- cmdPending = processSetUpIdleModeText(cmdDet, ctlvs);
- break;
- case GET_INKEY:
- cmdPending = processGetInkey(cmdDet, ctlvs);
- break;
- case GET_INPUT:
- cmdPending = processGetInput(cmdDet, ctlvs);
- break;
- case SEND_DTMF:
- case SEND_SMS:
- case SEND_SS:
- case SEND_USSD:
- cmdPending = processEventNotify(cmdDet, ctlvs);
- break;
- case SET_UP_CALL:
- cmdPending = processSetupCall(cmdDet, ctlvs);
- break;
- case REFRESH:
- processRefresh(cmdDet, ctlvs);
- cmdPending = false;
- break;
- case LAUNCH_BROWSER:
- cmdPending = processLaunchBrowser(cmdDet, ctlvs);
- break;
- case PLAY_TONE:
- cmdPending = processPlayTone(cmdDet, ctlvs);
- break;
- case PROVIDE_LOCAL_INFORMATION:
- cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
- break;
- case OPEN_CHANNEL:
- case CLOSE_CHANNEL:
- case RECEIVE_DATA:
- case SEND_DATA:
- cmdPending = processBIPClient(cmdDet, ctlvs);
- break;
- default:
- // unsupported proactive commands
- mCmdParams = new CommandParams(cmdDet);
- sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
- return;
- }
- } catch (ResultException e) {
- CatLog.d(this, "make: caught ResultException e=" + e);
- mCmdParams = new CommandParams(cmdDet);
- sendCmdParams(e.result());
- return;
- }
- if (!cmdPending) {
- sendCmdParams(ResultCode.OK);
- }
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_ID_LOAD_ICON_DONE:
- sendCmdParams(setIcons(msg.obj));
- break;
- }
- }
-
- private ResultCode setIcons(Object data) {
- Bitmap[] icons = null;
- int iconIndex = 0;
-
- if (data == null) {
- return ResultCode.PRFRMD_ICON_NOT_DISPLAYED;
- }
- switch(mIconLoadState) {
- case LOAD_SINGLE_ICON:
- mCmdParams.setIcon((Bitmap) data);
- break;
- case LOAD_MULTI_ICONS:
- icons = (Bitmap[]) data;
- // set each item icon.
- for (Bitmap icon : icons) {
- mCmdParams.setIcon(icon);
- }
- break;
- }
- return ResultCode.OK;
- }
-
- private void sendCmdParams(ResultCode resCode) {
- mCaller.sendMsgParamsDecoded(resCode, mCmdParams);
- }
-
- /**
- * Search for a COMPREHENSION-TLV object with the given tag from a list
- *
- * @param tag A tag to search for
- * @param ctlvs List of ComprehensionTlv objects used to search in
- *
- * @return A ComprehensionTlv object that has the tag value of {@code tag}.
- * If no object is found with the tag, null is returned.
- */
- private ComprehensionTlv searchForTag(ComprehensionTlvTag tag,
- List<ComprehensionTlv> ctlvs) {
- Iterator<ComprehensionTlv> iter = ctlvs.iterator();
- return searchForNextTag(tag, iter);
- }
-
- /**
- * Search for the next COMPREHENSION-TLV object with the given tag from a
- * list iterated by {@code iter}. {@code iter} points to the object next to
- * the found object when this method returns. Used for searching the same
- * list for similar tags, usually item id.
- *
- * @param tag A tag to search for
- * @param iter Iterator for ComprehensionTlv objects used for search
- *
- * @return A ComprehensionTlv object that has the tag value of {@code tag}.
- * If no object is found with the tag, null is returned.
- */
- private ComprehensionTlv searchForNextTag(ComprehensionTlvTag tag,
- Iterator<ComprehensionTlv> iter) {
- int tagValue = tag.value();
- while (iter.hasNext()) {
- ComprehensionTlv ctlv = iter.next();
- if (ctlv.getTag() == tagValue) {
- return ctlv;
- }
- }
- return null;
- }
-
- /**
- * Processes DISPLAY_TEXT proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- * @throws ResultException
- */
- private boolean processDisplayText(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs)
- throws ResultException {
-
- CatLog.d(this, "process DisplayText");
-
- TextMessage textMsg = new TextMessage();
- IconId iconId = null;
-
- ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING,
- ctlvs);
- if (ctlv != null) {
- textMsg.text = ValueParser.retrieveTextString(ctlv);
- }
- // If the tlv object doesn't exist or the it is a null object reply
- // with command not understood.
- if (textMsg.text == null) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
-
- ctlv = searchForTag(ComprehensionTlvTag.IMMEDIATE_RESPONSE, ctlvs);
- if (ctlv != null) {
- textMsg.responseNeeded = false;
- }
- // parse icon identifier
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- iconId = ValueParser.retrieveIconId(ctlv);
- textMsg.iconSelfExplanatory = iconId.selfExplanatory;
- }
- // parse tone duration
- ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
- if (ctlv != null) {
- textMsg.duration = ValueParser.retrieveDuration(ctlv);
- }
-
- // Parse command qualifier parameters.
- textMsg.isHighPriority = (cmdDet.commandQualifier & 0x01) != 0;
- textMsg.userClear = (cmdDet.commandQualifier & 0x80) != 0;
-
- mCmdParams = new DisplayTextParams(cmdDet, textMsg);
-
- if (iconId != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- mIconLoader.loadIcon(iconId.recordNumber, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-
- /**
- * Processes SET_UP_IDLE_MODE_TEXT proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- * @throws ResultException
- */
- private boolean processSetUpIdleModeText(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
-
- CatLog.d(this, "process SetUpIdleModeText");
-
- TextMessage textMsg = new TextMessage();
- IconId iconId = null;
-
- ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING,
- ctlvs);
- if (ctlv != null) {
- textMsg.text = ValueParser.retrieveTextString(ctlv);
- }
- // load icons only when text exist.
- if (textMsg.text != null) {
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- iconId = ValueParser.retrieveIconId(ctlv);
- textMsg.iconSelfExplanatory = iconId.selfExplanatory;
- }
- }
-
- mCmdParams = new DisplayTextParams(cmdDet, textMsg);
-
- if (iconId != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- mIconLoader.loadIcon(iconId.recordNumber, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-
- /**
- * Processes GET_INKEY proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- * @throws ResultException
- */
- private boolean processGetInkey(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
-
- CatLog.d(this, "process GetInkey");
-
- Input input = new Input();
- IconId iconId = null;
-
- ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING,
- ctlvs);
- if (ctlv != null) {
- input.text = ValueParser.retrieveTextString(ctlv);
- } else {
- throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
- }
- // parse icon identifier
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- iconId = ValueParser.retrieveIconId(ctlv);
- }
-
- // parse duration
- ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
- if (ctlv != null) {
- input.duration = ValueParser.retrieveDuration(ctlv);
- }
-
- input.minLen = 1;
- input.maxLen = 1;
-
- input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0;
- input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0;
- input.yesNo = (cmdDet.commandQualifier & 0x04) != 0;
- input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0;
- input.echo = true;
-
- mCmdParams = new GetInputParams(cmdDet, input);
-
- if (iconId != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- mIconLoader.loadIcon(iconId.recordNumber, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-
- /**
- * Processes GET_INPUT proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- * @throws ResultException
- */
- private boolean processGetInput(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
-
- CatLog.d(this, "process GetInput");
-
- Input input = new Input();
- IconId iconId = null;
-
- ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING,
- ctlvs);
- if (ctlv != null) {
- input.text = ValueParser.retrieveTextString(ctlv);
- } else {
- throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
- }
-
- ctlv = searchForTag(ComprehensionTlvTag.RESPONSE_LENGTH, ctlvs);
- if (ctlv != null) {
- try {
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- input.minLen = rawValue[valueIndex] & 0xff;
- input.maxLen = rawValue[valueIndex + 1] & 0xff;
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- } else {
- throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
- }
-
- ctlv = searchForTag(ComprehensionTlvTag.DEFAULT_TEXT, ctlvs);
- if (ctlv != null) {
- input.defaultText = ValueParser.retrieveTextString(ctlv);
- }
- // parse icon identifier
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- iconId = ValueParser.retrieveIconId(ctlv);
- }
-
- input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0;
- input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0;
- input.echo = (cmdDet.commandQualifier & 0x04) == 0;
- input.packed = (cmdDet.commandQualifier & 0x08) != 0;
- input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0;
-
- mCmdParams = new GetInputParams(cmdDet, input);
-
- if (iconId != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- mIconLoader.loadIcon(iconId.recordNumber, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-
- /**
- * Processes REFRESH proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- */
- private boolean processRefresh(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) {
-
- CatLog.d(this, "process Refresh");
-
- // REFRESH proactive command is rerouted by the baseband and handled by
- // the telephony layer. IDLE TEXT should be removed for a REFRESH command
- // with "initialization" or "reset"
- switch (cmdDet.commandQualifier) {
- case REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE:
- case REFRESH_NAA_INIT_AND_FILE_CHANGE:
- case REFRESH_NAA_INIT:
- case REFRESH_UICC_RESET:
- mCmdParams = new DisplayTextParams(cmdDet, null);
- break;
- }
- return false;
- }
-
- /**
- * Processes SELECT_ITEM proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- * @throws ResultException
- */
- private boolean processSelectItem(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
-
- CatLog.d(this, "process SelectItem");
-
- Menu menu = new Menu();
- IconId titleIconId = null;
- ItemsIconId itemsIconId = null;
- Iterator<ComprehensionTlv> iter = ctlvs.iterator();
-
- ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID,
- ctlvs);
- if (ctlv != null) {
- menu.title = ValueParser.retrieveAlphaId(ctlv);
- }
-
- while (true) {
- ctlv = searchForNextTag(ComprehensionTlvTag.ITEM, iter);
- if (ctlv != null) {
- menu.items.add(ValueParser.retrieveItem(ctlv));
- } else {
- break;
- }
- }
-
- // We must have at least one menu item.
- if (menu.items.size() == 0) {
- throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
- }
-
- ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs);
- if (ctlv != null) {
- // CAT items are listed 1...n while list start at 0, need to
- // subtract one.
- menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1;
- }
-
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- titleIconId = ValueParser.retrieveIconId(ctlv);
- menu.titleIconSelfExplanatory = titleIconId.selfExplanatory;
- }
-
- ctlv = searchForTag(ComprehensionTlvTag.ITEM_ICON_ID_LIST, ctlvs);
- if (ctlv != null) {
- mIconLoadState = LOAD_MULTI_ICONS;
- itemsIconId = ValueParser.retrieveItemsIconId(ctlv);
- menu.itemsIconSelfExplanatory = itemsIconId.selfExplanatory;
- }
-
- boolean presentTypeSpecified = (cmdDet.commandQualifier & 0x01) != 0;
- if (presentTypeSpecified) {
- if ((cmdDet.commandQualifier & 0x02) == 0) {
- menu.presentationType = PresentationType.DATA_VALUES;
- } else {
- menu.presentationType = PresentationType.NAVIGATION_OPTIONS;
- }
- }
- menu.softKeyPreferred = (cmdDet.commandQualifier & 0x04) != 0;
- menu.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0;
-
- mCmdParams = new SelectItemParams(cmdDet, menu, titleIconId != null);
-
- // Load icons data if needed.
- switch(mIconLoadState) {
- case LOAD_NO_ICON:
- return false;
- case LOAD_SINGLE_ICON:
- mIconLoader.loadIcon(titleIconId.recordNumber, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- break;
- case LOAD_MULTI_ICONS:
- int[] recordNumbers = itemsIconId.recordNumbers;
- if (titleIconId != null) {
- // Create a new array for all the icons (title and items).
- recordNumbers = new int[itemsIconId.recordNumbers.length + 1];
- recordNumbers[0] = titleIconId.recordNumber;
- System.arraycopy(itemsIconId.recordNumbers, 0, recordNumbers,
- 1, itemsIconId.recordNumbers.length);
- }
- mIconLoader.loadIcons(recordNumbers, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- break;
- }
- return true;
- }
-
- /**
- * Processes EVENT_NOTIFY message from baseband.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- */
- private boolean processEventNotify(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
-
- CatLog.d(this, "process EventNotify");
-
- TextMessage textMsg = new TextMessage();
- IconId iconId = null;
-
- ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID,
- ctlvs);
- textMsg.text = ValueParser.retrieveAlphaId(ctlv);
-
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- iconId = ValueParser.retrieveIconId(ctlv);
- textMsg.iconSelfExplanatory = iconId.selfExplanatory;
- }
-
- textMsg.responseNeeded = false;
- mCmdParams = new DisplayTextParams(cmdDet, textMsg);
-
- if (iconId != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- mIconLoader.loadIcon(iconId.recordNumber, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-
- /**
- * Processes SET_UP_EVENT_LIST proactive command from the SIM card.
- *
- * @param cmdDet Command Details object retrieved.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- */
- private boolean processSetUpEventList(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) {
-
- CatLog.d(this, "process SetUpEventList");
- //
- // ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST,
- // ctlvs);
- // if (ctlv != null) {
- // try {
- // byte[] rawValue = ctlv.getRawValue();
- // int valueIndex = ctlv.getValueIndex();
- // int valueLen = ctlv.getLength();
- //
- // } catch (IndexOutOfBoundsException e) {}
- // }
- return true;
- }
-
- /**
- * Processes LAUNCH_BROWSER proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- * @throws ResultException
- */
- private boolean processLaunchBrowser(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
-
- CatLog.d(this, "process LaunchBrowser");
-
- TextMessage confirmMsg = new TextMessage();
- IconId iconId = null;
- String url = null;
-
- ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.URL, ctlvs);
- if (ctlv != null) {
- try {
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- int valueLen = ctlv.getLength();
- if (valueLen > 0) {
- url = GsmAlphabet.gsm8BitUnpackedToString(rawValue,
- valueIndex, valueLen);
- } else {
- url = null;
- }
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- }
-
- // parse alpha identifier.
- ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
- confirmMsg.text = ValueParser.retrieveAlphaId(ctlv);
-
- // parse icon identifier
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- iconId = ValueParser.retrieveIconId(ctlv);
- confirmMsg.iconSelfExplanatory = iconId.selfExplanatory;
- }
-
- // parse command qualifier value.
- LaunchBrowserMode mode;
- switch (cmdDet.commandQualifier) {
- case 0x00:
- default:
- mode = LaunchBrowserMode.LAUNCH_IF_NOT_ALREADY_LAUNCHED;
- break;
- case 0x02:
- mode = LaunchBrowserMode.USE_EXISTING_BROWSER;
- break;
- case 0x03:
- mode = LaunchBrowserMode.LAUNCH_NEW_BROWSER;
- break;
- }
-
- mCmdParams = new LaunchBrowserParams(cmdDet, confirmMsg, url, mode);
-
- if (iconId != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- mIconLoader.loadIcon(iconId.recordNumber, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-
- /**
- * Processes PLAY_TONE proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.t
- * @throws ResultException
- */
- private boolean processPlayTone(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
-
- CatLog.d(this, "process PlayTone");
-
- Tone tone = null;
- TextMessage textMsg = new TextMessage();
- Duration duration = null;
- IconId iconId = null;
-
- ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TONE, ctlvs);
- if (ctlv != null) {
- // Nothing to do for null objects.
- if (ctlv.getLength() > 0) {
- try {
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- int toneVal = rawValue[valueIndex];
- tone = Tone.fromInt(toneVal);
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(
- ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- }
- }
- // parse alpha identifier
- ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
- if (ctlv != null) {
- textMsg.text = ValueParser.retrieveAlphaId(ctlv);
- }
- // parse tone duration
- ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
- if (ctlv != null) {
- duration = ValueParser.retrieveDuration(ctlv);
- }
- // parse icon identifier
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- iconId = ValueParser.retrieveIconId(ctlv);
- textMsg.iconSelfExplanatory = iconId.selfExplanatory;
- }
-
- boolean vibrate = (cmdDet.commandQualifier & 0x01) != 0x00;
-
- textMsg.responseNeeded = false;
- mCmdParams = new PlayToneParams(cmdDet, textMsg, tone, duration, vibrate);
-
- if (iconId != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- mIconLoader.loadIcon(iconId.recordNumber, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-
- /**
- * Processes SETUP_CALL proactive command from the SIM card.
- *
- * @param cmdDet Command Details object retrieved from the proactive command
- * object
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- * @return true if the command is processing is pending and additional
- * asynchronous processing is required.
- */
- private boolean processSetupCall(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
- CatLog.d(this, "process SetupCall");
-
- Iterator<ComprehensionTlv> iter = ctlvs.iterator();
- ComprehensionTlv ctlv = null;
- // User confirmation phase message.
- TextMessage confirmMsg = new TextMessage();
- // Call set up phase message.
- TextMessage callMsg = new TextMessage();
- IconId confirmIconId = null;
- IconId callIconId = null;
-
- // get confirmation message string.
- ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter);
- confirmMsg.text = ValueParser.retrieveAlphaId(ctlv);
-
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- confirmIconId = ValueParser.retrieveIconId(ctlv);
- confirmMsg.iconSelfExplanatory = confirmIconId.selfExplanatory;
- }
-
- // get call set up message string.
- ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter);
- if (ctlv != null) {
- callMsg.text = ValueParser.retrieveAlphaId(ctlv);
- }
-
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- callIconId = ValueParser.retrieveIconId(ctlv);
- callMsg.iconSelfExplanatory = callIconId.selfExplanatory;
- }
-
- mCmdParams = new CallSetupParams(cmdDet, confirmMsg, callMsg);
-
- if (confirmIconId != null || callIconId != null) {
- mIconLoadState = LOAD_MULTI_ICONS;
- int[] recordNumbers = new int[2];
- recordNumbers[0] = confirmIconId != null
- ? confirmIconId.recordNumber : -1;
- recordNumbers[1] = callIconId != null ? callIconId.recordNumber
- : -1;
-
- mIconLoader.loadIcons(recordNumbers, this
- .obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-
- private boolean processProvideLocalInfo(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
- throws ResultException {
- CatLog.d(this, "process ProvideLocalInfo");
- switch (cmdDet.commandQualifier) {
- case DTTZ_SETTING:
- CatLog.d(this, "PLI [DTTZ_SETTING]");
- mCmdParams = new CommandParams(cmdDet);
- break;
- case LANGUAGE_SETTING:
- CatLog.d(this, "PLI [LANGUAGE_SETTING]");
- mCmdParams = new CommandParams(cmdDet);
- break;
- default:
- CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported");
- mCmdParams = new CommandParams(cmdDet);
- throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY);
- }
- return false;
- }
-
- private boolean processBIPClient(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) throws ResultException {
- AppInterface.CommandType commandType =
- AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
- if (commandType != null) {
- CatLog.d(this, "process "+ commandType.name());
- }
-
- TextMessage textMsg = new TextMessage();
- IconId iconId = null;
- ComprehensionTlv ctlv = null;
- boolean has_alpha_id = false;
-
- // parse alpha identifier
- ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
- if (ctlv != null) {
- textMsg.text = ValueParser.retrieveAlphaId(ctlv);
- CatLog.d(this, "alpha TLV text=" + textMsg.text);
- has_alpha_id = true;
- }
-
- // parse icon identifier
- ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
- if (ctlv != null) {
- iconId = ValueParser.retrieveIconId(ctlv);
- textMsg.iconSelfExplanatory = iconId.selfExplanatory;
- }
-
- textMsg.responseNeeded = false;
- mCmdParams = new BIPClientParams(cmdDet, textMsg, has_alpha_id);
-
- if (iconId != null) {
- mIconLoadState = LOAD_SINGLE_ICON;
- mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
- return true;
- }
- return false;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
deleted file mode 100644
index 22cd5a4..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2011 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.cat;
-
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Class for representing COMPREHENSION-TLV objects.
- *
- * @see "ETSI TS 101 220 subsection 7.1.1"
- *
- * {@hide}
- */
-class ComprehensionTlv {
- private static final String LOG_TAG = "ComprehensionTlv";
- private int mTag;
- private boolean mCr;
- private int mLength;
- private int mValueIndex;
- private byte[] mRawValue;
-
- /**
- * Constructor. Private on purpose. Use
- * {@link #decodeMany(byte[], int) decodeMany} or
- * {@link #decode(byte[], int) decode} method.
- *
- * @param tag The tag for this object
- * @param cr Comprehension Required flag
- * @param length Length of the value
- * @param data Byte array containing the value
- * @param valueIndex Index in data at which the value starts
- */
- protected ComprehensionTlv(int tag, boolean cr, int length, byte[] data,
- int valueIndex) {
- mTag = tag;
- mCr = cr;
- mLength = length;
- mValueIndex = valueIndex;
- mRawValue = data;
- }
-
- public int getTag() {
- return mTag;
- }
-
- public boolean isComprehensionRequired() {
- return mCr;
- }
-
- public int getLength() {
- return mLength;
- }
-
- public int getValueIndex() {
- return mValueIndex;
- }
-
- public byte[] getRawValue() {
- return mRawValue;
- }
-
- /**
- * Parses a list of COMPREHENSION-TLV objects from a byte array.
- *
- * @param data A byte array containing data to be parsed
- * @param startIndex Index in data at which to start parsing
- * @return A list of COMPREHENSION-TLV objects parsed
- * @throws ResultException
- */
- public static List<ComprehensionTlv> decodeMany(byte[] data, int startIndex)
- throws ResultException {
- ArrayList<ComprehensionTlv> items = new ArrayList<ComprehensionTlv>();
- int endIndex = data.length;
- while (startIndex < endIndex) {
- ComprehensionTlv ctlv = ComprehensionTlv.decode(data, startIndex);
- if (ctlv != null) {
- items.add(ctlv);
- startIndex = ctlv.mValueIndex + ctlv.mLength;
- } else {
- CatLog.d(LOG_TAG, "decodeMany: ctlv is null, stop decoding");
- break;
- }
- }
-
- return items;
- }
-
- /**
- * Parses an COMPREHENSION-TLV object from a byte array.
- *
- * @param data A byte array containing data to be parsed
- * @param startIndex Index in data at which to start parsing
- * @return A COMPREHENSION-TLV object parsed
- * @throws ResultException
- */
- public static ComprehensionTlv decode(byte[] data, int startIndex)
- throws ResultException {
- int curIndex = startIndex;
- int endIndex = data.length;
-
- try {
- /* tag */
- int tag;
- boolean cr; // Comprehension required flag
- int temp = data[curIndex++] & 0xff;
- switch (temp) {
- case 0:
- case 0xff:
- case 0x80:
- Log.d("CAT ", "decode: unexpected first tag byte=" + Integer.toHexString(temp) +
- ", startIndex=" + startIndex + " curIndex=" + curIndex +
- " endIndex=" + endIndex);
- // Return null which will stop decoding, this has occurred
- // with Ghana MTN simcard and JDI simcard.
- return null;
-
- case 0x7f: // tag is in three-byte format
- tag = ((data[curIndex] & 0xff) << 8)
- | (data[curIndex + 1] & 0xff);
- cr = (tag & 0x8000) != 0;
- tag &= ~0x8000;
- curIndex += 2;
- break;
-
- default: // tag is in single-byte format
- tag = temp;
- cr = (tag & 0x80) != 0;
- tag &= ~0x80;
- break;
- }
-
- /* length */
- int length;
- temp = data[curIndex++] & 0xff;
- if (temp < 0x80) {
- length = temp;
- } else if (temp == 0x81) {
- length = data[curIndex++] & 0xff;
- if (length < 0x80) {
- throw new ResultException(
- ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- "length < 0x80 length=" + Integer.toHexString(length) +
- " startIndex=" + startIndex + " curIndex=" + curIndex +
- " endIndex=" + endIndex);
- }
- } else if (temp == 0x82) {
- length = ((data[curIndex] & 0xff) << 8)
- | (data[curIndex + 1] & 0xff);
- curIndex += 2;
- if (length < 0x100) {
- throw new ResultException(
- ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- "two byte length < 0x100 length=" + Integer.toHexString(length) +
- " startIndex=" + startIndex + " curIndex=" + curIndex +
- " endIndex=" + endIndex);
- }
- } else if (temp == 0x83) {
- length = ((data[curIndex] & 0xff) << 16)
- | ((data[curIndex + 1] & 0xff) << 8)
- | (data[curIndex + 2] & 0xff);
- curIndex += 3;
- if (length < 0x10000) {
- throw new ResultException(
- ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- "three byte length < 0x10000 length=0x" + Integer.toHexString(length) +
- " startIndex=" + startIndex + " curIndex=" + curIndex +
- " endIndex=" + endIndex);
- }
- } else {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- "Bad length modifer=" + temp +
- " startIndex=" + startIndex + " curIndex=" + curIndex +
- " endIndex=" + endIndex);
-
- }
-
- return new ComprehensionTlv(tag, cr, length, data, curIndex);
-
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD,
- "IndexOutOfBoundsException" + " startIndex=" + startIndex +
- " curIndex=" + curIndex + " endIndex=" + endIndex);
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
deleted file mode 100644
index 973dbc8..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2011 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.cat;
-
-/**
- * Enumeration for representing the tag value of COMPREHENSION-TLV objects. If
- * you want to get the actual value, call {@link #value() value} method.
- *
- * {@hide}
- */
-public enum ComprehensionTlvTag {
- COMMAND_DETAILS(0x01),
- DEVICE_IDENTITIES(0x02),
- RESULT(0x03),
- DURATION(0x04),
- ALPHA_ID(0x05),
- ADDRESS(0x06),
- USSD_STRING(0x0a),
- SMS_TPDU(0x0b),
- TEXT_STRING(0x0d),
- TONE(0x0e),
- ITEM(0x0f),
- ITEM_ID(0x10),
- RESPONSE_LENGTH(0x11),
- FILE_LIST(0x12),
- HELP_REQUEST(0x15),
- DEFAULT_TEXT(0x17),
- EVENT_LIST(0x19),
- ICON_ID(0x1e),
- ITEM_ICON_ID_LIST(0x1f),
- IMMEDIATE_RESPONSE(0x2b),
- LANGUAGE(0x2d),
- URL(0x31),
- BROWSER_TERMINATION_CAUSE(0x34),
- TEXT_ATTRIBUTE(0x50);
-
- private int mValue;
-
- ComprehensionTlvTag(int value) {
- mValue = value;
- }
-
- /**
- * Returns the actual value of this COMPREHENSION-TLV object.
- *
- * @return Actual tag value of this object
- */
- public int value() {
- return mValue;
- }
-
- public static ComprehensionTlvTag fromInt(int value) {
- for (ComprehensionTlvTag e : ComprehensionTlvTag.values()) {
- if (e.mValue == value) {
- return e;
- }
- }
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/Duration.java b/telephony/java/com/android/internal/telephony/cat/Duration.java
deleted file mode 100644
index e8cd404..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Duration.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-
-/**
- * Class for representing "Duration" object for CAT.
- *
- * {@hide}
- */
-public class Duration implements Parcelable {
- public int timeInterval;
- public TimeUnit timeUnit;
-
- public enum TimeUnit {
- MINUTE(0x00),
- SECOND(0x01),
- TENTH_SECOND(0x02);
-
- private int mValue;
-
- TimeUnit(int value) {
- mValue = value;
- }
-
- public int value() {
- return mValue;
- }
- }
-
- /**
- * @param timeInterval Between 1 and 255 inclusive.
- */
- public Duration(int timeInterval, TimeUnit timeUnit) {
- this.timeInterval = timeInterval;
- this.timeUnit = timeUnit;
- }
-
- private Duration(Parcel in) {
- timeInterval = in.readInt();
- timeUnit = TimeUnit.values()[in.readInt()];
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(timeInterval);
- dest.writeInt(timeUnit.ordinal());
- }
-
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<Duration> CREATOR = new Parcelable.Creator<Duration>() {
- public Duration createFromParcel(Parcel in) {
- return new Duration(in);
- }
-
- public Duration[] newArray(int size) {
- return new Duration[size];
- }
- };
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/FontSize.java b/telephony/java/com/android/internal/telephony/cat/FontSize.java
deleted file mode 100644
index 02c7ea0..0000000
--- a/telephony/java/com/android/internal/telephony/cat/FontSize.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.cat;
-
-
-/**
- * Enumeration for representing text font size.
- *
- * {@hide}
- */
-public enum FontSize {
- NORMAL(0x0),
- LARGE(0x1),
- SMALL(0x2);
-
- private int mValue;
-
- FontSize(int value) {
- mValue = value;
- }
-
- /**
- * Create a FontSize object.
- * @param value Integer value to be converted to a FontSize object.
- * @return FontSize object whose value is {@code value}. If no
- * FontSize object has that value, null is returned.
- */
- public static FontSize fromInt(int value) {
- for (FontSize e : FontSize.values()) {
- if (e.mValue == value) {
- return e;
- }
- }
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/IconLoader.java b/telephony/java/com/android/internal/telephony/cat/IconLoader.java
deleted file mode 100644
index 2fa1811..0000000
--- a/telephony/java/com/android/internal/telephony/cat/IconLoader.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * 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.cat;
-
-import com.android.internal.telephony.IccFileHandler;
-
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.HashMap;
-
-/**
- * Class for loading icons from the SIM card. Has two states: single, for loading
- * one icon. Multi, for loading icons list.
- *
- */
-class IconLoader extends Handler {
- // members
- private int mState = STATE_SINGLE_ICON;
- private ImageDescriptor mId = null;
- private Bitmap mCurrentIcon = null;
- private int mRecordNumber;
- private IccFileHandler mSimFH = null;
- private Message mEndMsg = null;
- private byte[] mIconData = null;
- // multi icons state members
- private int[] mRecordNumbers = null;
- private int mCurrentRecordIndex = 0;
- private Bitmap[] mIcons = null;
- private HashMap<Integer, Bitmap> mIconsCache = null;
-
- private static IconLoader sLoader = null;
-
- // Loader state values.
- private static final int STATE_SINGLE_ICON = 1;
- private static final int STATE_MULTI_ICONS = 2;
-
- // Finished loading single record from a linear-fixed EF-IMG.
- private static final int EVENT_READ_EF_IMG_RECOED_DONE = 1;
- // Finished loading single icon from a Transparent DF-Graphics.
- private static final int EVENT_READ_ICON_DONE = 2;
- // Finished loading single colour icon lookup table.
- private static final int EVENT_READ_CLUT_DONE = 3;
-
- // Color lookup table offset inside the EF.
- private static final int CLUT_LOCATION_OFFSET = 4;
- // CLUT entry size, {Red, Green, Black}
- private static final int CLUT_ENTRY_SIZE = 3;
-
-
- private IconLoader(Looper looper , IccFileHandler fh) {
- super(looper);
- mSimFH = fh;
-
- mIconsCache = new HashMap<Integer, Bitmap>(50);
- }
-
- static IconLoader getInstance(Handler caller, IccFileHandler fh) {
- if (sLoader != null) {
- return sLoader;
- }
- if (fh != null) {
- HandlerThread thread = new HandlerThread("Cat Icon Loader");
- thread.start();
- return new IconLoader(thread.getLooper(), fh);
- }
- return null;
- }
-
- void loadIcons(int[] recordNumbers, Message msg) {
- if (recordNumbers == null || recordNumbers.length == 0 || msg == null) {
- return;
- }
- mEndMsg = msg;
- // initialize multi icons load variables.
- mIcons = new Bitmap[recordNumbers.length];
- mRecordNumbers = recordNumbers;
- mCurrentRecordIndex = 0;
- mState = STATE_MULTI_ICONS;
- startLoadingIcon(recordNumbers[0]);
- }
-
- void loadIcon(int recordNumber, Message msg) {
- if (msg == null) {
- return;
- }
- mEndMsg = msg;
- mState = STATE_SINGLE_ICON;
- startLoadingIcon(recordNumber);
- }
-
- private void startLoadingIcon(int recordNumber) {
- // Reset the load variables.
- mId = null;
- mIconData = null;
- mCurrentIcon = null;
- mRecordNumber = recordNumber;
-
- // make sure the icon was not already loaded and saved in the local cache.
- if (mIconsCache.containsKey(recordNumber)) {
- mCurrentIcon = mIconsCache.get(recordNumber);
- postIcon();
- return;
- }
-
- // start the first phase ==> loading Image Descriptor.
- readId();
- }
-
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- try {
- switch (msg.what) {
- case EVENT_READ_EF_IMG_RECOED_DONE:
- ar = (AsyncResult) msg.obj;
- if (handleImageDescriptor((byte[]) ar.result)) {
- readIconData();
- } else {
- throw new Exception("Unable to parse image descriptor");
- }
- break;
- case EVENT_READ_ICON_DONE:
- ar = (AsyncResult) msg.obj;
- byte[] rawData = ((byte[]) ar.result);
- if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_BASIC) {
- mCurrentIcon = parseToBnW(rawData, rawData.length);
- mIconsCache.put(mRecordNumber, mCurrentIcon);
- postIcon();
- } else if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_COLOUR) {
- mIconData = rawData;
- readClut();
- }
- break;
- case EVENT_READ_CLUT_DONE:
- ar = (AsyncResult) msg.obj;
- byte [] clut = ((byte[]) ar.result);
- mCurrentIcon = parseToRGB(mIconData, mIconData.length,
- false, clut);
- mIconsCache.put(mRecordNumber, mCurrentIcon);
- postIcon();
- break;
- }
- } catch (Exception e) {
- CatLog.d(this, "Icon load failed");
- // post null icon back to the caller.
- postIcon();
- }
- }
-
- /**
- * Handles Image descriptor parsing and required processing. This is the
- * first step required to handle retrieving icons from the SIM.
- *
- * @param data byte [] containing Image Instance descriptor as defined in
- * TS 51.011.
- */
- private boolean handleImageDescriptor(byte[] rawData) {
- mId = ImageDescriptor.parse(rawData, 1);
- if (mId == null) {
- return false;
- }
- return true;
- }
-
- // Start reading colour lookup table from SIM card.
- private void readClut() {
- int length = mIconData[3] * CLUT_ENTRY_SIZE;
- Message msg = this.obtainMessage(EVENT_READ_CLUT_DONE);
- mSimFH.loadEFImgTransparent(mId.imageId,
- mIconData[CLUT_LOCATION_OFFSET],
- mIconData[CLUT_LOCATION_OFFSET + 1], length, msg);
- }
-
- // Start reading Image Descriptor from SIM card.
- private void readId() {
- if (mRecordNumber < 0) {
- mCurrentIcon = null;
- postIcon();
- return;
- }
- Message msg = this.obtainMessage(EVENT_READ_EF_IMG_RECOED_DONE);
- mSimFH.loadEFImgLinearFixed(mRecordNumber, msg);
- }
-
- // Start reading icon bytes array from SIM card.
- private void readIconData() {
- Message msg = this.obtainMessage(EVENT_READ_ICON_DONE);
- mSimFH.loadEFImgTransparent(mId.imageId, 0, 0, mId.length ,msg);
- }
-
- // When all is done pass icon back to caller.
- private void postIcon() {
- if (mState == STATE_SINGLE_ICON) {
- mEndMsg.obj = mCurrentIcon;
- mEndMsg.sendToTarget();
- } else if (mState == STATE_MULTI_ICONS) {
- mIcons[mCurrentRecordIndex++] = mCurrentIcon;
- // If not all icons were loaded, start loading the next one.
- if (mCurrentRecordIndex < mRecordNumbers.length) {
- startLoadingIcon(mRecordNumbers[mCurrentRecordIndex]);
- } else {
- mEndMsg.obj = mIcons;
- mEndMsg.sendToTarget();
- }
- }
- }
-
- /**
- * Convert a TS 131.102 image instance of code scheme '11' into Bitmap
- * @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;
- int height = data[valueIndex++] & 0xFF;
- int numOfPixels = width*height;
-
- int[] pixels = new int[numOfPixels];
-
- int pixelIndex = 0;
- int bitIndex = 7;
- byte currentByte = 0x00;
- while (pixelIndex < numOfPixels) {
- // reassign data and index for every byte (8 bits).
- if (pixelIndex % 8 == 0) {
- currentByte = data[valueIndex++];
- bitIndex = 7;
- }
- pixels[pixelIndex++] = bitToBnW((currentByte >> bitIndex-- ) & 0x01);
- }
-
- if (pixelIndex != numOfPixels) {
- CatLog.d("IconLoader", "parseToBnW; size error");
- }
- return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
- }
-
- /**
- * Decode one bit to a black and white color:
- * 0 is black
- * 1 is white
- * @param bit to decode
- * @return RGB color
- */
- private static int bitToBnW(int bit){
- if(bit == 1){
- return Color.WHITE;
- } else {
- return Color.BLACK;
- }
- }
-
- /**
- * 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
- * @param clut coulor lookup table
- * @return The color bitmap
- */
- public static Bitmap parseToRGB(byte[] data, int length,
- boolean transparency, byte[] clut) {
- int valueIndex = 0;
- int width = data[valueIndex++] & 0xFF;
- int height = data[valueIndex++] & 0xFF;
- int bitsPerImg = data[valueIndex++] & 0xFF;
- int numOfClutEntries = data[valueIndex++] & 0xFF;
-
- if (true == transparency) {
- clut[numOfClutEntries - 1] = Color.TRANSPARENT;
- }
-
- int numOfPixels = width * height;
- int[] pixels = new int[numOfPixels];
-
- valueIndex = 6;
- int pixelIndex = 0;
- int bitsStartOffset = 8 - bitsPerImg;
- int bitIndex = bitsStartOffset;
- byte currentByte = data[valueIndex++];
- int mask = getMask(bitsPerImg);
- boolean bitsOverlaps = (8 % bitsPerImg == 0);
- while (pixelIndex < numOfPixels) {
- // reassign data and index for every byte (8 bits).
- if (bitIndex < 0) {
- currentByte = data[valueIndex++];
- bitIndex = bitsOverlaps ? (bitsStartOffset) : (bitIndex * -1);
- }
- int clutEntry = ((currentByte >> bitIndex) & mask);
- int clutIndex = clutEntry * CLUT_ENTRY_SIZE;
- pixels[pixelIndex++] = Color.rgb(clut[clutIndex],
- clut[clutIndex + 1], clut[clutIndex + 2]);
- bitIndex -= bitsPerImg;
- }
-
- return Bitmap.createBitmap(pixels, width, height,
- Bitmap.Config.ARGB_8888);
- }
-
- /**
- * Calculate bit mask for a given number of bits. The mask should enable to
- * make a bitwise and to the given number of bits.
- * @param numOfBits number of bits to calculate mask for.
- * @return bit mask
- */
- private static int getMask(int numOfBits) {
- int mask = 0x00;
-
- switch (numOfBits) {
- case 1:
- mask = 0x01;
- break;
- case 2:
- mask = 0x03;
- break;
- case 3:
- mask = 0x07;
- break;
- case 4:
- mask = 0x0F;
- break;
- case 5:
- mask = 0x1F;
- break;
- case 6:
- mask = 0x3F;
- break;
- case 7:
- mask = 0x7F;
- break;
- case 8:
- mask = 0xFF;
- break;
- }
- return mask;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
deleted file mode 100644
index 711d977..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.cat;
-
-/**
- * {@hide}
- */
-public class ImageDescriptor {
- // members
- int width;
- int height;
- int codingScheme;
- int imageId;
- int highOffset;
- int lowOffset;
- int length;
-
- // constants
- static final int CODING_SCHEME_BASIC = 0x11;
- static final int CODING_SCHEME_COLOUR = 0x21;
-
- // public static final int ID_LENGTH = 9;
- // ID_LENGTH substituted by IccFileHandlerBase.GET_RESPONSE_EF_IMG_SIZE_BYTES
-
- ImageDescriptor() {
- width = 0;
- height = 0;
- codingScheme = 0;
- imageId = 0;
- highOffset = 0;
- lowOffset = 0;
- length = 0;
- }
-
- /**
- * Extract descriptor information about image instance.
- *
- * @param rawData
- * @param valueIndex
- * @return ImageDescriptor
- */
- static ImageDescriptor parse(byte[] rawData, int valueIndex) {
- ImageDescriptor d = new ImageDescriptor();
- try {
- d.width = rawData[valueIndex++] & 0xff;
- d.height = rawData[valueIndex++] & 0xff;
- d.codingScheme = rawData[valueIndex++] & 0xff;
-
- // parse image id
- d.imageId = (rawData[valueIndex++] & 0xff) << 8;
- d.imageId |= rawData[valueIndex++] & 0xff;
- // parse offset
- d.highOffset = (rawData[valueIndex++] & 0xff); // high byte offset
- d.lowOffset = rawData[valueIndex++] & 0xff; // low byte offset
-
- d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff));
- } catch (IndexOutOfBoundsException e) {
- CatLog.d("ImageDescripter", "parse; failed parsing image descriptor");
- d = null;
- }
- return d;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/Input.java b/telephony/java/com/android/internal/telephony/cat/Input.java
deleted file mode 100644
index 13a5ad4..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Input.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Container class for CAT GET INPUT, GET IN KEY commands parameters.
- *
- */
-public class Input implements Parcelable {
- public String text;
- public String defaultText;
- public Bitmap icon;
- public int minLen;
- public int maxLen;
- public boolean ucs2;
- public boolean packed;
- public boolean digitOnly;
- public boolean echo;
- public boolean yesNo;
- public boolean helpAvailable;
- public Duration duration;
-
- Input() {
- text = "";
- defaultText = null;
- icon = null;
- minLen = 0;
- maxLen = 1;
- ucs2 = false;
- packed = false;
- digitOnly = false;
- echo = false;
- yesNo = false;
- helpAvailable = false;
- duration = null;
- }
-
- private Input(Parcel in) {
- text = in.readString();
- defaultText = in.readString();
- icon = in.readParcelable(null);
- minLen = in.readInt();
- maxLen = in.readInt();
- ucs2 = in.readInt() == 1 ? true : false;
- packed = in.readInt() == 1 ? true : false;
- digitOnly = in.readInt() == 1 ? true : false;
- echo = in.readInt() == 1 ? true : false;
- yesNo = in.readInt() == 1 ? true : false;
- helpAvailable = in.readInt() == 1 ? true : false;
- duration = in.readParcelable(null);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(text);
- dest.writeString(defaultText);
- dest.writeParcelable(icon, 0);
- dest.writeInt(minLen);
- dest.writeInt(maxLen);
- dest.writeInt(ucs2 ? 1 : 0);
- dest.writeInt(packed ? 1 : 0);
- dest.writeInt(digitOnly ? 1 : 0);
- dest.writeInt(echo ? 1 : 0);
- dest.writeInt(yesNo ? 1 : 0);
- dest.writeInt(helpAvailable ? 1 : 0);
- dest.writeParcelable(duration, 0);
- }
-
- public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() {
- public Input createFromParcel(Parcel in) {
- return new Input(in);
- }
-
- public Input[] newArray(int size) {
- return new Input[size];
- }
- };
-
- boolean setIcon(Bitmap Icon) { return true; }
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/Item.java b/telephony/java/com/android/internal/telephony/cat/Item.java
deleted file mode 100644
index d4702bb..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Item.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.cat;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents an Item COMPREHENSION-TLV object.
- *
- * {@hide}
- */
-public class Item implements Parcelable {
- /** Identifier of the item. */
- public int id;
- /** Text string of the item. */
- public String text;
- /** Icon of the item */
- public Bitmap icon;
-
- public Item(int id, String text) {
- this.id = id;
- this.text = text;
- this.icon = null;
- }
-
- public Item(Parcel in) {
- id = in.readInt();
- text = in.readString();
- icon = in.readParcelable(null);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(id);
- dest.writeString(text);
- dest.writeParcelable(icon, flags);
- }
-
- public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>() {
- public Item createFromParcel(Parcel in) {
- return new Item(in);
- }
-
- public Item[] newArray(int size) {
- return new Item[size];
- }
- };
-
- public String toString() {
- return text;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
deleted file mode 100644
index af043d1..0000000
--- a/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.cat;
-
-
-/**
- * Browser launch mode for LAUNCH BROWSER proactive command.
- *
- * {@hide}
- */
-public enum LaunchBrowserMode {
- /** Launch browser if not already launched. */
- LAUNCH_IF_NOT_ALREADY_LAUNCHED,
- /**
- * Use the existing browser (the browser shall not use the active existing
- * secured session).
- */
- USE_EXISTING_BROWSER,
- /** Close the existing browser session and launch new browser session. */
- LAUNCH_NEW_BROWSER;
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/Menu.java b/telephony/java/com/android/internal/telephony/cat/Menu.java
deleted file mode 100644
index 7bbae01..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Menu.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Container class for CAT menu (SET UP MENU, SELECT ITEM) parameters.
- *
- */
-public class Menu implements Parcelable {
- public List<Item> items;
- public List<TextAttribute> titleAttrs;
- public PresentationType presentationType;
- public String title;
- public Bitmap titleIcon;
- public int defaultItem;
- public boolean softKeyPreferred;
- public boolean helpAvailable;
- public boolean titleIconSelfExplanatory;
- public boolean itemsIconSelfExplanatory;
-
- public Menu() {
- // Create an empty list.
- items = new ArrayList<Item>();
- title = null;
- titleAttrs = null;
- defaultItem = 0;
- softKeyPreferred = false;
- helpAvailable = false;
- titleIconSelfExplanatory = false;
- itemsIconSelfExplanatory = false;
- titleIcon = null;
- // set default style to be navigation menu.
- presentationType = PresentationType.NAVIGATION_OPTIONS;
- }
-
- private Menu(Parcel in) {
- title = in.readString();
- titleIcon = in.readParcelable(null);
- // rebuild items list.
- items = new ArrayList<Item>();
- int size = in.readInt();
- for (int i=0; i<size; i++) {
- Item item = in.readParcelable(null);
- items.add(item);
- }
- defaultItem = in.readInt();
- softKeyPreferred = in.readInt() == 1 ? true : false;
- helpAvailable = in.readInt() == 1 ? true : false;
- titleIconSelfExplanatory = in.readInt() == 1 ? true : false;
- itemsIconSelfExplanatory = in.readInt() == 1 ? true : false;
- presentationType = PresentationType.values()[in.readInt()];
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(title);
- dest.writeParcelable(titleIcon, flags);
- // write items list to the parcel.
- int size = items.size();
- dest.writeInt(size);
- for (int i=0; i<size; i++) {
- dest.writeParcelable(items.get(i), flags);
- }
- dest.writeInt(defaultItem);
- dest.writeInt(softKeyPreferred ? 1 : 0);
- dest.writeInt(helpAvailable ? 1 : 0);
- dest.writeInt(titleIconSelfExplanatory ? 1 : 0);
- dest.writeInt(itemsIconSelfExplanatory ? 1 : 0);
- dest.writeInt(presentationType.ordinal());
- }
-
- public static final Parcelable.Creator<Menu> CREATOR = new Parcelable.Creator<Menu>() {
- public Menu createFromParcel(Parcel in) {
- return new Menu(in);
- }
-
- public Menu[] newArray(int size) {
- return new Menu[size];
- }
- };
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/PresentationType.java b/telephony/java/com/android/internal/telephony/cat/PresentationType.java
deleted file mode 100644
index 7c8cd8c..0000000
--- a/telephony/java/com/android/internal/telephony/cat/PresentationType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.cat;
-
-
-/**
- * Presentation types for SELECT TYPE proactive command.
- *
- * {@hide}
- */
-public enum PresentationType {
- /** Presentation type is not specified */
- NOT_SPECIFIED,
- /** Presentation as a choice of data values */
- DATA_VALUES,
- /** Presentation as a choice of navigation options */
- NAVIGATION_OPTIONS;
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ResponseData.java b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
deleted file mode 100644
index 1157c1a..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ResponseData.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2006-2007 Google Inc.
- *
- * 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.cat;
-
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.GsmAlphabet;
-import java.util.Calendar;
-import java.util.TimeZone;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.cat.AppInterface.CommandType;
-
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-
-abstract class ResponseData {
- /**
- * Format the data appropriate for TERMINAL RESPONSE and write it into
- * the ByteArrayOutputStream object.
- */
- public abstract void format(ByteArrayOutputStream buf);
-
- public static void writeLength(ByteArrayOutputStream buf, int length) {
- // As per ETSI 102.220 Sec7.1.2, if the total length is greater
- // than 0x7F, it should be coded in two bytes and the first byte
- // should be 0x81.
- if (length > 0x7F) {
- buf.write(0x81);
- }
- buf.write(length);
- }
-}
-
-class SelectItemResponseData extends ResponseData {
- // members
- private int id;
-
- public SelectItemResponseData(int id) {
- super();
- this.id = id;
- }
-
- @Override
- public void format(ByteArrayOutputStream buf) {
- // Item identifier object
- int tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value();
- buf.write(tag); // tag
- buf.write(1); // length
- buf.write(id); // identifier of item chosen
- }
-}
-
-class GetInkeyInputResponseData extends ResponseData {
- // members
- private boolean mIsUcs2;
- private boolean mIsPacked;
- private boolean mIsYesNo;
- private boolean mYesNoResponse;
- public String mInData;
-
- // GetInKey Yes/No response characters constants.
- protected static final byte GET_INKEY_YES = 0x01;
- protected static final byte GET_INKEY_NO = 0x00;
-
- public GetInkeyInputResponseData(String inData, boolean ucs2, boolean packed) {
- super();
- this.mIsUcs2 = ucs2;
- this.mIsPacked = packed;
- this.mInData = inData;
- this.mIsYesNo = false;
- }
-
- public GetInkeyInputResponseData(boolean yesNoResponse) {
- super();
- this.mIsUcs2 = false;
- this.mIsPacked = false;
- this.mInData = "";
- this.mIsYesNo = true;
- this.mYesNoResponse = yesNoResponse;
- }
-
- @Override
- public void format(ByteArrayOutputStream buf) {
- if (buf == null) {
- return;
- }
-
- // Text string object
- int tag = 0x80 | ComprehensionTlvTag.TEXT_STRING.value();
- buf.write(tag); // tag
-
- byte[] data;
-
- if (mIsYesNo) {
- data = new byte[1];
- data[0] = mYesNoResponse ? GET_INKEY_YES : GET_INKEY_NO;
- } else if (mInData != null && mInData.length() > 0) {
- try {
- if (mIsUcs2) {
- data = mInData.getBytes("UTF-16");
- } else if (mIsPacked) {
- int size = mInData.length();
-
- byte[] tempData = GsmAlphabet
- .stringToGsm7BitPacked(mInData, 0, 0);
- data = new byte[size];
- // Since stringToGsm7BitPacked() set byte 0 in the
- // returned byte array to the count of septets used...
- // copy to a new array without byte 0.
- System.arraycopy(tempData, 1, data, 0, size);
- } else {
- data = GsmAlphabet.stringToGsm8BitPacked(mInData);
- }
- } catch (UnsupportedEncodingException e) {
- data = new byte[0];
- } catch (EncodeException e) {
- data = new byte[0];
- }
- } else {
- data = new byte[0];
- }
-
- // length - one more for data coding scheme.
- writeLength(buf, data.length + 1);
-
- // data coding scheme
- if (mIsUcs2) {
- buf.write(0x08); // UCS2
- } else if (mIsPacked) {
- buf.write(0x00); // 7 bit packed
- } else {
- buf.write(0x04); // 8 bit unpacked
- }
-
- for (byte b : data) {
- buf.write(b);
- }
- }
-}
-
-// For "PROVIDE LOCAL INFORMATION" command.
-// See TS 31.111 section 6.4.15/ETSI TS 102 223
-// TS 31.124 section 27.22.4.15 for test spec
-class LanguageResponseData extends ResponseData {
- private String lang;
-
- public LanguageResponseData(String lang) {
- super();
- this.lang = lang;
- }
-
- @Override
- public void format(ByteArrayOutputStream buf) {
- if (buf == null) {
- return;
- }
-
- // Text string object
- int tag = 0x80 | ComprehensionTlvTag.LANGUAGE.value();
- buf.write(tag); // tag
-
- byte[] data;
-
- if (lang != null && lang.length() > 0) {
- data = GsmAlphabet.stringToGsm8BitPacked(lang);
- }
- else {
- data = new byte[0];
- }
-
- buf.write(data.length);
-
- for (byte b : data) {
- buf.write(b);
- }
- }
-}
-
-// For "PROVIDE LOCAL INFORMATION" command.
-// See TS 31.111 section 6.4.15/ETSI TS 102 223
-// TS 31.124 section 27.22.4.15 for test spec
-class DTTZResponseData extends ResponseData {
- private Calendar calendar;
-
- public DTTZResponseData(Calendar cal) {
- super();
- calendar = cal;
- }
-
- @Override
- public void format(ByteArrayOutputStream buf) {
- if (buf == null) {
- return;
- }
-
- // DTTZ object
- int tag = 0x80 | CommandType.PROVIDE_LOCAL_INFORMATION.value();
- buf.write(tag); // tag
-
- byte[] data = new byte[8];
-
- data[0] = 0x07; // Write length of DTTZ data
-
- if (calendar == null) {
- calendar = Calendar.getInstance();
- }
- // Fill year byte
- data[1] = byteToBCD(calendar.get(java.util.Calendar.YEAR) % 100);
-
- // Fill month byte
- data[2] = byteToBCD(calendar.get(java.util.Calendar.MONTH) + 1);
-
- // Fill day byte
- data[3] = byteToBCD(calendar.get(java.util.Calendar.DATE));
-
- // Fill hour byte
- data[4] = byteToBCD(calendar.get(java.util.Calendar.HOUR_OF_DAY));
-
- // Fill minute byte
- data[5] = byteToBCD(calendar.get(java.util.Calendar.MINUTE));
-
- // Fill second byte
- data[6] = byteToBCD(calendar.get(java.util.Calendar.SECOND));
-
- String tz = SystemProperties.get("persist.sys.timezone", "");
- if (TextUtils.isEmpty(tz)) {
- data[7] = (byte) 0xFF; // set FF in terminal response
- } else {
- TimeZone zone = TimeZone.getTimeZone(tz);
- int zoneOffset = zone.getRawOffset() + zone.getDSTSavings();
- data[7] = getTZOffSetByte(zoneOffset);
- }
-
- for (byte b : data) {
- buf.write(b);
- }
- }
-
- private byte byteToBCD(int value) {
- if (value < 0 && value > 99) {
- CatLog.d(this, "Err: byteToBCD conversion Value is " + value +
- " Value has to be between 0 and 99");
- return 0;
- }
-
- return (byte) ((value / 10) | ((value % 10) << 4));
- }
-
- private byte getTZOffSetByte(long offSetVal) {
- boolean isNegative = (offSetVal < 0);
-
- /*
- * The 'offSetVal' is in milliseconds. Convert it to hours and compute
- * offset While sending T.R to UICC, offset is expressed is 'quarters of
- * hours'
- */
-
- long tzOffset = offSetVal / (15 * 60 * 1000);
- tzOffset = (isNegative ? -1 : 1) * tzOffset;
- byte bcdVal = byteToBCD((int) tzOffset);
- // For negative offsets, put '1' in the msb
- return isNegative ? (bcdVal |= 0x08) : bcdVal;
- }
-
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cat/ResultCode.java b/telephony/java/com/android/internal/telephony/cat/ResultCode.java
deleted file mode 100644
index 8544175..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ResultCode.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.cat;
-
-
-/**
- * Enumeration for the return code in TERMINAL RESPONSE.
- * To get the actual return code for each enum value, call {@link #code() code}
- * method.
- *
- * {@hide}
- */
-public enum ResultCode {
-
- /*
- * Results '0X' and '1X' indicate that the command has been performed.
- */
-
- /** Command performed successfully */
- OK(0x00),
-
- /** Command performed with partial comprehension */
- PRFRMD_WITH_PARTIAL_COMPREHENSION(0x01),
-
- /** Command performed, with missing information */
- PRFRMD_WITH_MISSING_INFO(0x02),
-
- /** REFRESH performed with additional EFs read */
- PRFRMD_WITH_ADDITIONAL_EFS_READ(0x03),
-
- /**
- * Command performed successfully, but requested icon could not be
- * displayed
- */
- PRFRMD_ICON_NOT_DISPLAYED(0x04),
-
- /** Command performed, but modified by call control by NAA */
- PRFRMD_MODIFIED_BY_NAA(0x05),
-
- /** Command performed successfully, limited service */
- PRFRMD_LIMITED_SERVICE(0x06),
-
- /** Command performed with modification */
- PRFRMD_WITH_MODIFICATION(0x07),
-
- /** REFRESH performed but indicated NAA was not active */
- PRFRMD_NAA_NOT_ACTIVE(0x08),
-
- /** Command performed successfully, tone not played */
- PRFRMD_TONE_NOT_PLAYED(0x09),
-
- /** Proactive UICC session terminated by the user */
- UICC_SESSION_TERM_BY_USER(0x10),
-
- /** Backward move in the proactive UICC session requested by the user */
- BACKWARD_MOVE_BY_USER(0x11),
-
- /** No response from user */
- NO_RESPONSE_FROM_USER(0x12),
-
- /** Help information required by the user */
- HELP_INFO_REQUIRED(0x13),
-
- /** USSD or SS transaction terminated by the user */
- USSD_SS_SESSION_TERM_BY_USER(0x14),
-
-
- /*
- * Results '2X' indicate to the UICC that it may be worth re-trying the
- * command at a later opportunity.
- */
-
- /** Terminal currently unable to process command */
- TERMINAL_CRNTLY_UNABLE_TO_PROCESS(0x20),
-
- /** Network currently unable to process command */
- NETWORK_CRNTLY_UNABLE_TO_PROCESS(0x21),
-
- /** User did not accept the proactive command */
- USER_NOT_ACCEPT(0x22),
-
- /** User cleared down call before connection or network release */
- USER_CLEAR_DOWN_CALL(0x23),
-
- /** Action in contradiction with the current timer state */
- CONTRADICTION_WITH_TIMER(0x24),
-
- /** Interaction with call control by NAA, temporary problem */
- NAA_CALL_CONTROL_TEMPORARY(0x25),
-
- /** Launch browser generic error code */
- LAUNCH_BROWSER_ERROR(0x26),
-
- /** MMS temporary problem. */
- MMS_TEMPORARY(0x27),
-
-
- /*
- * Results '3X' indicate that it is not worth the UICC re-trying with an
- * identical command, as it will only get the same response. However, the
- * decision to retry lies with the application.
- */
-
- /** Command beyond terminal's capabilities */
- BEYOND_TERMINAL_CAPABILITY(0x30),
-
- /** Command type not understood by terminal */
- CMD_TYPE_NOT_UNDERSTOOD(0x31),
-
- /** Command data not understood by terminal */
- CMD_DATA_NOT_UNDERSTOOD(0x32),
-
- /** Command number not known by terminal */
- CMD_NUM_NOT_KNOWN(0x33),
-
- /** SS Return Error */
- SS_RETURN_ERROR(0x34),
-
- /** SMS RP-ERROR */
- SMS_RP_ERROR(0x35),
-
- /** Error, required values are missing */
- REQUIRED_VALUES_MISSING(0x36),
-
- /** USSD Return Error */
- USSD_RETURN_ERROR(0x37),
-
- /** MultipleCard commands error */
- MULTI_CARDS_CMD_ERROR(0x38),
-
- /**
- * Interaction with call control by USIM or MO short message control by
- * USIM, permanent problem
- */
- USIM_CALL_CONTROL_PERMANENT(0x39),
-
- /** Bearer Independent Protocol error */
- BIP_ERROR(0x3a),
-
- /** Access Technology unable to process command */
- ACCESS_TECH_UNABLE_TO_PROCESS(0x3b),
-
- /** Frames error */
- FRAMES_ERROR(0x3c),
-
- /** MMS Error */
- MMS_ERROR(0x3d);
-
-
- private int mCode;
-
- ResultCode(int code) {
- mCode = code;
- }
-
- /**
- * Retrieves the actual result code that this object represents.
- * @return Actual result code
- */
- public int value() {
- return mCode;
- }
-
- public static ResultCode fromInt(int value) {
- for (ResultCode r : ResultCode.values()) {
- if (r.mCode == value) {
- return r;
- }
- }
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ResultException.java b/telephony/java/com/android/internal/telephony/cat/ResultException.java
deleted file mode 100644
index 84879c2..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ResultException.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.cat;
-
-
-/**
- * Class for errors in the Result object.
- *
- * {@hide}
- */
-public class ResultException extends CatException {
- private ResultCode mResult;
- private int mAdditionalInfo;
- private String mExplanation;
-
- public ResultException(ResultCode result) {
- super();
-
- // ETSI TS 102 223, 8.12 -- For the general results '20', '21', '26',
- // '38', '39', '3A', '3C', and '3D', it is mandatory for the terminal
- // to provide a specific cause value as additional information.
- switch (result) {
- case TERMINAL_CRNTLY_UNABLE_TO_PROCESS: // 0x20
- case NETWORK_CRNTLY_UNABLE_TO_PROCESS: // 0x21
- case LAUNCH_BROWSER_ERROR: // 0x26
- case MULTI_CARDS_CMD_ERROR: // 0x38
- case USIM_CALL_CONTROL_PERMANENT: // 0x39
- case BIP_ERROR: // 0x3a
- case FRAMES_ERROR: // 0x3c
- case MMS_ERROR: // 0x3d
- throw new AssertionError(
- "For result code, " + result +
- ", additional information must be given!");
- }
-
- mResult = result;
- mAdditionalInfo = -1;
- mExplanation = "";
- }
-
- public ResultException(ResultCode result, String explanation) {
- this(result);
- mExplanation = explanation;
- }
-
- public ResultException(ResultCode result, int additionalInfo) {
- this(result);
-
- if (additionalInfo < 0) {
- throw new AssertionError(
- "Additional info must be greater than zero!");
- }
-
- mAdditionalInfo = additionalInfo;
- }
-
- public ResultException(ResultCode result, int additionalInfo, String explanation) {
- this(result, additionalInfo);
- mExplanation = explanation;
- }
-
- public ResultCode result() {
- return mResult;
- }
-
- public boolean hasAdditionalInfo() {
- return mAdditionalInfo >= 0;
- }
-
- public int additionalInfo() {
- return mAdditionalInfo;
- }
-
- public String explanation() {
- return mExplanation;
- }
-
- @Override
- public String toString() {
- return "result=" + mResult + " additionalInfo=" + mAdditionalInfo +
- " explantion=" + mExplanation;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
deleted file mode 100644
index fb33a8e..0000000
--- a/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccUtils;
-
-import android.os.Handler;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import android.os.Message;
-
-/**
- * Class used for queuing raw ril messages, decoding them into CommanParams
- * objects and sending the result back to the CAT Service.
- */
-class RilMessageDecoder extends StateMachine {
-
- // constants
- private static final int CMD_START = 1;
- private static final int CMD_PARAMS_READY = 2;
-
- // members
- private static RilMessageDecoder sInstance = null;
- private CommandParamsFactory mCmdParamsFactory = null;
- private RilMessage mCurrentRilMessage = null;
- private Handler mCaller = null;
-
- // States
- private StateStart mStateStart = new StateStart();
- private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady();
-
- /**
- * Get the singleton instance, constructing if necessary.
- *
- * @param caller
- * @param fh
- * @return RilMesssageDecoder
- */
- public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) {
- if (sInstance == null) {
- sInstance = new RilMessageDecoder(caller, fh);
- sInstance.start();
- }
- return sInstance;
- }
-
- /**
- * Start decoding the message parameters,
- * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller.
- *
- * @param rilMsg
- */
- public void sendStartDecodingMessageParams(RilMessage rilMsg) {
- Message msg = obtainMessage(CMD_START);
- msg.obj = rilMsg;
- sendMessage(msg);
- }
-
- /**
- * The command parameters have been decoded.
- *
- * @param resCode
- * @param cmdParams
- */
- public void sendMsgParamsDecoded(ResultCode resCode, CommandParams cmdParams) {
- Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY);
- msg.arg1 = resCode.value();
- msg.obj = cmdParams;
- sendMessage(msg);
- }
-
- private void sendCmdForExecution(RilMessage rilMsg) {
- Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED,
- new RilMessage(rilMsg));
- msg.sendToTarget();
- }
-
- private RilMessageDecoder(Handler caller, IccFileHandler fh) {
- super("RilMessageDecoder");
-
- addState(mStateStart);
- addState(mStateCmdParamsReady);
- setInitialState(mStateStart);
-
- mCaller = caller;
- mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh);
- }
-
- private class StateStart extends State {
- @Override
- public boolean processMessage(Message msg) {
- if (msg.what == CMD_START) {
- if (decodeMessageParams((RilMessage)msg.obj)) {
- transitionTo(mStateCmdParamsReady);
- }
- } else {
- CatLog.d(this, "StateStart unexpected expecting START=" +
- CMD_START + " got " + msg.what);
- }
- return true;
- }
- }
-
- private class StateCmdParamsReady extends State {
- @Override
- public boolean processMessage(Message msg) {
- if (msg.what == CMD_PARAMS_READY) {
- mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1);
- mCurrentRilMessage.mData = msg.obj;
- sendCmdForExecution(mCurrentRilMessage);
- transitionTo(mStateStart);
- } else {
- CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
- + CMD_PARAMS_READY + " got " + msg.what);
- deferMessage(msg);
- }
- return true;
- }
- }
-
- private boolean decodeMessageParams(RilMessage rilMsg) {
- boolean decodingStarted;
-
- mCurrentRilMessage = rilMsg;
- switch(rilMsg.mId) {
- case CatService.MSG_ID_SESSION_END:
- case CatService.MSG_ID_CALL_SETUP:
- mCurrentRilMessage.mResCode = ResultCode.OK;
- sendCmdForExecution(mCurrentRilMessage);
- decodingStarted = false;
- break;
- case CatService.MSG_ID_PROACTIVE_COMMAND:
- case CatService.MSG_ID_EVENT_NOTIFY:
- case CatService.MSG_ID_REFRESH:
- byte[] rawData = null;
- try {
- rawData = IccUtils.hexStringToBytes((String) rilMsg.mData);
- } catch (Exception e) {
- // zombie messages are dropped
- CatLog.d(this, "decodeMessageParams dropping zombie messages");
- decodingStarted = false;
- break;
- }
- try {
- // Start asynch parsing of the command parameters.
- mCmdParamsFactory.make(BerTlv.decode(rawData));
- decodingStarted = true;
- } catch (ResultException e) {
- // send to Service for proper RIL communication.
- CatLog.d(this, "decodeMessageParams: caught ResultException e=" + e);
- mCurrentRilMessage.mResCode = e.result();
- sendCmdForExecution(mCurrentRilMessage);
- decodingStarted = false;
- }
- break;
- default:
- decodingStarted = false;
- break;
- }
- return decodingStarted;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/TextAlignment.java b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
deleted file mode 100644
index 7fb58a5..0000000
--- a/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.cat;
-
-
-/**
- * Enumeration for representing text alignment.
- *
- * {@hide}
- */
-public enum TextAlignment {
- LEFT(0x0),
- CENTER(0x1),
- RIGHT(0x2),
- /** Language dependent (default) */
- DEFAULT(0x3);
-
- private int mValue;
-
- TextAlignment(int value) {
- mValue = value;
- }
-
- /**
- * Create a TextAlignment object.
- * @param value Integer value to be converted to a TextAlignment object.
- * @return TextAlignment object whose value is {@code value}. If no
- * TextAlignment object has that value, null is returned.
- */
- public static TextAlignment fromInt(int value) {
- for (TextAlignment e : TextAlignment.values()) {
- if (e.mValue == value) {
- return e;
- }
- }
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/TextAttribute.java b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
deleted file mode 100644
index 0dea640..0000000
--- a/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.cat;
-
-
-/**
- * Class for representing text attributes for SIM Toolkit.
- *
- * {@hide}
- */
-public class TextAttribute {
- public int start;
- public int length;
- public TextAlignment align;
- public FontSize size;
- public boolean bold;
- public boolean italic;
- public boolean underlined;
- public boolean strikeThrough;
- public TextColor color;
-
- public TextAttribute(int start, int length, TextAlignment align,
- FontSize size, boolean bold, boolean italic, boolean underlined,
- boolean strikeThrough, TextColor color) {
- this.start = start;
- this.length = length;
- this.align = align;
- this.size = size;
- this.bold = bold;
- this.italic = italic;
- this.underlined = underlined;
- this.strikeThrough = strikeThrough;
- this.color = color;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/TextColor.java b/telephony/java/com/android/internal/telephony/cat/TextColor.java
deleted file mode 100644
index 6447e74..0000000
--- a/telephony/java/com/android/internal/telephony/cat/TextColor.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.cat;
-
-
-/**
- * Enumeration for representing text color.
- *
- * {@hide}
- */
-public enum TextColor {
- BLACK(0x0),
- DARK_GRAY(0x1),
- DARK_RED(0x2),
- DARK_YELLOW(0x3),
- DARK_GREEN(0x4),
- DARK_CYAN(0x5),
- DARK_BLUE(0x6),
- DARK_MAGENTA(0x7),
- GRAY(0x8),
- WHITE(0x9),
- BRIGHT_RED(0xa),
- BRIGHT_YELLOW(0xb),
- BRIGHT_GREEN(0xc),
- BRIGHT_CYAN(0xd),
- BRIGHT_BLUE(0xe),
- BRIGHT_MAGENTA(0xf);
-
- private int mValue;
-
- TextColor(int value) {
- mValue = value;
- }
-
- /**
- * Create a TextColor object.
- * @param value Integer value to be converted to a TextColor object.
- * @return TextColor object whose value is {@code value}. If no TextColor
- * object has that value, null is returned.
- */
- public static TextColor fromInt(int value) {
- for (TextColor e : TextColor.values()) {
- if (e.mValue == value) {
- return e;
- }
- }
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/TextMessage.java b/telephony/java/com/android/internal/telephony/cat/TextMessage.java
deleted file mode 100644
index 5ffd076..0000000
--- a/telephony/java/com/android/internal/telephony/cat/TextMessage.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class TextMessage implements Parcelable {
- public String title = "";
- public String text = null;
- public Bitmap icon = null;
- public boolean iconSelfExplanatory = false;
- public boolean isHighPriority = false;
- public boolean responseNeeded = true;
- public boolean userClear = false;
- public Duration duration = null;
-
- TextMessage() {
- }
-
- private TextMessage(Parcel in) {
- title = in.readString();
- text = in.readString();
- icon = in.readParcelable(null);
- iconSelfExplanatory = in.readInt() == 1 ? true : false;
- isHighPriority = in.readInt() == 1 ? true : false;
- responseNeeded = in.readInt() == 1 ? true : false;
- userClear = in.readInt() == 1 ? true : false;
- duration = in.readParcelable(null);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(title);
- dest.writeString(text);
- dest.writeParcelable(icon, 0);
- dest.writeInt(iconSelfExplanatory ? 1 : 0);
- dest.writeInt(isHighPriority ? 1 : 0);
- dest.writeInt(responseNeeded ? 1 : 0);
- dest.writeInt(userClear ? 1 : 0);
- dest.writeParcelable(duration, 0);
- }
-
- public static final Parcelable.Creator<TextMessage> CREATOR = new Parcelable.Creator<TextMessage>() {
- public TextMessage createFromParcel(Parcel in) {
- return new TextMessage(in);
- }
-
- public TextMessage[] newArray(int size) {
- return new TextMessage[size];
- }
- };
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/Tone.java b/telephony/java/com/android/internal/telephony/cat/Tone.java
deleted file mode 100644
index 27b4489..0000000
--- a/telephony/java/com/android/internal/telephony/cat/Tone.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Enumeration for representing the tone values for use with PLAY TONE
- * proactive commands.
- *
- * {@hide}
- */
-public enum Tone implements Parcelable {
- // Standard supervisory tones
-
- /**
- * Dial tone.
- */
- DIAL(0x01),
-
- /**
- * Called subscriber busy.
- */
- BUSY(0x02),
-
- /**
- * Congestion.
- */
- CONGESTION(0x03),
-
- /**
- * Radio path acknowledge.
- */
- RADIO_PATH_ACK(0x04),
-
- /**
- * Radio path not available / Call dropped.
- */
- RADIO_PATH_NOT_AVAILABLE(0x05),
-
- /**
- * Error/Special information.
- */
- ERROR_SPECIAL_INFO(0x06),
-
- /**
- * Call waiting tone.
- */
- CALL_WAITING(0x07),
-
- /**
- * Ringing tone.
- */
- RINGING(0x08),
-
- // Terminal proprietary tones
-
- /**
- * General beep.
- */
- GENERAL_BEEP(0x10),
-
- /**
- * Positive acknowledgement tone.
- */
- POSITIVE_ACK(0x11),
-
- /**
- * Negative acknowledgement tone.
- */
- NEGATIVE_ACK(0x12),
-
- /**
- * Ringing tone as selected by the user for incoming speech call.
- */
- INCOMING_SPEECH_CALL(0x13),
-
- /**
- * Alert tone as selected by the user for incoming SMS.
- */
- INCOMING_SMS(0x14),
-
- /**
- * Critical alert.
- * This tone is to be used in critical situations. The terminal shall make
- * every effort to alert the user when this tone is indicated independent
- * from the volume setting in the terminal.
- */
- CRITICAL_ALERT(0x15),
-
- /**
- * Vibrate only, if available.
- */
- VIBRATE_ONLY(0x20),
-
- // Themed tones
-
- /**
- * Happy tone.
- */
- HAPPY(0x30),
-
- /**
- * Sad tone.
- */
- SAD(0x31),
-
- /**
- * Urgent action tone.
- */
- URGENT(0x32),
-
- /**
- * Question tone.
- */
- QUESTION(0x33),
-
- /**
- * Message received tone.
- */
- MESSAGE_RECEIVED(0x34),
-
- // Melody tones
- MELODY_1(0x40),
- MELODY_2(0x41),
- MELODY_3(0x42),
- MELODY_4(0x43),
- MELODY_5(0x44),
- MELODY_6(0x45),
- MELODY_7(0x46),
- MELODY_8(0x47);
-
- private int mValue;
-
- Tone(int value) {
- mValue = value;
- }
-
- /**
- * Create a Tone object.
- * @param value Integer value to be converted to a Tone object.
- * @return Tone object whose value is {@code value}. If no Tone object has
- * that value, null is returned.
- */
- public static Tone fromInt(int value) {
- for (Tone e : Tone.values()) {
- if (e.mValue == value) {
- return e;
- }
- }
- return null;
- }
-
- Tone(Parcel in) {
- mValue = in.readInt();
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(ordinal());
- }
-
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<Tone> CREATOR = new Parcelable.Creator<Tone>() {
- public Tone createFromParcel(Parcel in) {
- return Tone.values()[in.readInt()];
- }
-
- public Tone[] newArray(int size) {
- return new Tone[size];
- }
- };
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/ToneSettings.java b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
deleted file mode 100644
index 6375afb..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cat;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Container class for PlayTone commands parameters.
- *
- */
-public class ToneSettings implements Parcelable {
- public Duration duration;
- public Tone tone;
- public boolean vibrate;
-
- public ToneSettings(Duration duration, Tone tone, boolean vibrate) {
- this.duration = duration;
- this.tone = tone;
- this.vibrate = vibrate;
- }
-
- private ToneSettings(Parcel in) {
- duration = in.readParcelable(null);
- tone = in.readParcelable(null);
- vibrate = in.readInt() == 1;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(duration, 0);
- dest.writeParcelable(tone, 0);
- dest.writeInt(vibrate ? 1 : 0);
- }
-
- public static final Parcelable.Creator<ToneSettings> CREATOR = new Parcelable.Creator<ToneSettings>() {
- public ToneSettings createFromParcel(Parcel in) {
- return new ToneSettings(in);
- }
-
- public ToneSettings[] newArray(int size) {
- return new ToneSettings[size];
- }
- };
-}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/cat/ValueParser.java b/telephony/java/com/android/internal/telephony/cat/ValueParser.java
deleted file mode 100644
index 584d96c..0000000
--- a/telephony/java/com/android/internal/telephony/cat/ValueParser.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2006-2007 Google Inc.
- *
- * 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.cat;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.cat.Duration.TimeUnit;
-
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-abstract class ValueParser {
-
- /**
- * Search for a Command Details object from a list.
- *
- * @param ctlvs List of ComprehensionTlv objects used for search
- * @return An CtlvCommandDetails object found from the objects. If no
- * Command Details object is found, ResultException is thrown.
- * @throws ResultException
- */
- static CommandDetails retrieveCommandDetails(ComprehensionTlv ctlv)
- throws ResultException {
-
- CommandDetails cmdDet = new CommandDetails();
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- try {
- cmdDet.compRequired = ctlv.isComprehensionRequired();
- cmdDet.commandNumber = rawValue[valueIndex] & 0xff;
- cmdDet.typeOfCommand = rawValue[valueIndex + 1] & 0xff;
- cmdDet.commandQualifier = rawValue[valueIndex + 2] & 0xff;
- return cmdDet;
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- }
-
- /**
- * Search for a Device Identities object from a list.
- *
- * @param ctlvs List of ComprehensionTlv objects used for search
- * @return An CtlvDeviceIdentities object found from the objects. If no
- * Command Details object is found, ResultException is thrown.
- * @throws ResultException
- */
- static DeviceIdentities retrieveDeviceIdentities(ComprehensionTlv ctlv)
- throws ResultException {
-
- DeviceIdentities devIds = new DeviceIdentities();
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- try {
- devIds.sourceId = rawValue[valueIndex] & 0xff;
- devIds.destinationId = rawValue[valueIndex + 1] & 0xff;
- return devIds;
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING);
- }
- }
-
- /**
- * Retrieves Duration information from the Duration COMPREHENSION-TLV
- * object.
- *
- * @param ctlv A Text Attribute COMPREHENSION-TLV object
- * @return A Duration object
- * @throws ResultException
- */
- static Duration retrieveDuration(ComprehensionTlv ctlv) throws ResultException {
- int timeInterval = 0;
- TimeUnit timeUnit = TimeUnit.SECOND;
-
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
-
- try {
- timeUnit = TimeUnit.values()[(rawValue[valueIndex] & 0xff)];
- timeInterval = rawValue[valueIndex + 1] & 0xff;
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- return new Duration(timeInterval, timeUnit);
- }
-
- /**
- * Retrieves Item information from the COMPREHENSION-TLV object.
- *
- * @param ctlv A Text Attribute COMPREHENSION-TLV object
- * @return An Item
- * @throws ResultException
- */
- static Item retrieveItem(ComprehensionTlv ctlv) throws ResultException {
- Item item = null;
-
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- int length = ctlv.getLength();
-
- if (length != 0) {
- int textLen = length - 1;
-
- try {
- int id = rawValue[valueIndex] & 0xff;
- String text = IccUtils.adnStringFieldToString(rawValue,
- valueIndex + 1, textLen);
- item = new Item(id, text);
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- }
-
- return item;
- }
-
- /**
- * Retrieves Item id information from the COMPREHENSION-TLV object.
- *
- * @param ctlv A Text Attribute COMPREHENSION-TLV object
- * @return An Item id
- * @throws ResultException
- */
- static int retrieveItemId(ComprehensionTlv ctlv) throws ResultException {
- int id = 0;
-
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
-
- try {
- id = rawValue[valueIndex] & 0xff;
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
-
- return id;
- }
-
- /**
- * Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object
- *
- * @param ctlv An Icon Identifier COMPREHENSION-TLV object
- * @return IconId instance
- * @throws ResultException
- */
- static IconId retrieveIconId(ComprehensionTlv ctlv) throws ResultException {
- IconId id = new IconId();
-
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- try {
- id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00;
- id.recordNumber = rawValue[valueIndex] & 0xff;
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
-
- return id;
- }
-
- /**
- * Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV
- * object
- *
- * @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object
- * @return ItemsIconId instance
- * @throws ResultException
- */
- static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv)
- throws ResultException {
- CatLog.d("ValueParser", "retrieveItemsIconId:");
- ItemsIconId id = new ItemsIconId();
-
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- int numOfItems = ctlv.getLength() - 1;
- id.recordNumbers = new int[numOfItems];
-
- try {
- // get icon self-explanatory
- id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00;
-
- for (int index = 0; index < numOfItems;) {
- id.recordNumbers[index++] = rawValue[valueIndex++];
- }
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- return id;
- }
-
- /**
- * Retrieves text attribute information from the Text Attribute
- * COMPREHENSION-TLV object.
- *
- * @param ctlv A Text Attribute COMPREHENSION-TLV object
- * @return A list of TextAttribute objects
- * @throws ResultException
- */
- static List<TextAttribute> retrieveTextAttribute(ComprehensionTlv ctlv)
- throws ResultException {
- ArrayList<TextAttribute> lst = new ArrayList<TextAttribute>();
-
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- int length = ctlv.getLength();
-
- if (length != 0) {
- // Each attribute is consisted of four bytes
- int itemCount = length / 4;
-
- try {
- for (int i = 0; i < itemCount; i++, valueIndex += 4) {
- int start = rawValue[valueIndex] & 0xff;
- int textLength = rawValue[valueIndex + 1] & 0xff;
- int format = rawValue[valueIndex + 2] & 0xff;
- int colorValue = rawValue[valueIndex + 3] & 0xff;
-
- int alignValue = format & 0x03;
- TextAlignment align = TextAlignment.fromInt(alignValue);
-
- int sizeValue = (format >> 2) & 0x03;
- FontSize size = FontSize.fromInt(sizeValue);
- if (size == null) {
- // Font size value is not defined. Use default.
- size = FontSize.NORMAL;
- }
-
- boolean bold = (format & 0x10) != 0;
- boolean italic = (format & 0x20) != 0;
- boolean underlined = (format & 0x40) != 0;
- boolean strikeThrough = (format & 0x80) != 0;
-
- TextColor color = TextColor.fromInt(colorValue);
-
- TextAttribute attr = new TextAttribute(start, textLength,
- align, size, bold, italic, underlined,
- strikeThrough, color);
- lst.add(attr);
- }
-
- return lst;
-
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- }
- return null;
- }
-
-
- /**
- * Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV
- * object.
- *
- * @param ctlv An Alpha Identifier COMPREHENSION-TLV object
- * @return String corresponding to the alpha identifier
- * @throws ResultException
- */
- static String retrieveAlphaId(ComprehensionTlv ctlv) throws ResultException {
-
- if (ctlv != null) {
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- int length = ctlv.getLength();
- if (length != 0) {
- try {
- return IccUtils.adnStringFieldToString(rawValue, valueIndex,
- length);
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- } else {
- return CatService.STK_DEFAULT;
- }
- } else {
- return CatService.STK_DEFAULT;
- }
- }
-
- /**
- * Retrieves text from the Text COMPREHENSION-TLV object, and decodes it
- * into a Java String.
- *
- * @param ctlv A Text COMPREHENSION-TLV object
- * @return A Java String object decoded from the Text object
- * @throws ResultException
- */
- static String retrieveTextString(ComprehensionTlv ctlv) throws ResultException {
- byte[] rawValue = ctlv.getRawValue();
- int valueIndex = ctlv.getValueIndex();
- byte codingScheme = 0x00;
- String text = null;
- int textLen = ctlv.getLength();
-
- // In case the text length is 0, return a null string.
- if (textLen == 0) {
- return text;
- } else {
- // one byte is coding scheme
- textLen -= 1;
- }
-
- try {
- codingScheme = (byte) (rawValue[valueIndex] & 0x0c);
-
- if (codingScheme == 0x00) { // GSM 7-bit packed
- text = GsmAlphabet.gsm7BitPackedToString(rawValue,
- valueIndex + 1, (textLen * 8) / 7);
- } else if (codingScheme == 0x04) { // GSM 8-bit unpacked
- text = GsmAlphabet.gsm8BitUnpackedToString(rawValue,
- valueIndex + 1, textLen);
- } else if (codingScheme == 0x08) { // UCS2
- text = new String(rawValue, valueIndex + 1, textLen, "UTF-16");
- } else {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
-
- return text;
- } catch (IndexOutOfBoundsException e) {
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- } catch (UnsupportedEncodingException e) {
- // This should never happen.
- throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cat/package.html b/telephony/java/com/android/internal/telephony/cat/package.html
deleted file mode 100644
index 5b6bfc6..0000000
--- a/telephony/java/com/android/internal/telephony/cat/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<HTML>
-<BODY>
-Provides classes for ICC Toolkit Service (CAT).
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
deleted file mode 100644
index d99a625..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2011 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.cdma;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.preference.PreferenceManager;
-import android.provider.Telephony;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.gsm.GsmSMSDispatcher;
-import com.android.internal.telephony.gsm.SmsMessage;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.uicc.UiccController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-public class CDMALTEPhone extends CDMAPhone {
- static final String LOG_TAG = "CDMA";
-
- private static final boolean DBG = true;
-
- /** Secondary SMSDispatcher for 3GPP format messages. */
- SMSDispatcher m3gppSMS;
-
- /**
- * Small container class used to hold information relevant to
- * the carrier selection process. operatorNumeric can be ""
- * if we are looking for automatic selection. operatorAlphaLong is the
- * corresponding operator name.
- */
- private static class NetworkSelectMessage {
- public Message message;
- public String operatorNumeric;
- public String operatorAlphaLong;
- }
-
- // Constructors
- public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
- super(context, ci, notifier, false);
- m3gppSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
- mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
- }
-
- @Override
- public void handleMessage (Message msg) {
- AsyncResult ar;
- switch (msg.what) {
- // handle the select network completion callbacks.
- case EVENT_SET_NETWORK_MANUAL_COMPLETE:
- handleSetSelectNetwork((AsyncResult) msg.obj);
- break;
- case EVENT_NEW_ICC_SMS:
- ar = (AsyncResult)msg.obj;
- m3gppSMS.dispatchMessage((SmsMessage)ar.result);
- break;
- default:
- super.handleMessage(msg);
- }
- }
-
- @Override
- protected void initSstIcc() {
- mIccCard.set(UiccController.getInstance(this).getIccCard());
- mIccRecords = mIccCard.get().getIccRecords();
- // CdmaLteServiceStateTracker registers with IccCard to know
- // when the card is ready. So create mIccCard before the ServiceStateTracker
- mSST = new CdmaLteServiceStateTracker(this);
- }
-
- @Override
- public void dispose() {
- synchronized(PhoneProxy.lockForRadioTechnologyChange) {
- super.dispose();
- m3gppSMS.dispose();
- mIccRecords.unregisterForNewSms(this);
- }
- }
-
- @Override
- public void removeReferences() {
- super.removeReferences();
- m3gppSMS = null;
- }
-
- @Override
- public DataState getDataConnectionState(String apnType) {
- DataState ret = DataState.DISCONNECTED;
-
- if (mSST == null) {
- // Radio Technology Change is ongoing, dispose() and
- // removeReferences() have already been called
-
- ret = DataState.DISCONNECTED;
- } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false) {
- ret = DataState.DISCONNECTED;
- } else {
- switch (mDataConnectionTracker.getState(apnType)) {
- case FAILED:
- case IDLE:
- ret = DataState.DISCONNECTED;
- break;
-
- case CONNECTED:
- case DISCONNECTING:
- if (mCT.state != Phone.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed()) {
- ret = DataState.SUSPENDED;
- } else {
- ret = DataState.CONNECTED;
- }
- break;
-
- case INITING:
- case CONNECTING:
- case SCANNING:
- ret = DataState.CONNECTING;
- break;
- }
- }
-
- log("getDataConnectionState apnType=" + apnType + " ret=" + ret);
- return ret;
- }
-
- @Override
- public void
- selectNetworkManually(OperatorInfo network,
- Message response) {
- // wrap the response message in our own message along with
- // the operator's id.
- NetworkSelectMessage nsm = new NetworkSelectMessage();
- nsm.message = response;
- nsm.operatorNumeric = network.getOperatorNumeric();
- nsm.operatorAlphaLong = network.getOperatorAlphaLong();
-
- // get the message
- Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
-
- mCM.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
- }
-
- /**
- * Used to track the settings upon completion of the network change.
- */
- private void handleSetSelectNetwork(AsyncResult ar) {
- // look for our wrapper within the asyncresult, skip the rest if it
- // is null.
- if (!(ar.userObj instanceof NetworkSelectMessage)) {
- Log.e(LOG_TAG, "unexpected result from user object.");
- return;
- }
-
- NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
-
- // found the object, now we send off the message we had originally
- // attached to the request.
- if (nsm.message != null) {
- if (DBG) log("sending original message to recipient");
- AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
- nsm.message.sendToTarget();
- }
-
- // open the shared preferences editor, and write the value.
- // nsm.operatorNumeric is "" if we're in automatic.selection.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- SharedPreferences.Editor editor = sp.edit();
- editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric);
- editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong);
-
- // commit and log the result.
- if (! editor.commit()) {
- Log.e(LOG_TAG, "failed to commit network selection preference");
- }
-
- }
-
- @Override
- public boolean updateCurrentCarrierInProvider() {
- if (mIccRecords != null) {
- try {
- Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
- ContentValues map = new ContentValues();
- String operatorNumeric = mIccRecords.getOperatorNumeric();
- map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
- if (DBG) log("updateCurrentCarrierInProvider from UICC: numeric=" +
- operatorNumeric);
- mContext.getContentResolver().insert(uri, map);
- return true;
- } catch (SQLException e) {
- Log.e(LOG_TAG, "[CDMALTEPhone] Can't store current operator ret false", e);
- }
- } else {
- if (DBG) log("updateCurrentCarrierInProvider mIccRecords == null ret false");
- }
- return false;
- }
-
- // return IMSI from USIM as subscriber ID.
- @Override
- public String getSubscriberId() {
- return mIccRecords.getIMSI();
- }
-
- @Override
- public String getImei() {
- return mImei;
- }
-
- @Override
- public String getDeviceSvn() {
- return mImeiSv;
- }
-
- @Override
- public IsimRecords getIsimRecords() {
- return mIccRecords.getIsimRecords();
- }
-
- @Override
- public String getMsisdn() {
- return mIccRecords.getMsisdnNumber();
- }
-
- @Override
- public void getAvailableNetworks(Message response) {
- mCM.getAvailableNetworks(response);
- }
-
- @Override
- public void requestIsimAuthentication(String nonce, Message result) {
- mCM.requestIsimAuthentication(nonce, result);
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("CDMALTEPhone extends:");
- super.dump(fd, pw, args);
- pw.println(" m3gppSMS=" + m3gppSMS);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
deleted file mode 100755
index 9f6ec71..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ /dev/null
@@ -1,1507 +0,0 @@
-/*
- * 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.cdma;
-
-import android.app.ActivityManagerNative;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Telephony;
-import android.telephony.CellLocation;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.CallTracker;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccException;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.cat.CatService;
-import com.android.internal.telephony.uicc.UiccController;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-
-/**
- * {@hide}
- */
-public class CDMAPhone extends PhoneBase {
- static final String LOG_TAG = "CDMA";
- private static final boolean DBG = true;
- private static final boolean VDBG = false; /* STOP SHIP if true */
-
- // Default Emergency Callback Mode exit timer
- private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000;
-
- static final String VM_COUNT_CDMA = "vm_count_key_cdma";
- private static final String VM_NUMBER_CDMA = "vm_number_key_cdma";
- private String mVmNumber = null;
-
- static final int RESTART_ECM_TIMER = 0; // restart Ecm timer
- static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer
-
- // Instance Variables
- CdmaCallTracker mCT;
- CdmaServiceStateTracker mSST;
- CdmaSubscriptionSourceManager mCdmaSSM;
- ArrayList <CdmaMmiCode> mPendingMmis = new ArrayList<CdmaMmiCode>();
- RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager;
- RuimSmsInterfaceManager mRuimSmsInterfaceManager;
- int mCdmaSubscriptionSource = CdmaSubscriptionSourceManager.SUBSCRIPTION_SOURCE_UNKNOWN;
- PhoneSubInfo mSubInfo;
- EriManager mEriManager;
- WakeLock mWakeLock;
-
- // mEriFileLoadedRegistrants are informed after the ERI text has been loaded
- private final RegistrantList mEriFileLoadedRegistrants = new RegistrantList();
-
- // mEcmTimerResetRegistrants are informed after Ecm timer is canceled or re-started
- private final RegistrantList mEcmTimerResetRegistrants = new RegistrantList();
-
- // mEcmExitRespRegistrant is informed after the phone has been exited
- //the emergency callback mode
- //keep track of if phone is in emergency callback mode
- private boolean mIsPhoneInEcmState;
- private Registrant mEcmExitRespRegistrant;
- protected String mImei;
- protected String mImeiSv;
- private String mEsn;
- private String mMeid;
- // string to define how the carrier specifies its own ota sp number
- private String mCarrierOtaSpNumSchema;
-
- // A runnable which is used to automatically exit from Ecm after a period of time.
- private Runnable mExitEcmRunnable = new Runnable() {
- @Override
- public void run() {
- exitEmergencyCallbackMode();
- }
- };
-
- Registrant mPostDialHandler;
-
- static String PROPERTY_CDMA_HOME_OPERATOR_NUMERIC = "ro.cdma.home.operator.numeric";
-
- // Constructors
- public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
- super(notifier, context, ci, false);
- initSstIcc();
- init(context, notifier);
- }
-
- public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
- boolean unitTestMode) {
- super(notifier, context, ci, unitTestMode);
- initSstIcc();
- init(context, notifier);
- }
-
- protected void initSstIcc() {
- mIccCard.set(UiccController.getInstance(this).getIccCard());
- mIccRecords = mIccCard.get().getIccRecords();
- // CdmaServiceStateTracker registers with IccCard to know
- // when the Ruim card is ready. So create mIccCard before the ServiceStateTracker
- mSST = new CdmaServiceStateTracker(this);
- }
-
- protected void init(Context context, PhoneNotifier notifier) {
- mCM.setPhoneType(Phone.PHONE_TYPE_CDMA);
- mCT = new CdmaCallTracker(this);
- mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(context, mCM, this,
- EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
- mSMS = new CdmaSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
- mDataConnectionTracker = new CdmaDataConnectionTracker (this);
- mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this);
- mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this, mSMS);
- mSubInfo = new PhoneSubInfo(this);
- mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
-
- mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
- registerForRuimRecordEvents();
- mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mCM.registerForOn(this, EVENT_RADIO_ON, null);
- mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
- mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
- mCM.setEmergencyCallbackMode(this, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null);
-
- PowerManager pm
- = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,LOG_TAG);
-
- //Change the system setting
- SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
- Integer.toString(Phone.PHONE_TYPE_CDMA));
-
- // This is needed to handle phone process crashes
- String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- mIsPhoneInEcmState = inEcm.equals("true");
- if (mIsPhoneInEcmState) {
- // Send a message which will invoke handleExitEmergencyCallbackMode
- mCM.exitEmergencyCallbackMode(obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
- }
-
- // get the string that specifies the carrier OTA Sp number
- mCarrierOtaSpNumSchema = SystemProperties.get(
- TelephonyProperties.PROPERTY_OTASP_NUM_SCHEMA,"");
-
- // Sets operator alpha property by retrieving from build-time system property
- String operatorAlpha = SystemProperties.get("ro.cdma.home.operator.alpha");
- setSystemProperty(PROPERTY_ICC_OPERATOR_ALPHA, operatorAlpha);
-
- // Sets operator numeric property by retrieving from build-time system property
- String operatorNumeric = SystemProperties.get(PROPERTY_CDMA_HOME_OPERATOR_NUMERIC);
- log("CDMAPhone: init set 'gsm.sim.operator.numeric' to operator='" +
- operatorNumeric + "'");
- setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, operatorNumeric);
-
- // Sets iso country property by retrieving from build-time system property
- setIsoCountryProperty(operatorNumeric);
-
- // Sets current entry in the telephony carrier table
- updateCurrentCarrierInProvider(operatorNumeric);
-
- // Notify voicemails.
- notifier.notifyMessageWaitingChanged(this);
- }
-
- @Override
- public void dispose() {
- synchronized(PhoneProxy.lockForRadioTechnologyChange) {
- super.dispose();
- log("dispose");
-
- //Unregister from all former registered events
- unregisterForRuimRecordEvents();
- mCM.unregisterForAvailable(this); //EVENT_RADIO_AVAILABLE
- mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
- mCM.unregisterForOn(this); //EVENT_RADIO_ON
- mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK
- mCM.unSetOnSuppServiceNotification(this);
- removeCallbacks(mExitEcmRunnable);
-
- mPendingMmis.clear();
-
- //Force all referenced classes to unregister their former registered events
- mCT.dispose();
- mDataConnectionTracker.dispose();
- mSST.dispose();
- mCdmaSSM.dispose(this);
- mSMS.dispose();
- mRuimPhoneBookInterfaceManager.dispose();
- mRuimSmsInterfaceManager.dispose();
- mSubInfo.dispose();
- mEriManager.dispose();
- }
- }
-
- @Override
- public void removeReferences() {
- log("removeReferences");
- mRuimPhoneBookInterfaceManager = null;
- mRuimSmsInterfaceManager = null;
- mSubInfo = null;
- mCT = null;
- mSST = null;
- mEriManager = null;
- mExitEcmRunnable = null;
- super.removeReferences();
- }
-
- @Override
- protected void finalize() {
- if(DBG) Log.d(LOG_TAG, "CDMAPhone finalized");
- if (mWakeLock.isHeld()) {
- Log.e(LOG_TAG, "UNEXPECTED; mWakeLock is held when finalizing.");
- mWakeLock.release();
- }
- }
-
- public ServiceState getServiceState() {
- return mSST.ss;
- }
-
- public CallTracker getCallTracker() {
- return mCT;
- }
-
- public Phone.State getState() {
- return mCT.state;
- }
-
- public ServiceStateTracker getServiceStateTracker() {
- return mSST;
- }
-
- public String getPhoneName() {
- return "CDMA";
- }
-
- public int getPhoneType() {
- return Phone.PHONE_TYPE_CDMA;
- }
-
- public boolean canTransfer() {
- Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
- return false;
- }
-
- public CdmaCall getRingingCall() {
- return mCT.ringingCall;
- }
-
- public void setMute(boolean muted) {
- mCT.setMute(muted);
- }
-
- public boolean getMute() {
- return mCT.getMute();
- }
-
- public void conference() throws CallStateException {
- // three way calls in CDMA will be handled by feature codes
- Log.e(LOG_TAG, "conference: not possible in CDMA");
- }
-
- public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
- this.mCM.setPreferredVoicePrivacy(enable, onComplete);
- }
-
- public void getEnhancedVoicePrivacy(Message onComplete) {
- this.mCM.getPreferredVoicePrivacy(onComplete);
- }
-
- public void clearDisconnected() {
- mCT.clearDisconnected();
- }
-
- public DataActivityState getDataActivityState() {
- DataActivityState ret = DataActivityState.NONE;
-
- if (mSST.getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
-
- switch (mDataConnectionTracker.getActivity()) {
- case DATAIN:
- ret = DataActivityState.DATAIN;
- break;
-
- case DATAOUT:
- ret = DataActivityState.DATAOUT;
- break;
-
- case DATAINANDOUT:
- ret = DataActivityState.DATAINANDOUT;
- break;
-
- case DORMANT:
- ret = DataActivityState.DORMANT;
- break;
- }
- }
- return ret;
- }
-
- /*package*/ void
- notifySignalStrength() {
- mNotifier.notifySignalStrength(this);
- }
-
- public Connection
- dial (String dialString) throws CallStateException {
- // Need to make sure dialString gets parsed properly
- String newDialString = PhoneNumberUtils.stripSeparators(dialString);
- return mCT.dial(newDialString);
- }
-
- public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {
- throw new CallStateException("Sending UUS information NOT supported in CDMA!");
- }
-
- public SignalStrength getSignalStrength() {
- return mSST.mSignalStrength;
- }
-
- public boolean
- getMessageWaitingIndicator() {
- return (getVoiceMessageCount() > 0);
- }
-
- public List<? extends MmiCode>
- getPendingMmiCodes() {
- return mPendingMmis;
- }
-
- public void registerForSuppServiceNotification(
- Handler h, int what, Object obj) {
- Log.e(LOG_TAG, "method registerForSuppServiceNotification is NOT supported in CDMA!");
- }
-
- public CdmaCall getBackgroundCall() {
- return mCT.backgroundCall;
- }
-
- public boolean handleInCallMmiCommands(String dialString) {
- Log.e(LOG_TAG, "method handleInCallMmiCommands is NOT supported in CDMA!");
- return false;
- }
-
- boolean isInCall() {
- CdmaCall.State foregroundCallState = getForegroundCall().getState();
- CdmaCall.State backgroundCallState = getBackgroundCall().getState();
- CdmaCall.State ringingCallState = getRingingCall().getState();
-
- return (foregroundCallState.isAlive() || backgroundCallState.isAlive() || ringingCallState
- .isAlive());
- }
-
- public void
- setNetworkSelectionModeAutomatic(Message response) {
- Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!");
- }
-
- public void unregisterForSuppServiceNotification(Handler h) {
- Log.e(LOG_TAG, "method unregisterForSuppServiceNotification is NOT supported in CDMA!");
- }
-
- public void
- acceptCall() throws CallStateException {
- mCT.acceptCall();
- }
-
- public void
- rejectCall() throws CallStateException {
- mCT.rejectCall();
- }
-
- public void
- switchHoldingAndActive() throws CallStateException {
- mCT.switchWaitingOrHoldingAndActive();
- }
-
- public String getLine1Number() {
- return mSST.getMdnNumber();
- }
-
- public String getCdmaPrlVersion(){
- return mSST.getPrlVersion();
- }
-
- public String getCdmaMin() {
- return mSST.getCdmaMin();
- }
-
- public boolean isMinInfoReady() {
- return mSST.isMinInfoReady();
- }
-
- public void getCallWaiting(Message onComplete) {
- mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
- }
-
- public void
- setRadioPower(boolean power) {
- mSST.setRadioPower(power);
- }
-
- public String getEsn() {
- return mEsn;
- }
-
- public String getMeid() {
- return mMeid;
- }
-
- //returns MEID or ESN in CDMA
- public String getDeviceId() {
- String id = getMeid();
- if ((id == null) || id.matches("^0*$")) {
- Log.d(LOG_TAG, "getDeviceId(): MEID is not initialized use ESN");
- id = getEsn();
- }
- return id;
- }
-
- public String getDeviceSvn() {
- Log.d(LOG_TAG, "getDeviceSvn(): return 0");
- return "0";
- }
-
- public String getSubscriberId() {
- return mSST.getImsi();
- }
-
- public String getImei() {
- Log.e(LOG_TAG, "IMEI is not available in CDMA");
- return null;
- }
-
- public boolean canConference() {
- Log.e(LOG_TAG, "canConference: not possible in CDMA");
- return false;
- }
-
- public CellLocation getCellLocation() {
- return mSST.cellLoc;
- }
-
- public CdmaCall getForegroundCall() {
- return mCT.foregroundCall;
- }
-
- public void
- selectNetworkManually(OperatorInfo network,
- Message response) {
- Log.e(LOG_TAG, "selectNetworkManually: not possible in CDMA");
- }
-
- public void setOnPostDialCharacter(Handler h, int what, Object obj) {
- mPostDialHandler = new Registrant(h, what, obj);
- }
-
- public boolean handlePinMmi(String dialString) {
- CdmaMmiCode mmi = CdmaMmiCode.newFromDialString(dialString, this);
-
- if (mmi == null) {
- Log.e(LOG_TAG, "Mmi is NULL!");
- return false;
- } else if (mmi.isPukCommand()) {
- mPendingMmis.add(mmi);
- mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
- mmi.processCode();
- return true;
- }
- Log.e(LOG_TAG, "Unrecognized mmi!");
- return false;
- }
-
- /**
- * Removes the given MMI from the pending list and notifies registrants that
- * it is complete.
- *
- * @param mmi MMI that is done
- */
- void onMMIDone(CdmaMmiCode mmi) {
- /*
- * Only notify complete if it's on the pending list. Otherwise, it's
- * already been handled (eg, previously canceled).
- */
- if (mPendingMmis.remove(mmi)) {
- mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
- }
- }
-
- public void setLine1Number(String alphaTag, String number, Message onComplete) {
- Log.e(LOG_TAG, "setLine1Number: not possible in CDMA");
- }
-
- public void setCallWaiting(boolean enable, Message onComplete) {
- Log.e(LOG_TAG, "method setCallWaiting is NOT supported in CDMA!");
- }
-
- public void updateServiceLocation() {
- mSST.enableSingleLocationUpdate();
- }
-
- public void setDataRoamingEnabled(boolean enable) {
- mDataConnectionTracker.setDataOnRoamingEnabled(enable);
- }
-
- public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
- mCM.registerForCdmaOtaProvision(h, what, obj);
- }
-
- public void unregisterForCdmaOtaStatusChange(Handler h) {
- mCM.unregisterForCdmaOtaProvision(h);
- }
-
- public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
- mSST.registerForSubscriptionInfoReady(h, what, obj);
- }
-
- public void unregisterForSubscriptionInfoReady(Handler h) {
- mSST.unregisterForSubscriptionInfoReady(h);
- }
-
- public void setOnEcbModeExitResponse(Handler h, int what, Object obj) {
- mEcmExitRespRegistrant = new Registrant (h, what, obj);
- }
-
- public void unsetOnEcbModeExitResponse(Handler h) {
- mEcmExitRespRegistrant.clear();
- }
-
- public void registerForCallWaiting(Handler h, int what, Object obj) {
- mCT.registerForCallWaiting(h, what, obj);
- }
-
- public void unregisterForCallWaiting(Handler h) {
- mCT.unregisterForCallWaiting(h);
- }
-
- public void
- getNeighboringCids(Message response) {
- /*
- * This is currently not implemented. At least as of June
- * 2009, there is no neighbor cell information available for
- * CDMA because some party is resisting making this
- * information readily available. Consequently, calling this
- * function can have no useful effect. This situation may
- * (and hopefully will) change in the future.
- */
- if (response != null) {
- CommandException ce = new CommandException(
- CommandException.Error.REQUEST_NOT_SUPPORTED);
- AsyncResult.forMessage(response).exception = ce;
- response.sendToTarget();
- }
- }
-
- public DataState getDataConnectionState(String apnType) {
- DataState ret = DataState.DISCONNECTED;
-
- if (mSST == null) {
- // Radio Technology Change is ongoning, dispose() and removeReferences() have
- // already been called
-
- ret = DataState.DISCONNECTED;
- } else if (mSST.getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
- // If we're out of service, open TCP sockets may still work
- // but no data will flow
- ret = DataState.DISCONNECTED;
- } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false ||
- mDataConnectionTracker.isApnTypeActive(apnType) == false) {
- ret = DataState.DISCONNECTED;
- } else {
- switch (mDataConnectionTracker.getState(apnType)) {
- case FAILED:
- case IDLE:
- ret = DataState.DISCONNECTED;
- break;
-
- case CONNECTED:
- case DISCONNECTING:
- if ( mCT.state != Phone.State.IDLE
- && !mSST.isConcurrentVoiceAndDataAllowed()) {
- ret = DataState.SUSPENDED;
- } else {
- ret = DataState.CONNECTED;
- }
- break;
-
- case INITING:
- case CONNECTING:
- case SCANNING:
- ret = DataState.CONNECTING;
- break;
- }
- }
-
- log("getDataConnectionState apnType=" + apnType + " ret=" + ret);
- return ret;
- }
-
- public void sendUssdResponse(String ussdMessge) {
- Log.e(LOG_TAG, "sendUssdResponse: not possible in CDMA");
- }
-
- public void sendDtmf(char c) {
- if (!PhoneNumberUtils.is12Key(c)) {
- Log.e(LOG_TAG,
- "sendDtmf called with invalid character '" + c + "'");
- } else {
- if (mCT.state == Phone.State.OFFHOOK) {
- mCM.sendDtmf(c, null);
- }
- }
- }
-
- public void startDtmf(char c) {
- if (!PhoneNumberUtils.is12Key(c)) {
- Log.e(LOG_TAG,
- "startDtmf called with invalid character '" + c + "'");
- } else {
- mCM.startDtmf(c, null);
- }
- }
-
- public void stopDtmf() {
- mCM.stopDtmf(null);
- }
-
- public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
- boolean check = true;
- for (int itr = 0;itr < dtmfString.length(); itr++) {
- if (!PhoneNumberUtils.is12Key(dtmfString.charAt(itr))) {
- Log.e(LOG_TAG,
- "sendDtmf called with invalid character '" + dtmfString.charAt(itr)+ "'");
- check = false;
- break;
- }
- }
- if ((mCT.state == Phone.State.OFFHOOK)&&(check)) {
- mCM.sendBurstDtmf(dtmfString, on, off, onComplete);
- }
- }
-
- public void getAvailableNetworks(Message response) {
- Log.e(LOG_TAG, "getAvailableNetworks: not possible in CDMA");
- }
-
- public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) {
- Log.e(LOG_TAG, "setOutgoingCallerIdDisplay: not possible in CDMA");
- }
-
- public void enableLocationUpdates() {
- mSST.enableLocationUpdates();
- }
-
- public void disableLocationUpdates() {
- mSST.disableLocationUpdates();
- }
-
- public void getDataCallList(Message response) {
- mCM.getDataCallList(response);
- }
-
- public boolean getDataRoamingEnabled() {
- return mDataConnectionTracker.getDataOnRoamingEnabled();
- }
-
- public void setVoiceMailNumber(String alphaTag,
- String voiceMailNumber,
- Message onComplete) {
- Message resp;
- mVmNumber = voiceMailNumber;
- resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
- mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
- }
-
- public String getVoiceMailNumber() {
- String number = null;
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- // TODO: The default value of voicemail number should be read from a system property
-
- // Read platform settings for dynamic voicemail number
- if (getContext().getResources().getBoolean(com.android.internal
- .R.bool.config_telephony_use_own_number_for_voicemail)) {
- number = sp.getString(VM_NUMBER_CDMA, getLine1Number());
- } else {
- number = sp.getString(VM_NUMBER_CDMA, "*86");
- }
- return number;
- }
-
- /* Returns Number of Voicemails
- * @hide
- */
- public int getVoiceMessageCount() {
- int voicemailCount = mIccRecords.getVoiceMessageCount();
- // If mRuimRecords.getVoiceMessageCount returns zero, then there is possibility
- // that phone was power cycled and would have lost the voicemail count.
- // So get the count from preferences.
- if (voicemailCount == 0) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- voicemailCount = sp.getInt(VM_COUNT_CDMA, 0);
- }
- return voicemailCount;
- }
-
- public String getVoiceMailAlphaTag() {
- // TODO: Where can we get this value has to be clarified with QC.
- String ret = "";//TODO: Remove = "", if we know where to get this value.
-
- //ret = mSIMRecords.getVoiceMailAlphaTag();
-
- if (ret == null || ret.length() == 0) {
- return mContext.getText(
- com.android.internal.R.string.defaultVoiceMailAlphaTag).toString();
- }
-
- return ret;
- }
-
- public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
- Log.e(LOG_TAG, "getCallForwardingOption: not possible in CDMA");
- }
-
- public void setCallForwardingOption(int commandInterfaceCFAction,
- int commandInterfaceCFReason,
- String dialingNumber,
- int timerSeconds,
- Message onComplete) {
- Log.e(LOG_TAG, "setCallForwardingOption: not possible in CDMA");
- }
-
- public void
- getOutgoingCallerIdDisplay(Message onComplete) {
- Log.e(LOG_TAG, "getOutgoingCallerIdDisplay: not possible in CDMA");
- }
-
- public boolean
- getCallForwardingIndicator() {
- Log.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
- return false;
- }
-
- public void explicitCallTransfer() {
- Log.e(LOG_TAG, "explicitCallTransfer: not possible in CDMA");
- }
-
- public String getLine1AlphaTag() {
- Log.e(LOG_TAG, "getLine1AlphaTag: not possible in CDMA");
- return null;
- }
-
- /**
- * Notify any interested party of a Phone state change {@link Phone.State}
- */
- /*package*/ void notifyPhoneStateChanged() {
- mNotifier.notifyPhoneState(this);
- }
-
- /**
- * Notify registrants of a change in the call state. This notifies changes in {@link Call.State}
- * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged.
- */
- /*package*/ void notifyPreciseCallStateChanged() {
- /* we'd love it if this was package-scoped*/
- super.notifyPreciseCallStateChangedP();
- }
-
- void notifyServiceStateChanged(ServiceState ss) {
- super.notifyServiceStateChangedP(ss);
- }
-
- void notifyLocationChanged() {
- mNotifier.notifyCellLocation(this);
- }
-
- /*package*/ void notifyNewRingingConnection(Connection c) {
- /* we'd love it if this was package-scoped*/
- super.notifyNewRingingConnectionP(c);
- }
-
- /*package*/ void notifyDisconnect(Connection cn) {
- mDisconnectRegistrants.notifyResult(cn);
- }
-
- void notifyUnknownConnection() {
- mUnknownConnectionRegistrants.notifyResult(this);
- }
-
- public boolean isInEmergencyCall() {
- return mCT.isInEmergencyCall();
- }
-
- public boolean isInEcm() {
- return mIsPhoneInEcmState;
- }
-
- void sendEmergencyCallbackModeChange(){
- //Send an Intent
- Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
- intent.putExtra(PHONE_IN_ECM_STATE, mIsPhoneInEcmState);
- ActivityManagerNative.broadcastStickyIntent(intent,null);
- if (DBG) Log.d(LOG_TAG, "sendEmergencyCallbackModeChange");
- }
-
- @Override
- public void exitEmergencyCallbackMode() {
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
- }
- // Send a message which will invoke handleExitEmergencyCallbackMode
- mCM.exitEmergencyCallbackMode(obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
- }
-
- private void handleEnterEmergencyCallbackMode(Message msg) {
- if (DBG) {
- Log.d(LOG_TAG, "handleEnterEmergencyCallbackMode,mIsPhoneInEcmState= "
- + mIsPhoneInEcmState);
- }
- // if phone is not in Ecm mode, and it's changed to Ecm mode
- if (mIsPhoneInEcmState == false) {
- mIsPhoneInEcmState = true;
- // notify change
- sendEmergencyCallbackModeChange();
- setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
-
- // Post this runnable so we will automatically exit
- // if no one invokes exitEmergencyCallbackMode() directly.
- long delayInMillis = SystemProperties.getLong(
- TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
- postDelayed(mExitEcmRunnable, delayInMillis);
- // We don't want to go to sleep while in Ecm
- mWakeLock.acquire();
- }
- }
-
- private void handleExitEmergencyCallbackMode(Message msg) {
- AsyncResult ar = (AsyncResult)msg.obj;
- if (DBG) {
- Log.d(LOG_TAG, "handleExitEmergencyCallbackMode,ar.exception , mIsPhoneInEcmState "
- + ar.exception + mIsPhoneInEcmState);
- }
- // Remove pending exit Ecm runnable, if any
- removeCallbacks(mExitEcmRunnable);
-
- if (mEcmExitRespRegistrant != null) {
- mEcmExitRespRegistrant.notifyRegistrant(ar);
- }
- // if exiting ecm success
- if (ar.exception == null) {
- if (mIsPhoneInEcmState) {
- mIsPhoneInEcmState = false;
- setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- }
- // send an Intent
- sendEmergencyCallbackModeChange();
- // Re-initiate data connection
- mDataConnectionTracker.setInternalDataEnabled(true);
- }
- }
-
- /**
- * Handle to cancel or restart Ecm timer in emergency call back mode
- * if action is CANCEL_ECM_TIMER, cancel Ecm timer and notify apps the timer is canceled;
- * otherwise, restart Ecm timer and notify apps the timer is restarted.
- */
- void handleTimerInEmergencyCallbackMode(int action) {
- switch(action) {
- case CANCEL_ECM_TIMER:
- removeCallbacks(mExitEcmRunnable);
- mEcmTimerResetRegistrants.notifyResult(Boolean.TRUE);
- break;
- case RESTART_ECM_TIMER:
- long delayInMillis = SystemProperties.getLong(
- TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
- postDelayed(mExitEcmRunnable, delayInMillis);
- mEcmTimerResetRegistrants.notifyResult(Boolean.FALSE);
- break;
- default:
- Log.e(LOG_TAG, "handleTimerInEmergencyCallbackMode, unsupported action " + action);
- }
- }
-
- /**
- * Registration point for Ecm timer reset
- * @param h handler to notify
- * @param what User-defined message code
- * @param obj placed in Message.obj
- */
- public void registerForEcmTimerReset(Handler h, int what, Object obj) {
- mEcmTimerResetRegistrants.addUnique(h, what, obj);
- }
-
- public void unregisterForEcmTimerReset(Handler h) {
- mEcmTimerResetRegistrants.remove(h);
- }
-
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
- Message onComplete;
-
- switch(msg.what) {
- case EVENT_RADIO_AVAILABLE: {
- mCM.getBasebandVersion(obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
-
- mCM.getDeviceIdentity(obtainMessage(EVENT_GET_DEVICE_IDENTITY_DONE));
- }
- break;
-
- case EVENT_GET_BASEBAND_VERSION_DONE:{
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- break;
- }
-
- if (DBG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
- setSystemProperty(TelephonyProperties.PROPERTY_BASEBAND_VERSION, (String)ar.result);
- }
- break;
-
- case EVENT_GET_DEVICE_IDENTITY_DONE:{
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- break;
- }
- String[] respId = (String[])ar.result;
- mImei = respId[0];
- mImeiSv = respId[1];
- mEsn = respId[2];
- mMeid = respId[3];
- }
- break;
-
- case EVENT_EMERGENCY_CALLBACK_MODE_ENTER:{
- handleEnterEmergencyCallbackMode(msg);
- }
- break;
-
- case EVENT_ICC_RECORD_EVENTS:
- ar = (AsyncResult)msg.obj;
- processIccRecordEvents((Integer)ar.result);
- break;
-
- case EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE:{
- handleExitEmergencyCallbackMode(msg);
- }
- break;
-
- case EVENT_RUIM_RECORDS_LOADED:{
- Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received");
- updateCurrentCarrierInProvider();
- }
- break;
-
- case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:{
- Log.d(LOG_TAG, "Event EVENT_RADIO_OFF_OR_NOT_AVAILABLE Received");
- }
- break;
-
- case EVENT_RADIO_ON:{
- Log.d(LOG_TAG, "Event EVENT_RADIO_ON Received");
- handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
- }
- break;
-
- case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:{
- Log.d(LOG_TAG, "EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED");
- handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
- }
- break;
-
- case EVENT_SSN:{
- Log.d(LOG_TAG, "Event EVENT_SSN Received");
- }
- break;
-
- case EVENT_REGISTERED_TO_NETWORK:{
- Log.d(LOG_TAG, "Event EVENT_REGISTERED_TO_NETWORK Received");
- }
- break;
-
- case EVENT_NV_READY:{
- Log.d(LOG_TAG, "Event EVENT_NV_READY Received");
- prepareEri();
- }
- break;
-
- case EVENT_SET_VM_NUMBER_DONE:{
- ar = (AsyncResult)msg.obj;
- if (IccException.class.isInstance(ar.exception)) {
- storeVoiceMailNumber(mVmNumber);
- ar.exception = null;
- }
- onComplete = (Message) ar.userObj;
- if (onComplete != null) {
- AsyncResult.forMessage(onComplete, ar.result, ar.exception);
- onComplete.sendToTarget();
- }
- }
- break;
-
- default:{
- super.handleMessage(msg);
- }
- }
- }
-
- private void processIccRecordEvents(int eventCode) {
- switch (eventCode) {
- case RuimRecords.EVENT_MWI:
- notifyMessageWaitingIndicator();
- break;
-
- default:
- Log.e(LOG_TAG,"Unknown icc records event code " + eventCode);
- break;
- }
- }
-
- /**
- * Handles the call to get the subscription source
- *
- * @param newSubscriptionSource holds the new CDMA subscription source value
- */
- private void handleCdmaSubscriptionSource(int newSubscriptionSource) {
- if (newSubscriptionSource != mCdmaSubscriptionSource) {
- mCdmaSubscriptionSource = newSubscriptionSource;
- if (newSubscriptionSource == CDMA_SUBSCRIPTION_NV) {
- // NV is ready when subscription source is NV
- sendMessage(obtainMessage(EVENT_NV_READY));
- }
- }
- }
-
- /**
- * Retrieves the PhoneSubInfo of the CDMAPhone
- */
- public PhoneSubInfo getPhoneSubInfo() {
- return mSubInfo;
- }
-
- /**
- * Retrieves the IccSmsInterfaceManager of the CDMAPhone
- */
- public IccSmsInterfaceManager getIccSmsInterfaceManager() {
- return mRuimSmsInterfaceManager;
- }
-
- /**
- * Retrieves the IccPhoneBookInterfaceManager of the CDMAPhone
- */
- public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager() {
- return mRuimPhoneBookInterfaceManager;
- }
-
- public void registerForEriFileLoaded(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mEriFileLoadedRegistrants.add(r);
- }
-
- public void unregisterForEriFileLoaded(Handler h) {
- mEriFileLoadedRegistrants.remove(h);
- }
-
- // override for allowing access from other classes of this package
- /**
- * {@inheritDoc}
- */
- public final void setSystemProperty(String property, String value) {
- super.setSystemProperty(property, value);
- }
-
- /**
- * Activate or deactivate cell broadcast SMS.
- *
- * @param activate 0 = activate, 1 = deactivate
- * @param response Callback message is empty on completion
- */
- public void activateCellBroadcastSms(int activate, Message response) {
- Log.e(LOG_TAG, "[CDMAPhone] activateCellBroadcastSms() is obsolete; use SmsManager");
- response.sendToTarget();
- }
-
- /**
- * Query the current configuration of cdma cell broadcast SMS.
- *
- * @param response Callback message is empty on completion
- */
- public void getCellBroadcastSmsConfig(Message response) {
- Log.e(LOG_TAG, "[CDMAPhone] getCellBroadcastSmsConfig() is obsolete; use SmsManager");
- response.sendToTarget();
- }
-
- /**
- * Configure cdma cell broadcast SMS.
- *
- * @param response Callback message is empty on completion
- */
- public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
- Log.e(LOG_TAG, "[CDMAPhone] setCellBroadcastSmsConfig() is obsolete; use SmsManager");
- response.sendToTarget();
- }
-
- /**
- * Returns true if OTA Service Provisioning needs to be performed.
- */
- @Override
- public boolean needsOtaServiceProvisioning() {
- return mSST.getOtasp() != ServiceStateTracker.OTASP_NOT_NEEDED;
- }
-
- private static final String IS683A_FEATURE_CODE = "*228";
- private static final int IS683A_FEATURE_CODE_NUM_DIGITS = 4;
- private static final int IS683A_SYS_SEL_CODE_NUM_DIGITS = 2;
- private static final int IS683A_SYS_SEL_CODE_OFFSET = 4;
-
- private static final int IS683_CONST_800MHZ_A_BAND = 0;
- private static final int IS683_CONST_800MHZ_B_BAND = 1;
- private static final int IS683_CONST_1900MHZ_A_BLOCK = 2;
- private static final int IS683_CONST_1900MHZ_B_BLOCK = 3;
- private static final int IS683_CONST_1900MHZ_C_BLOCK = 4;
- private static final int IS683_CONST_1900MHZ_D_BLOCK = 5;
- private static final int IS683_CONST_1900MHZ_E_BLOCK = 6;
- private static final int IS683_CONST_1900MHZ_F_BLOCK = 7;
- private static final int INVALID_SYSTEM_SELECTION_CODE = -1;
-
- private static boolean isIs683OtaSpDialStr(String dialStr) {
- int sysSelCodeInt;
- boolean isOtaspDialString = false;
- int dialStrLen = dialStr.length();
-
- if (dialStrLen == IS683A_FEATURE_CODE_NUM_DIGITS) {
- if (dialStr.equals(IS683A_FEATURE_CODE)) {
- isOtaspDialString = true;
- }
- } else {
- sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr);
- switch (sysSelCodeInt) {
- case IS683_CONST_800MHZ_A_BAND:
- case IS683_CONST_800MHZ_B_BAND:
- case IS683_CONST_1900MHZ_A_BLOCK:
- case IS683_CONST_1900MHZ_B_BLOCK:
- case IS683_CONST_1900MHZ_C_BLOCK:
- case IS683_CONST_1900MHZ_D_BLOCK:
- case IS683_CONST_1900MHZ_E_BLOCK:
- case IS683_CONST_1900MHZ_F_BLOCK:
- isOtaspDialString = true;
- break;
- default:
- break;
- }
- }
- return isOtaspDialString;
- }
- /**
- * This function extracts the system selection code from the dial string.
- */
- private static int extractSelCodeFromOtaSpNum(String dialStr) {
- int dialStrLen = dialStr.length();
- int sysSelCodeInt = INVALID_SYSTEM_SELECTION_CODE;
-
- if ((dialStr.regionMatches(0, IS683A_FEATURE_CODE,
- 0, IS683A_FEATURE_CODE_NUM_DIGITS)) &&
- (dialStrLen >= (IS683A_FEATURE_CODE_NUM_DIGITS +
- IS683A_SYS_SEL_CODE_NUM_DIGITS))) {
- // Since we checked the condition above, the system selection code
- // extracted from dialStr will not cause any exception
- sysSelCodeInt = Integer.parseInt (
- dialStr.substring (IS683A_FEATURE_CODE_NUM_DIGITS,
- IS683A_FEATURE_CODE_NUM_DIGITS + IS683A_SYS_SEL_CODE_NUM_DIGITS));
- }
- if (DBG) Log.d(LOG_TAG, "extractSelCodeFromOtaSpNum " + sysSelCodeInt);
- return sysSelCodeInt;
- }
-
- /**
- * This function checks if the system selection code extracted from
- * the dial string "sysSelCodeInt' is the system selection code specified
- * in the carrier ota sp number schema "sch".
- */
- private static boolean
- checkOtaSpNumBasedOnSysSelCode (int sysSelCodeInt, String sch[]) {
- boolean isOtaSpNum = false;
- try {
- // Get how many number of system selection code ranges
- int selRc = Integer.parseInt((String)sch[1]);
- for (int i = 0; i < selRc; i++) {
- if (!TextUtils.isEmpty(sch[i+2]) && !TextUtils.isEmpty(sch[i+3])) {
- int selMin = Integer.parseInt((String)sch[i+2]);
- int selMax = Integer.parseInt((String)sch[i+3]);
- // Check if the selection code extracted from the dial string falls
- // within any of the range pairs specified in the schema.
- if ((sysSelCodeInt >= selMin) && (sysSelCodeInt <= selMax)) {
- isOtaSpNum = true;
- break;
- }
- }
- }
- } catch (NumberFormatException ex) {
- // If the carrier ota sp number schema is not correct, we still allow dial
- // and only log the error:
- Log.e(LOG_TAG, "checkOtaSpNumBasedOnSysSelCode, error", ex);
- }
- return isOtaSpNum;
- }
-
- // Define the pattern/format for carrier specified OTASP number schema.
- // It separates by comma and/or whitespace.
- private static Pattern pOtaSpNumSchema = Pattern.compile("[,\\s]+");
-
- /**
- * The following function checks if a dial string is a carrier specified
- * OTASP number or not by checking against the OTASP number schema stored
- * in PROPERTY_OTASP_NUM_SCHEMA.
- *
- * Currently, there are 2 schemas for carriers to specify the OTASP number:
- * 1) Use system selection code:
- * The schema is:
- * SELC,the # of code pairs,min1,max1,min2,max2,...
- * e.g "SELC,3,10,20,30,40,60,70" indicates that there are 3 pairs of
- * selection codes, and they are {10,20}, {30,40} and {60,70} respectively.
- *
- * 2) Use feature code:
- * The schema is:
- * "FC,length of feature code,feature code".
- * e.g "FC,2,*2" indicates that the length of the feature code is 2,
- * and the code itself is "*2".
- */
- private boolean isCarrierOtaSpNum(String dialStr) {
- boolean isOtaSpNum = false;
- int sysSelCodeInt = extractSelCodeFromOtaSpNum(dialStr);
- if (sysSelCodeInt == INVALID_SYSTEM_SELECTION_CODE) {
- return isOtaSpNum;
- }
- // mCarrierOtaSpNumSchema is retrieved from PROPERTY_OTASP_NUM_SCHEMA:
- if (!TextUtils.isEmpty(mCarrierOtaSpNumSchema)) {
- Matcher m = pOtaSpNumSchema.matcher(mCarrierOtaSpNumSchema);
- if (DBG) {
- Log.d(LOG_TAG, "isCarrierOtaSpNum,schema" + mCarrierOtaSpNumSchema);
- }
-
- if (m.find()) {
- String sch[] = pOtaSpNumSchema.split(mCarrierOtaSpNumSchema);
- // If carrier uses system selection code mechanism
- if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("SELC")) {
- if (sysSelCodeInt!=INVALID_SYSTEM_SELECTION_CODE) {
- isOtaSpNum=checkOtaSpNumBasedOnSysSelCode(sysSelCodeInt,sch);
- } else {
- if (DBG) {
- Log.d(LOG_TAG, "isCarrierOtaSpNum,sysSelCodeInt is invalid");
- }
- }
- } else if (!TextUtils.isEmpty(sch[0]) && sch[0].equals("FC")) {
- int fcLen = Integer.parseInt((String)sch[1]);
- String fc = (String)sch[2];
- if (dialStr.regionMatches(0,fc,0,fcLen)) {
- isOtaSpNum = true;
- } else {
- if (DBG) Log.d(LOG_TAG, "isCarrierOtaSpNum,not otasp number");
- }
- } else {
- if (DBG) {
- Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema not supported" + sch[0]);
- }
- }
- } else {
- if (DBG) {
- Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern not right" +
- mCarrierOtaSpNumSchema);
- }
- }
- } else {
- if (DBG) Log.d(LOG_TAG, "isCarrierOtaSpNum,ota schema pattern empty");
- }
- return isOtaSpNum;
- }
-
- /**
- * isOTASPNumber: checks a given number against the IS-683A OTASP dial string and carrier
- * OTASP dial string.
- *
- * @param dialStr the number to look up.
- * @return true if the number is in IS-683A OTASP dial string or carrier OTASP dial string
- */
- @Override
- public boolean isOtaSpNumber(String dialStr){
- boolean isOtaSpNum = false;
- String dialableStr = PhoneNumberUtils.extractNetworkPortionAlt(dialStr);
- if (dialableStr != null) {
- isOtaSpNum = isIs683OtaSpDialStr(dialableStr);
- if (isOtaSpNum == false) {
- isOtaSpNum = isCarrierOtaSpNum(dialableStr);
- }
- }
- if (DBG) Log.d(LOG_TAG, "isOtaSpNumber " + isOtaSpNum);
- return isOtaSpNum;
- }
-
- @Override
- public int getCdmaEriIconIndex() {
- return getServiceState().getCdmaEriIconIndex();
- }
-
- /**
- * Returns the CDMA ERI icon mode,
- * 0 - ON
- * 1 - FLASHING
- */
- @Override
- public int getCdmaEriIconMode() {
- return getServiceState().getCdmaEriIconMode();
- }
-
- /**
- * Returns the CDMA ERI text,
- */
- @Override
- public String getCdmaEriText() {
- int roamInd = getServiceState().getCdmaRoamingIndicator();
- int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator();
- return mEriManager.getCdmaEriText(roamInd, defRoamInd);
- }
-
- /**
- * Store the voicemail number in preferences
- */
- private void storeVoiceMailNumber(String number) {
- // Update the preference value of voicemail number
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- SharedPreferences.Editor editor = sp.edit();
- editor.putString(VM_NUMBER_CDMA, number);
- editor.apply();
- }
-
- /**
- * Sets PROPERTY_ICC_OPERATOR_ISO_COUNTRY property
- *
- */
- private void setIsoCountryProperty(String operatorNumeric) {
- if (TextUtils.isEmpty(operatorNumeric)) {
- setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, "");
- } else {
- String iso = "";
- try {
- iso = MccTable.countryCodeForMcc(Integer.parseInt(
- operatorNumeric.substring(0,3)));
- } catch (NumberFormatException ex) {
- Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
- } catch (StringIndexOutOfBoundsException ex) {
- Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
- }
-
- setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, iso);
- }
- }
-
- /**
- * Sets the "current" field in the telephony provider according to the
- * build-time operator numeric property
- *
- * @return true for success; false otherwise.
- */
- boolean updateCurrentCarrierInProvider(String operatorNumeric) {
- if (!TextUtils.isEmpty(operatorNumeric)) {
- try {
- Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
- ContentValues map = new ContentValues();
- map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
- log("updateCurrentCarrierInProvider from system: numeric=" + operatorNumeric);
- getContext().getContentResolver().insert(uri, map);
-
- // Updates MCC MNC device configuration information
- MccTable.updateMccMncConfiguration(mContext, operatorNumeric);
-
- return true;
- } catch (SQLException e) {
- Log.e(LOG_TAG, "Can't store current operator", e);
- }
- }
- return false;
- }
-
- /**
- * Sets the "current" field in the telephony provider according to the SIM's operator.
- * Implemented in {@link CDMALTEPhone} for CDMA/LTE devices.
- *
- * @return true for success; false otherwise.
- */
- boolean updateCurrentCarrierInProvider() {
- return true;
- }
-
- public void prepareEri() {
- mEriManager.loadEriFile();
- if(mEriManager.isEriFileLoaded()) {
- // when the ERI file is loaded
- log("ERI read, notify registrants");
- mEriFileLoadedRegistrants.notifyRegistrants();
- }
- }
-
- public boolean isEriFileLoaded() {
- return mEriManager.isEriFileLoaded();
- }
-
- private void registerForRuimRecordEvents() {
- mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
- mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
- }
-
- private void unregisterForRuimRecordEvents() {
- mIccRecords.unregisterForRecordsEvents(this);
- mIccRecords.unregisterForRecordsLoaded(this);
- }
-
- protected void log(String s) {
- if (DBG)
- Log.d(LOG_TAG, "[CDMAPhone] " + s);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("CDMAPhone extends:");
- super.dump(fd, pw, args);
- pw.println(" mVmNumber=" + mVmNumber);
- pw.println(" mCT=" + mCT);
- pw.println(" mSST=" + mSST);
- pw.println(" mCdmaSSM=" + mCdmaSSM);
- pw.println(" mPendingMmis=" + mPendingMmis);
- pw.println(" mRuimPhoneBookInterfaceManager=" + mRuimPhoneBookInterfaceManager);
- pw.println(" mRuimSmsInterfaceManager=" + mRuimSmsInterfaceManager);
- pw.println(" mCdmaSubscriptionSource=" + mCdmaSubscriptionSource);
- pw.println(" mSubInfo=" + mSubInfo);
- pw.println(" mEriManager=" + mEriManager);
- pw.println(" mWakeLock=" + mWakeLock);
- pw.println(" mIsPhoneInEcmState=" + mIsPhoneInEcmState);
- if (VDBG) pw.println(" mImei=" + mImei);
- if (VDBG) pw.println(" mImeiSv=" + mImeiSv);
- if (VDBG) pw.println(" mEsn=" + mEsn);
- if (VDBG) pw.println(" mMeid=" + mMeid);
- pw.println(" mCarrierOtaSpNumSchema=" + mCarrierOtaSpNumSchema);
- pw.println(" getCdmaEriIconIndex()=" + getCdmaEriIconIndex());
- pw.println(" getCdmaEriIconMode()=" + getCdmaEriIconMode());
- pw.println(" getCdmaEriText()=" + getCdmaEriText());
- pw.println(" isMinInfoReady()=" + isMinInfoReady());
- pw.println(" isCspPlmnEnabled()=" + isCspPlmnEnabled());
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
deleted file mode 100644
index ad6c23c..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.cdma;
-
-/**
- * CDMA Call fail causes covering all the possible failures that are
- * needed to be distinguished by the UI. CDMA call failure reasons
- * are derived from the possible call failure scenarios described
- * in "CDMA IS2000 - Release A (C.S0005-A v6.0)" standard.
- *
- * {@hide}
- *
- */
-public interface CallFailCause {
- static final int NORMAL_CLEARING = 16;
- // Busy Tone
- static final int USER_BUSY = 17;
-
- static final int NORMAL_UNSPECIFIED = 31;
-
- // Congestion Tone
- static final int NO_CIRCUIT_AVAIL = 34;
-
- // others
- static final int ACM_LIMIT_EXCEEDED = 68;
- static final int CALL_BARRED = 240;
- static final int FDN_BLOCKED = 241;
-
- static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000;
- static final int CDMA_DROP = 1001;
- static final int CDMA_INTERCEPT = 1002;
- static final int CDMA_REORDER = 1003;
- static final int CDMA_SO_REJECT = 1004;
- static final int CDMA_RETRY_ORDER = 1005;
- static final int CDMA_ACCESS_FAILURE = 1006;
- static final int CDMA_PREEMPTED = 1007;
-
- // For non-emergency number dialed while in emergency callback mode.
- static final int CDMA_NOT_EMERGENCY = 1008;
-
- // Access Blocked by CDMA Network.
- static final int CDMA_ACCESS_BLOCKED = 1009;
-
- static final int ERROR_UNSPECIFIED = 0xffff;
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
deleted file mode 100644
index 4ad61bb..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * 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.cdma;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DriverCall;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.Call.State;
-
-/**
- * {@hide}
- */
-public final class CdmaCall extends Call {
- /*************************** Instance Variables **************************/
-
- /*package*/ ArrayList<Connection> connections = new ArrayList<Connection>();
- /*package*/ State state = State.IDLE;
- /*package*/ CdmaCallTracker owner;
-
- /***************************** Class Methods *****************************/
-
- static State
- stateFromDCState (DriverCall.State dcState) {
- switch (dcState) {
- case ACTIVE: return State.ACTIVE;
- case HOLDING: return State.HOLDING;
- case DIALING: return State.DIALING;
- case ALERTING: return State.ALERTING;
- case INCOMING: return State.INCOMING;
- case WAITING: return State.WAITING;
- default: throw new RuntimeException ("illegal call state:" + dcState);
- }
- }
-
-
- /****************************** Constructors *****************************/
- /*package*/
- CdmaCall (CdmaCallTracker owner) {
- this.owner = owner;
- }
-
- public void dispose() {
- }
-
- /************************** Overridden from Call *************************/
- public List<Connection>
- getConnections() {
- // FIXME should return Collections.unmodifiableList();
- return connections;
- }
-
- public State
- getState() {
- return state;
- }
-
- public Phone
- getPhone() {
- return owner.phone;
- }
-
- public boolean isMultiparty() {
- return connections.size() > 1;
- }
-
- /** Please note: if this is the foreground call and a
- * background call exists, the background call will be resumed
- * because an AT+CHLD=1 will be sent
- */
- public void
- hangup() throws CallStateException {
- owner.hangup(this);
- }
-
- public String
- toString() {
- return state.toString();
- }
-
- //***** Called from CdmaConnection
-
- /*package*/ void
- attach(Connection conn, DriverCall dc) {
- connections.add(conn);
-
- state = stateFromDCState (dc.state);
- }
-
- /*package*/ void
- attachFake(Connection conn, State state) {
- connections.add(conn);
-
- this.state = state;
- }
-
- /**
- * Called by CdmaConnection when it has disconnected
- */
- void
- connectionDisconnected(CdmaConnection conn) {
- if (state != State.DISCONNECTED) {
- /* If only disconnected connections remain, we are disconnected*/
-
- boolean hasOnlyDisconnectedConnections = true;
-
- for (int i = 0, s = connections.size() ; i < s; i ++) {
- if (connections.get(i).getState()
- != State.DISCONNECTED
- ) {
- hasOnlyDisconnectedConnections = false;
- break;
- }
- }
-
- if (hasOnlyDisconnectedConnections) {
- state = State.DISCONNECTED;
- }
- }
- }
-
-
- /*package*/ void
- detach(CdmaConnection conn) {
- connections.remove(conn);
-
- if (connections.size() == 0) {
- state = State.IDLE;
- }
- }
-
- /*package*/ boolean
- update (CdmaConnection conn, DriverCall dc) {
- State newState;
- boolean changed = false;
-
- newState = stateFromDCState(dc.state);
-
- if (newState != state) {
- state = newState;
- changed = true;
- }
-
- return changed;
- }
-
- /**
- * @return true if there's no space in this call for additional
- * connections to be added via "conference"
- */
- /*package*/ boolean
- isFull() {
- return connections.size() == CdmaCallTracker.MAX_CONNECTIONS_PER_CALL;
- }
-
- //***** Called from CdmaCallTracker
-
-
- /**
- * Called when this Call is being hung up locally (eg, user pressed "end")
- * Note that at this point, the hangup request has been dispatched to the radio
- * but no response has yet been received so update() has not yet been called
- */
- void
- onHangupLocal() {
- for (int i = 0, s = connections.size(); i < s; i++) {
- CdmaConnection cn = (CdmaConnection)connections.get(i);
-
- cn.onHangupLocal();
- }
- state = State.DISCONNECTING;
- }
-
- /**
- * Called when it's time to clean up disconnected Connection objects
- */
- void clearDisconnected() {
- for (int i = connections.size() - 1 ; i >= 0 ; i--) {
- CdmaConnection cn = (CdmaConnection)connections.get(i);
-
- if (cn.getState() == State.DISCONNECTED) {
- connections.remove(i);
- }
- }
-
- if (connections.size() == 0) {
- state = State.IDLE;
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
deleted file mode 100644
index af92b08..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * 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.cdma;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.util.Log;
-import android.os.SystemProperties;
-
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.CallTracker;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DriverCall;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.TelephonyProperties;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * {@hide}
- */
-public final class CdmaCallTracker extends CallTracker {
- static final String LOG_TAG = "CDMA";
-
- private static final boolean REPEAT_POLLING = false;
-
- private static final boolean DBG_POLL = false;
-
- //***** Constants
-
- static final int MAX_CONNECTIONS = 1; // only 1 connection allowed in CDMA
- static final int MAX_CONNECTIONS_PER_CALL = 1; // only 1 connection allowed per call
-
- //***** Instance Variables
-
- CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS];
- RegistrantList voiceCallEndedRegistrants = new RegistrantList();
- RegistrantList voiceCallStartedRegistrants = new RegistrantList();
- RegistrantList callWaitingRegistrants = new RegistrantList();
-
-
- // connections dropped during last poll
- ArrayList<CdmaConnection> droppedDuringPoll
- = new ArrayList<CdmaConnection>(MAX_CONNECTIONS);
-
- CdmaCall ringingCall = new CdmaCall(this);
- // A call that is ringing or (call) waiting
- CdmaCall foregroundCall = new CdmaCall(this);
- CdmaCall backgroundCall = new CdmaCall(this);
-
- CdmaConnection pendingMO;
- boolean hangupPendingMO;
- boolean pendingCallInEcm=false;
- boolean mIsInEmergencyCall = false;
- CDMAPhone phone;
-
- boolean desiredMute = false; // false = mute off
-
- int pendingCallClirMode;
- Phone.State state = Phone.State.IDLE;
-
- private boolean mIsEcmTimerCanceled = false;
-
-// boolean needsPoll;
-
-
-
- //***** Events
-
- //***** Constructors
- CdmaCallTracker(CDMAPhone phone) {
- this.phone = phone;
- cm = phone.mCM;
- cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
- cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
- cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
- cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
- foregroundCall.setGeneric(false);
- }
-
- public void dispose() {
- cm.unregisterForCallStateChanged(this);
- cm.unregisterForOn(this);
- cm.unregisterForNotAvailable(this);
- cm.unregisterForCallWaitingInfo(this);
- for(CdmaConnection c : connections) {
- try {
- if(c != null) hangup(c);
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "unexpected error on hangup during dispose");
- }
- }
-
- try {
- if(pendingMO != null) hangup(pendingMO);
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "unexpected error on hangup during dispose");
- }
-
- clearDisconnected();
-
- }
-
- @Override
- protected void finalize() {
- Log.d(LOG_TAG, "CdmaCallTracker finalized");
- }
-
- //***** Instance Methods
-
- //***** Public Methods
- public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- voiceCallStartedRegistrants.add(r);
- // Notify if in call when registering
- if (state != Phone.State.IDLE) {
- r.notifyRegistrant(new AsyncResult(null, null, null));
- }
- }
- public void unregisterForVoiceCallStarted(Handler h) {
- voiceCallStartedRegistrants.remove(h);
- }
-
- public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- voiceCallEndedRegistrants.add(r);
- }
-
- public void unregisterForVoiceCallEnded(Handler h) {
- voiceCallEndedRegistrants.remove(h);
- }
-
- public void registerForCallWaiting(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- callWaitingRegistrants.add(r);
- }
-
- public void unregisterForCallWaiting(Handler h) {
- callWaitingRegistrants.remove(h);
- }
-
- private void
- fakeHoldForegroundBeforeDial() {
- List<Connection> connCopy;
-
- // We need to make a copy here, since fakeHoldBeforeDial()
- // modifies the lists, and we don't want to reverse the order
- connCopy = (List<Connection>) foregroundCall.connections.clone();
-
- for (int i = 0, s = connCopy.size() ; i < s ; i++) {
- CdmaConnection conn = (CdmaConnection)connCopy.get(i);
-
- conn.fakeHoldBeforeDial();
- }
- }
-
- /**
- * clirMode is one of the CLIR_ constants
- */
- Connection
- dial (String dialString, int clirMode) throws CallStateException {
- // note that this triggers call state changed notif
- clearDisconnected();
-
- if (!canDial()) {
- throw new CallStateException("cannot dial in current state");
- }
-
- String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- boolean isPhoneInEcmMode = inEcm.equals("true");
- boolean isEmergencyCall =
- PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext());
-
- // Cancel Ecm timer if a second emergency call is originating in Ecm mode
- if (isPhoneInEcmMode && isEmergencyCall) {
- handleEcmTimer(phone.CANCEL_ECM_TIMER);
- }
-
- // We are initiating a call therefore even if we previously
- // didn't know the state (i.e. Generic was true) we now know
- // and therefore can set Generic to false.
- foregroundCall.setGeneric(false);
-
- // The new call must be assigned to the foreground call.
- // That call must be idle, so place anything that's
- // there on hold
- if (foregroundCall.getState() == CdmaCall.State.ACTIVE) {
- return dialThreeWay(dialString);
- }
-
- pendingMO = new CdmaConnection(phone.getContext(), checkForTestEmergencyNumber(dialString),
- this, foregroundCall);
- hangupPendingMO = false;
-
- if (pendingMO.address == null || pendingMO.address.length() == 0
- || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) {
- // Phone number is invalid
- pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
-
- // handlePollCalls() will notice this call not present
- // and will mark it as dropped.
- pollCallsWhenSafe();
- } else {
- // Always unmute when initiating a new call
- setMute(false);
-
- // Check data call
- disableDataCallInEmergencyCall(dialString);
-
- // In Ecm mode, if another emergency call is dialed, Ecm mode will not exit.
- if(!isPhoneInEcmMode || (isPhoneInEcmMode && isEmergencyCall)) {
- cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
- } else {
- phone.exitEmergencyCallbackMode();
- phone.setOnEcbModeExitResponse(this,EVENT_EXIT_ECM_RESPONSE_CDMA, null);
- pendingCallClirMode=clirMode;
- pendingCallInEcm=true;
- }
- }
-
- updatePhoneState();
- phone.notifyPreciseCallStateChanged();
-
- return pendingMO;
- }
-
-
- Connection
- dial (String dialString) throws CallStateException {
- return dial(dialString, CommandsInterface.CLIR_DEFAULT);
- }
-
- private Connection
- dialThreeWay (String dialString) {
- if (!foregroundCall.isIdle()) {
- // Check data call
- disableDataCallInEmergencyCall(dialString);
-
- // Attach the new connection to foregroundCall
- pendingMO = new CdmaConnection(phone.getContext(),
- checkForTestEmergencyNumber(dialString), this, foregroundCall);
- cm.sendCDMAFeatureCode(pendingMO.address,
- obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
- return pendingMO;
- }
- return null;
- }
-
- void
- acceptCall() throws CallStateException {
- if (ringingCall.getState() == CdmaCall.State.INCOMING) {
- Log.i("phone", "acceptCall: incoming...");
- // Always unmute when answering a new call
- setMute(false);
- cm.acceptCall(obtainCompleteMessage());
- } else if (ringingCall.getState() == CdmaCall.State.WAITING) {
- CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection());
-
- // Since there is no network response for supplimentary
- // service for CDMA, we assume call waiting is answered.
- // ringing Call state change to idle is in CdmaCall.detach
- // triggered by updateParent.
- cwConn.updateParent(ringingCall, foregroundCall);
- cwConn.onConnectedInOrOut();
- updatePhoneState();
- switchWaitingOrHoldingAndActive();
- } else {
- throw new CallStateException("phone not ringing");
- }
- }
-
- void
- rejectCall () throws CallStateException {
- // AT+CHLD=0 means "release held or UDUB"
- // so if the phone isn't ringing, this could hang up held
- if (ringingCall.getState().isRinging()) {
- cm.rejectCall(obtainCompleteMessage());
- } else {
- throw new CallStateException("phone not ringing");
- }
- }
-
- void
- switchWaitingOrHoldingAndActive() throws CallStateException {
- // Should we bother with this check?
- if (ringingCall.getState() == CdmaCall.State.INCOMING) {
- throw new CallStateException("cannot be in the incoming state");
- } else if (foregroundCall.getConnections().size() > 1) {
- flashAndSetGenericTrue();
- } else {
- // Send a flash command to CDMA network for putting the other party on hold.
- // For CDMA networks which do not support this the user would just hear a beep
- // from the network. For CDMA networks which do support it will put the other
- // party on hold.
- cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
- }
- }
-
- void
- conference() throws CallStateException {
- // Should we be checking state?
- flashAndSetGenericTrue();
- }
-
- void
- explicitCallTransfer() throws CallStateException {
- cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
- }
-
- void
- clearDisconnected() {
- internalClearDisconnected();
-
- updatePhoneState();
- phone.notifyPreciseCallStateChanged();
- }
-
- boolean
- canConference() {
- return foregroundCall.getState() == CdmaCall.State.ACTIVE
- && backgroundCall.getState() == CdmaCall.State.HOLDING
- && !backgroundCall.isFull()
- && !foregroundCall.isFull();
- }
-
- boolean
- canDial() {
- boolean ret;
- int serviceState = phone.getServiceState().getState();
- String disableCall = SystemProperties.get(
- TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
-
- ret = (serviceState != ServiceState.STATE_POWER_OFF)
- && pendingMO == null
- && !ringingCall.isRinging()
- && !disableCall.equals("true")
- && (!foregroundCall.getState().isAlive()
- || (foregroundCall.getState() == CdmaCall.State.ACTIVE)
- || !backgroundCall.getState().isAlive());
-
- if (!ret) {
- log(String.format("canDial is false\n" +
- "((serviceState=%d) != ServiceState.STATE_POWER_OFF)::=%s\n" +
- "&& pendingMO == null::=%s\n" +
- "&& !ringingCall.isRinging()::=%s\n" +
- "&& !disableCall.equals(\"true\")::=%s\n" +
- "&& (!foregroundCall.getState().isAlive()::=%s\n" +
- " || foregroundCall.getState() == CdmaCall.State.ACTIVE::=%s\n" +
- " ||!backgroundCall.getState().isAlive())::=%s)",
- serviceState,
- serviceState != ServiceState.STATE_POWER_OFF,
- pendingMO == null,
- !ringingCall.isRinging(),
- !disableCall.equals("true"),
- !foregroundCall.getState().isAlive(),
- foregroundCall.getState() == CdmaCall.State.ACTIVE,
- !backgroundCall.getState().isAlive()));
- }
- return ret;
- }
-
- boolean
- canTransfer() {
- Log.e(LOG_TAG, "canTransfer: not possible in CDMA");
- return false;
- }
-
- //***** Private Instance Methods
-
- private void
- internalClearDisconnected() {
- ringingCall.clearDisconnected();
- foregroundCall.clearDisconnected();
- backgroundCall.clearDisconnected();
- }
-
- /**
- * Obtain a message to use for signalling "invoke getCurrentCalls() when
- * this operation and all other pending operations are complete
- */
- private Message
- obtainCompleteMessage() {
- return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
- }
-
- /**
- * Obtain a message to use for signalling "invoke getCurrentCalls() when
- * this operation and all other pending operations are complete
- */
- private Message
- obtainCompleteMessage(int what) {
- pendingOperations++;
- lastRelevantPoll = null;
- needsPoll = true;
-
- if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
- pendingOperations + ", needsPoll=" + needsPoll);
-
- return obtainMessage(what);
- }
-
- private void
- operationComplete() {
- pendingOperations--;
-
- if (DBG_POLL) log("operationComplete: pendingOperations=" +
- pendingOperations + ", needsPoll=" + needsPoll);
-
- if (pendingOperations == 0 && needsPoll) {
- lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
- cm.getCurrentCalls(lastRelevantPoll);
- } else if (pendingOperations < 0) {
- // this should never happen
- Log.e(LOG_TAG,"CdmaCallTracker.pendingOperations < 0");
- pendingOperations = 0;
- }
- }
-
-
-
- private void
- updatePhoneState() {
- Phone.State oldState = state;
-
- if (ringingCall.isRinging()) {
- state = Phone.State.RINGING;
- } else if (pendingMO != null ||
- !(foregroundCall.isIdle() && backgroundCall.isIdle())) {
- state = Phone.State.OFFHOOK;
- } else {
- state = Phone.State.IDLE;
- }
-
- if (state == Phone.State.IDLE && oldState != state) {
- voiceCallEndedRegistrants.notifyRegistrants(
- new AsyncResult(null, null, null));
- } else if (oldState == Phone.State.IDLE && oldState != state) {
- voiceCallStartedRegistrants.notifyRegistrants (
- new AsyncResult(null, null, null));
- }
- if (Phone.DEBUG_PHONE) {
- log("update phone state, old=" + oldState + " new="+ state);
- }
- if (state != oldState) {
- phone.notifyPhoneStateChanged();
- }
- }
-
- // ***** Overwritten from CallTracker
-
- protected void
- handlePollCalls(AsyncResult ar) {
- List polledCalls;
-
- if (ar.exception == null) {
- polledCalls = (List)ar.result;
- } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
- // just a dummy empty ArrayList to cause the loop
- // to hang up all the calls
- polledCalls = new ArrayList();
- } else {
- // Radio probably wasn't ready--try again in a bit
- // But don't keep polling if the channel is closed
- pollCallsAfterDelay();
- return;
- }
-
- Connection newRinging = null; //or waiting
- boolean hasNonHangupStateChanged = false; // Any change besides
- // a dropped connection
- boolean needsPollDelay = false;
- boolean unknownConnectionAppeared = false;
-
- for (int i = 0, curDC = 0, dcSize = polledCalls.size()
- ; i < connections.length; i++) {
- CdmaConnection conn = connections[i];
- DriverCall dc = null;
-
- // polledCall list is sparse
- if (curDC < dcSize) {
- dc = (DriverCall) polledCalls.get(curDC);
-
- if (dc.index == i+1) {
- curDC++;
- } else {
- dc = null;
- }
- }
-
- if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
- conn+", dc=" + dc);
-
- if (conn == null && dc != null) {
- // Connection appeared in CLCC response that we don't know about
- if (pendingMO != null && pendingMO.compareTo(dc)) {
-
- if (DBG_POLL) log("poll: pendingMO=" + pendingMO);
-
- // It's our pending mobile originating call
- connections[i] = pendingMO;
- pendingMO.index = i;
- pendingMO.update(dc);
- pendingMO = null;
-
- // Someone has already asked to hangup this call
- if (hangupPendingMO) {
- hangupPendingMO = false;
- // Re-start Ecm timer when an uncompleted emergency call ends
- if (mIsEcmTimerCanceled) {
- handleEcmTimer(phone.RESTART_ECM_TIMER);
- }
-
- try {
- if (Phone.DEBUG_PHONE) log(
- "poll: hangupPendingMO, hangup conn " + i);
- hangup(connections[i]);
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "unexpected error on hangup");
- }
-
- // Do not continue processing this poll
- // Wait for hangup and repoll
- return;
- }
- } else {
- if (Phone.DEBUG_PHONE) {
- log("pendingMo=" + pendingMO + ", dc=" + dc);
- }
- // find if the MT call is a new ring or unknown connection
- newRinging = checkMtFindNewRinging(dc,i);
- if (newRinging == null) {
- unknownConnectionAppeared = true;
- }
- checkAndEnableDataCallAfterEmergencyCallDropped();
- }
- hasNonHangupStateChanged = true;
- } else if (conn != null && dc == null) {
- // This case means the RIL has no more active call anymore and
- // we need to clean up the foregroundCall and ringingCall.
- // Loop through foreground call connections as
- // it contains the known logical connections.
- int count = foregroundCall.connections.size();
- for (int n = 0; n < count; n++) {
- if (Phone.DEBUG_PHONE) log("adding fgCall cn " + n + " to droppedDuringPoll");
- CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
- droppedDuringPoll.add(cn);
- }
- count = ringingCall.connections.size();
- // Loop through ringing call connections as
- // it may contain the known logical connections.
- for (int n = 0; n < count; n++) {
- if (Phone.DEBUG_PHONE) log("adding rgCall cn " + n + " to droppedDuringPoll");
- CdmaConnection cn = (CdmaConnection)ringingCall.connections.get(n);
- droppedDuringPoll.add(cn);
- }
- foregroundCall.setGeneric(false);
- ringingCall.setGeneric(false);
-
- // Re-start Ecm timer when the connected emergency call ends
- if (mIsEcmTimerCanceled) {
- handleEcmTimer(phone.RESTART_ECM_TIMER);
- }
- // If emergency call is not going through while dialing
- checkAndEnableDataCallAfterEmergencyCallDropped();
-
- // Dropped connections are removed from the CallTracker
- // list but kept in the Call list
- connections[i] = null;
- } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
- // Call collision case
- if (conn.isIncoming != dc.isMT) {
- if (dc.isMT == true){
- // Mt call takes precedence than Mo,drops Mo
- droppedDuringPoll.add(conn);
- // find if the MT call is a new ring or unknown connection
- newRinging = checkMtFindNewRinging(dc,i);
- if (newRinging == null) {
- unknownConnectionAppeared = true;
- }
- checkAndEnableDataCallAfterEmergencyCallDropped();
- } else {
- // Call info stored in conn is not consistent with the call info from dc.
- // We should follow the rule of MT calls taking precedence over MO calls
- // when there is conflict, so here we drop the call info from dc and
- // continue to use the call info from conn, and only take a log.
- Log.e(LOG_TAG,"Error in RIL, Phantom call appeared " + dc);
- }
- } else {
- boolean changed;
- changed = conn.update(dc);
- hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
- }
- }
-
- if (REPEAT_POLLING) {
- if (dc != null) {
- // FIXME with RIL, we should not need this anymore
- if ((dc.state == DriverCall.State.DIALING
- /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
- || (dc.state == DriverCall.State.ALERTING
- /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
- || (dc.state == DriverCall.State.INCOMING
- /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
- || (dc.state == DriverCall.State.WAITING
- /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
- ) {
- // Sometimes there's no unsolicited notification
- // for state transitions
- needsPollDelay = true;
- }
- }
- }
- }
-
- // This is the first poll after an ATD.
- // We expect the pending call to appear in the list
- // If it does not, we land here
- if (pendingMO != null) {
- Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
- + foregroundCall.getState());
-
- droppedDuringPoll.add(pendingMO);
- pendingMO = null;
- hangupPendingMO = false;
- if( pendingCallInEcm) {
- pendingCallInEcm = false;
- }
- }
-
- if (newRinging != null) {
- phone.notifyNewRingingConnection(newRinging);
- }
-
- // clear the "local hangup" and "missed/rejected call"
- // cases from the "dropped during poll" list
- // These cases need no "last call fail" reason
- for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) {
- CdmaConnection conn = droppedDuringPoll.get(i);
-
- if (conn.isIncoming() && conn.getConnectTime() == 0) {
- // Missed or rejected call
- Connection.DisconnectCause cause;
- if (conn.cause == Connection.DisconnectCause.LOCAL) {
- cause = Connection.DisconnectCause.INCOMING_REJECTED;
- } else {
- cause = Connection.DisconnectCause.INCOMING_MISSED;
- }
-
- if (Phone.DEBUG_PHONE) {
- log("missed/rejected call, conn.cause=" + conn.cause);
- log("setting cause to " + cause);
- }
- droppedDuringPoll.remove(i);
- conn.onDisconnect(cause);
- } else if (conn.cause == Connection.DisconnectCause.LOCAL) {
- // Local hangup
- droppedDuringPoll.remove(i);
- conn.onDisconnect(Connection.DisconnectCause.LOCAL);
- } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) {
- droppedDuringPoll.remove(i);
- conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
- }
- }
-
- // Any non-local disconnects: determine cause
- if (droppedDuringPoll.size() > 0) {
- cm.getLastCallFailCause(
- obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
- }
-
- if (needsPollDelay) {
- pollCallsAfterDelay();
- }
-
- // Cases when we can no longer keep disconnected Connection's
- // with their previous calls
- // 1) the phone has started to ring
- // 2) A Call/Connection object has changed state...
- // we may have switched or held or answered (but not hung up)
- if (newRinging != null || hasNonHangupStateChanged) {
- internalClearDisconnected();
- }
-
- updatePhoneState();
-
- if (unknownConnectionAppeared) {
- phone.notifyUnknownConnection();
- }
-
- if (hasNonHangupStateChanged || newRinging != null) {
- phone.notifyPreciseCallStateChanged();
- }
-
- //dumpState();
- }
-
- //***** Called from CdmaConnection
- /*package*/ void
- hangup (CdmaConnection conn) throws CallStateException {
- if (conn.owner != this) {
- throw new CallStateException ("CdmaConnection " + conn
- + "does not belong to CdmaCallTracker " + this);
- }
-
- if (conn == pendingMO) {
- // We're hanging up an outgoing call that doesn't have it's
- // GSM index assigned yet
-
- if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
- hangupPendingMO = true;
- } else if ((conn.getCall() == ringingCall)
- && (ringingCall.getState() == CdmaCall.State.WAITING)) {
- // Handle call waiting hang up case.
- //
- // The ringingCall state will change to IDLE in CdmaCall.detach
- // if the ringing call connection size is 0. We don't specifically
- // set the ringing call state to IDLE here to avoid a race condition
- // where a new call waiting could get a hang up from an old call
- // waiting ringingCall.
- //
- // PhoneApp does the call log itself since only PhoneApp knows
- // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
- // is not called here. Instead, conn.onLocalDisconnect() is called.
- conn.onLocalDisconnect();
- updatePhoneState();
- phone.notifyPreciseCallStateChanged();
- return;
- } else {
- try {
- cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
- } catch (CallStateException ex) {
- // Ignore "connection not found"
- // Call may have hung up already
- Log.w(LOG_TAG,"CdmaCallTracker WARN: hangup() on absent connection "
- + conn);
- }
- }
-
- conn.onHangupLocal();
- }
-
- /*package*/ void
- separate (CdmaConnection conn) throws CallStateException {
- if (conn.owner != this) {
- throw new CallStateException ("CdmaConnection " + conn
- + "does not belong to CdmaCallTracker " + this);
- }
- try {
- cm.separateConnection (conn.getCDMAIndex(),
- obtainCompleteMessage(EVENT_SEPARATE_RESULT));
- } catch (CallStateException ex) {
- // Ignore "connection not found"
- // Call may have hung up already
- Log.w(LOG_TAG,"CdmaCallTracker WARN: separate() on absent connection "
- + conn);
- }
- }
-
- //***** Called from CDMAPhone
-
- /*package*/ void
- setMute(boolean mute) {
- desiredMute = mute;
- cm.setMute(desiredMute, null);
- }
-
- /*package*/ boolean
- getMute() {
- return desiredMute;
- }
-
-
- //***** Called from CdmaCall
-
- /* package */ void
- hangup (CdmaCall call) throws CallStateException {
- if (call.getConnections().size() == 0) {
- throw new CallStateException("no connections in call");
- }
-
- if (call == ringingCall) {
- if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
- cm.hangupWaitingOrBackground(obtainCompleteMessage());
- } else if (call == foregroundCall) {
- if (call.isDialingOrAlerting()) {
- if (Phone.DEBUG_PHONE) {
- log("(foregnd) hangup dialing or alerting...");
- }
- hangup((CdmaConnection)(call.getConnections().get(0)));
- } else {
- hangupForegroundResumeBackground();
- }
- } else if (call == backgroundCall) {
- if (ringingCall.isRinging()) {
- if (Phone.DEBUG_PHONE) {
- log("hangup all conns in background call");
- }
- hangupAllConnections(call);
- } else {
- hangupWaitingOrBackground();
- }
- } else {
- throw new RuntimeException ("CdmaCall " + call +
- "does not belong to CdmaCallTracker " + this);
- }
-
- call.onHangupLocal();
- phone.notifyPreciseCallStateChanged();
- }
-
- /* package */
- void hangupWaitingOrBackground() {
- if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
- cm.hangupWaitingOrBackground(obtainCompleteMessage());
- }
-
- /* package */
- void hangupForegroundResumeBackground() {
- if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
- cm.hangupForegroundResumeBackground(obtainCompleteMessage());
- }
-
- void hangupConnectionByIndex(CdmaCall call, int index)
- throws CallStateException {
- int count = call.connections.size();
- for (int i = 0; i < count; i++) {
- CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- if (cn.getCDMAIndex() == index) {
- cm.hangupConnection(index, obtainCompleteMessage());
- return;
- }
- }
-
- throw new CallStateException("no gsm index found");
- }
-
- void hangupAllConnections(CdmaCall call) throws CallStateException{
- try {
- int count = call.connections.size();
- for (int i = 0; i < count; i++) {
- CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- cm.hangupConnection(cn.getCDMAIndex(), obtainCompleteMessage());
- }
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
- }
- }
-
- /* package */
- CdmaConnection getConnectionByIndex(CdmaCall call, int index)
- throws CallStateException {
- int count = call.connections.size();
- for (int i = 0; i < count; i++) {
- CdmaConnection cn = (CdmaConnection)call.connections.get(i);
- if (cn.getCDMAIndex() == index) {
- return cn;
- }
- }
-
- return null;
- }
-
- private void flashAndSetGenericTrue() throws CallStateException {
- cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
-
- // Set generic to true because in CDMA it is not known what
- // the status of the call is after a call waiting is answered,
- // 3 way call merged or a switch between calls.
- foregroundCall.setGeneric(true);
- phone.notifyPreciseCallStateChanged();
- }
-
- private Phone.SuppService getFailedService(int what) {
- switch (what) {
- case EVENT_SWITCH_RESULT:
- return Phone.SuppService.SWITCH;
- case EVENT_CONFERENCE_RESULT:
- return Phone.SuppService.CONFERENCE;
- case EVENT_SEPARATE_RESULT:
- return Phone.SuppService.SEPARATE;
- case EVENT_ECT_RESULT:
- return Phone.SuppService.TRANSFER;
- }
- return Phone.SuppService.UNKNOWN;
- }
-
- private void handleRadioNotAvailable() {
- // handlePollCalls will clear out its
- // call list when it gets the CommandException
- // error result from this
- pollCallsWhenSafe();
- }
-
- private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
- if (callWaitingRegistrants != null) {
- callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
- }
- }
-
- private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) {
- // Check how many connections in foregroundCall.
- // If the connection in foregroundCall is more
- // than one, then the connection information is
- // not reliable anymore since it means either
- // call waiting is connected or 3 way call is
- // dialed before, so set generic.
- if (foregroundCall.connections.size() > 1 ) {
- foregroundCall.setGeneric(true);
- }
-
- // Create a new CdmaConnection which attaches itself to ringingCall.
- ringingCall.setGeneric(false);
- new CdmaConnection(phone.getContext(), cw, this, ringingCall);
- updatePhoneState();
-
- // Finally notify application
- notifyCallWaitingInfo(cw);
- }
- //****** Overridden from Handler
-
- public void
- handleMessage (Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_POLL_CALLS_RESULT:{
- Log.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
- ar = (AsyncResult)msg.obj;
-
- if(msg == lastRelevantPoll) {
- if(DBG_POLL) log(
- "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
- needsPoll = false;
- lastRelevantPoll = null;
- handlePollCalls((AsyncResult)msg.obj);
- }
- }
- break;
-
- case EVENT_OPERATION_COMPLETE:
- operationComplete();
- break;
-
- case EVENT_SWITCH_RESULT:
- // In GSM call operationComplete() here which gets the
- // current call list. But in CDMA there is no list so
- // there is nothing to do.
- break;
-
- case EVENT_GET_LAST_CALL_FAIL_CAUSE:
- int causeCode;
- ar = (AsyncResult)msg.obj;
-
- operationComplete();
-
- if (ar.exception != null) {
- // An exception occurred...just treat the disconnect
- // cause as "normal"
- causeCode = CallFailCause.NORMAL_CLEARING;
- Log.i(LOG_TAG,
- "Exception during getLastCallFailCause, assuming normal disconnect");
- } else {
- causeCode = ((int[])ar.result)[0];
- }
-
- for (int i = 0, s = droppedDuringPoll.size()
- ; i < s ; i++
- ) {
- CdmaConnection conn = droppedDuringPoll.get(i);
-
- conn.onRemoteDisconnect(causeCode);
- }
-
- updatePhoneState();
-
- phone.notifyPreciseCallStateChanged();
- droppedDuringPoll.clear();
- break;
-
- case EVENT_REPOLL_AFTER_DELAY:
- case EVENT_CALL_STATE_CHANGE:
- pollCallsWhenSafe();
- break;
-
- case EVENT_RADIO_AVAILABLE:
- handleRadioAvailable();
- break;
-
- case EVENT_RADIO_NOT_AVAILABLE:
- handleRadioNotAvailable();
- break;
-
- case EVENT_EXIT_ECM_RESPONSE_CDMA:
- //no matter the result, we still do the same here
- if (pendingCallInEcm) {
- cm.dial(pendingMO.address, pendingCallClirMode, obtainCompleteMessage());
- pendingCallInEcm = false;
- }
- phone.unsetOnEcbModeExitResponse(this);
- break;
-
- case EVENT_CALL_WAITING_INFO_CDMA:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
- Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
- }
- break;
-
- case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- // Assume 3 way call is connected
- pendingMO.onConnectedInOrOut();
- pendingMO = null;
- }
- break;
-
- default:{
- throw new RuntimeException("unexpected event not handled");
- }
- }
- }
-
- /**
- * Handle Ecm timer to be canceled or re-started
- */
- private void handleEcmTimer(int action) {
- phone.handleTimerInEmergencyCallbackMode(action);
- switch(action) {
- case CDMAPhone.CANCEL_ECM_TIMER: mIsEcmTimerCanceled = true; break;
- case CDMAPhone.RESTART_ECM_TIMER: mIsEcmTimerCanceled = false; break;
- default:
- Log.e(LOG_TAG, "handleEcmTimer, unsupported action " + action);
- }
- }
-
- /**
- * Disable data call when emergency call is connected
- */
- private void disableDataCallInEmergencyCall(String dialString) {
- if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
- if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
- mIsInEmergencyCall = true;
- phone.mDataConnectionTracker.setInternalDataEnabled(false);
- }
- }
-
- /**
- * Check and enable data call after an emergency call is dropped if it's
- * not in ECM
- */
- private void checkAndEnableDataCallAfterEmergencyCallDropped() {
- if (mIsInEmergencyCall) {
- mIsInEmergencyCall = false;
- String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- if (Phone.DEBUG_PHONE) {
- log("checkAndEnableDataCallAfterEmergencyCallDropped,inEcm=" + inEcm);
- }
- if (inEcm.compareTo("false") == 0) {
- // Re-initiate data connection
- phone.mDataConnectionTracker.setInternalDataEnabled(true);
- }
- }
- }
-
- /**
- * Check the MT call to see if it's a new ring or
- * a unknown connection.
- */
- private Connection checkMtFindNewRinging(DriverCall dc, int i) {
-
- Connection newRinging = null;
-
- connections[i] = new CdmaConnection(phone.getContext(), dc, this, i);
- // it's a ringing call
- if (connections[i].getCall() == ringingCall) {
- newRinging = connections[i];
- if (Phone.DEBUG_PHONE) log("Notify new ring " + dc);
- } else {
- // Something strange happened: a call which is neither
- // a ringing call nor the one we created. It could be the
- // call collision result from RIL
- Log.e(LOG_TAG,"Phantom call appeared " + dc);
- // If it's a connected call, set the connect time so that
- // it's non-zero. It may not be accurate, but at least
- // it won't appear as a Missed Call.
- if (dc.state != DriverCall.State.ALERTING
- && dc.state != DriverCall.State.DIALING) {
- connections[i].connectTime = System.currentTimeMillis();
- }
- }
- return newRinging;
- }
-
- /**
- * Check if current call is in emergency call
- *
- * @return true if it is in emergency call
- * false if it is not in emergency call
- */
- boolean isInEmergencyCall() {
- return mIsInEmergencyCall;
- }
-
- protected void log(String msg) {
- Log.d(LOG_TAG, "[CdmaCallTracker] " + msg);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("GsmCallTracker extends:");
- super.dump(fd, pw, args);
- pw.println("droppedDuringPoll: length=" + connections.length);
- for(int i=0; i < connections.length; i++) {
- pw.printf(" connections[%d]=%s\n", i, connections[i]);
- }
- pw.println(" voiceCallEndedRegistrants=" + voiceCallEndedRegistrants);
- pw.println(" voiceCallStartedRegistrants=" + voiceCallStartedRegistrants);
- pw.println(" callWaitingRegistrants=" + callWaitingRegistrants);
- pw.println("droppedDuringPoll: size=" + droppedDuringPoll.size());
- for(int i = 0; i < droppedDuringPoll.size(); i++) {
- pw.printf( " droppedDuringPoll[%d]=%s\n", i, droppedDuringPoll.get(i));
- }
- pw.println(" ringingCall=" + ringingCall);
- pw.println(" foregroundCall=" + foregroundCall);
- pw.println(" backgroundCall=" + backgroundCall);
- pw.println(" pendingMO=" + pendingMO);
- pw.println(" hangupPendingMO=" + hangupPendingMO);
- pw.println(" pendingCallInEcm=" + pendingCallInEcm);
- pw.println(" mIsInEmergencyCall=" + mIsInEmergencyCall);
- pw.println(" phone=" + phone);
- pw.println(" desiredMute=" + desiredMute);
- pw.println(" pendingCallClirMode=" + pendingCallClirMode);
- pw.println(" state=" + state);
- pw.println(" mIsEcmTimerCanceled=" + mIsEcmTimerCanceled);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
deleted file mode 100644
index 81ff042..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 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.cdma;
-
-import android.util.Log;
-import com.android.internal.telephony.Connection;
-
-/**
- * Represents a Supplementary Service Notification received from the network.
- *
- * {@hide}
- */
-public class CdmaCallWaitingNotification {
- static final String LOG_TAG = "CDMA";
- public String number = null;
- public int numberPresentation = 0;
- public String name = null;
- public int namePresentation = 0;
- public int numberType = 0;
- public int numberPlan = 0;
- public int isPresent = 0;
- public int signalType = 0;
- public int alertPitch = 0;
- public int signal = 0;
-
- public String toString()
- {
- return super.toString() + "Call Waiting Notification "
- + " number: " + number
- + " numberPresentation: " + numberPresentation
- + " name: " + name
- + " namePresentation: " + namePresentation
- + " numberType: " + numberType
- + " numberPlan: " + numberPlan
- + " isPresent: " + isPresent
- + " signalType: " + signalType
- + " alertPitch: " + alertPitch
- + " signal: " + signal ;
- }
-
- public static int
- presentationFromCLIP(int cli)
- {
- switch(cli) {
- case 0: return Connection.PRESENTATION_ALLOWED;
- case 1: return Connection.PRESENTATION_RESTRICTED;
- case 2: return Connection.PRESENTATION_UNKNOWN;
- default:
- // This shouldn't happen, just log an error and treat as Unknown
- Log.d(LOG_TAG, "Unexpected presentation " + cli);
- return Connection.PRESENTATION_UNKNOWN;
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
deleted file mode 100755
index 98ad3b1..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ /dev/null
@@ -1,955 +0,0 @@
-/*
- * 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.cdma;
-
-import com.android.internal.telephony.*;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Log;
-import android.text.TextUtils;
-
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.RILConstants;
-
-/**
- * {@hide}
- */
-public class CdmaConnection extends Connection {
- static final String LOG_TAG = "CDMA";
-
- //***** Instance Variables
-
- CdmaCallTracker owner;
- CdmaCall parent;
-
-
- String address; // MAY BE NULL!!!
- String dialString; // outgoing calls only
- String postDialString; // outgoing calls only
- boolean isIncoming;
- boolean disconnected;
- String cnapName;
- int index; // index in CdmaCallTracker.connections[], -1 if unassigned
-
- /*
- * These time/timespan values are based on System.currentTimeMillis(),
- * i.e., "wall clock" time.
- */
- long createTime;
- long connectTime;
- long disconnectTime;
-
- /*
- * These time/timespan values are based on SystemClock.elapsedRealTime(),
- * i.e., time since boot. They are appropriate for comparison and
- * calculating deltas.
- */
- long connectTimeReal;
- long duration;
- long holdingStartTime; // The time when the Connection last transitioned
- // into HOLDING
-
- int nextPostDialChar; // index into postDialString
-
- DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
- PostDialState postDialState = PostDialState.NOT_STARTED;
- int numberPresentation = Connection.PRESENTATION_ALLOWED;
- int cnapNamePresentation = Connection.PRESENTATION_ALLOWED;
-
-
- Handler h;
-
- private PowerManager.WakeLock mPartialWakeLock;
-
- //***** Event Constants
- static final int EVENT_DTMF_DONE = 1;
- static final int EVENT_PAUSE_DONE = 2;
- static final int EVENT_NEXT_POST_DIAL = 3;
- static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
-
- //***** Constants
- static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
- static final int PAUSE_DELAY_MILLIS = 2 * 1000;
-
- //***** Inner Classes
-
- class MyHandler extends Handler {
- MyHandler(Looper l) {super(l);}
-
- public void
- handleMessage(Message msg) {
-
- switch (msg.what) {
- case EVENT_NEXT_POST_DIAL:
- case EVENT_DTMF_DONE:
- case EVENT_PAUSE_DONE:
- processNextPostDialChar();
- break;
- case EVENT_WAKE_LOCK_TIMEOUT:
- releaseWakeLock();
- break;
- }
- }
- }
-
- //***** Constructors
-
- /** This is probably an MT call that we first saw in a CLCC response */
- /*package*/
- CdmaConnection (Context context, DriverCall dc, CdmaCallTracker ct, int index) {
- createWakeLock(context);
- acquireWakeLock();
-
- owner = ct;
- h = new MyHandler(owner.getLooper());
-
- address = dc.number;
-
- isIncoming = dc.isMT;
- createTime = System.currentTimeMillis();
- cnapName = dc.name;
- cnapNamePresentation = dc.namePresentation;
- numberPresentation = dc.numberPresentation;
-
- this.index = index;
-
- parent = parentFromDCState (dc.state);
- parent.attach(this, dc);
- }
-
- /** This is an MO call/three way call, created when dialing */
- /*package*/
- CdmaConnection(Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) {
- createWakeLock(context);
- acquireWakeLock();
-
- owner = ct;
- h = new MyHandler(owner.getLooper());
-
- this.dialString = dialString;
- Log.d(LOG_TAG, "[CDMAConn] CdmaConnection: dialString=" + dialString);
- dialString = formatDialString(dialString);
- Log.d(LOG_TAG, "[CDMAConn] CdmaConnection:formated dialString=" + dialString);
-
- this.address = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
- this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
-
- index = -1;
-
- isIncoming = false;
- cnapName = null;
- cnapNamePresentation = Connection.PRESENTATION_ALLOWED;
- numberPresentation = Connection.PRESENTATION_ALLOWED;
- createTime = System.currentTimeMillis();
-
- if (parent != null) {
- this.parent = parent;
-
- //for the three way call case, not change parent state
- if (parent.state == CdmaCall.State.ACTIVE) {
- parent.attachFake(this, CdmaCall.State.ACTIVE);
- } else {
- parent.attachFake(this, CdmaCall.State.DIALING);
- }
- }
- }
-
- /** This is a Call waiting call*/
- CdmaConnection(Context context, CdmaCallWaitingNotification cw, CdmaCallTracker ct,
- CdmaCall parent) {
- createWakeLock(context);
- acquireWakeLock();
-
- owner = ct;
- h = new MyHandler(owner.getLooper());
- address = cw.number;
- numberPresentation = cw.numberPresentation;
- cnapName = cw.name;
- cnapNamePresentation = cw.namePresentation;
- index = -1;
- isIncoming = true;
- createTime = System.currentTimeMillis();
- connectTime = 0;
- this.parent = parent;
- parent.attachFake(this, CdmaCall.State.WAITING);
- }
-
- public void dispose() {
- }
-
- static boolean
- equalsHandlesNulls (Object a, Object b) {
- return (a == null) ? (b == null) : a.equals (b);
- }
-
- /*package*/ boolean
- compareTo(DriverCall c) {
- // On mobile originated (MO) calls, the phone number may have changed
- // due to a SIM Toolkit call control modification.
- //
- // We assume we know when MO calls are created (since we created them)
- // and therefore don't need to compare the phone number anyway.
- if (! (isIncoming || c.isMT)) return true;
-
- // ... but we can compare phone numbers on MT calls, and we have
- // no control over when they begin, so we might as well
-
- String cAddress = PhoneNumberUtils.stringFromStringAndTOA(c.number, c.TOA);
- return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
- }
-
-
- public String getOrigDialString(){
- return dialString;
- }
-
- public String getAddress() {
- return address;
- }
-
- public String getCnapName() {
- return cnapName;
- }
-
- public int getCnapNamePresentation() {
- return cnapNamePresentation;
- }
-
- public CdmaCall getCall() {
- return parent;
- }
-
- public long getCreateTime() {
- return createTime;
- }
-
- public long getConnectTime() {
- return connectTime;
- }
-
- public long getDisconnectTime() {
- return disconnectTime;
- }
-
- public long getDurationMillis() {
- if (connectTimeReal == 0) {
- return 0;
- } else if (duration == 0) {
- return SystemClock.elapsedRealtime() - connectTimeReal;
- } else {
- return duration;
- }
- }
-
- public long getHoldDurationMillis() {
- if (getState() != CdmaCall.State.HOLDING) {
- // If not holding, return 0
- return 0;
- } else {
- return SystemClock.elapsedRealtime() - holdingStartTime;
- }
- }
-
- public DisconnectCause getDisconnectCause() {
- return cause;
- }
-
- public boolean isIncoming() {
- return isIncoming;
- }
-
- public CdmaCall.State getState() {
- if (disconnected) {
- return CdmaCall.State.DISCONNECTED;
- } else {
- return super.getState();
- }
- }
-
- public void hangup() throws CallStateException {
- if (!disconnected) {
- owner.hangup(this);
- } else {
- throw new CallStateException ("disconnected");
- }
- }
-
- public void separate() throws CallStateException {
- if (!disconnected) {
- owner.separate(this);
- } else {
- throw new CallStateException ("disconnected");
- }
- }
-
- public PostDialState getPostDialState() {
- return postDialState;
- }
-
- public void proceedAfterWaitChar() {
- if (postDialState != PostDialState.WAIT) {
- Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
- + "getPostDialState() to be WAIT but was " + postDialState);
- return;
- }
-
- setPostDialState(PostDialState.STARTED);
-
- processNextPostDialChar();
- }
-
- public void proceedAfterWildChar(String str) {
- if (postDialState != PostDialState.WILD) {
- Log.w(LOG_TAG, "CdmaConnection.proceedAfterWaitChar(): Expected "
- + "getPostDialState() to be WILD but was " + postDialState);
- return;
- }
-
- setPostDialState(PostDialState.STARTED);
-
- if (false) {
- boolean playedTone = false;
- int len = (str != null ? str.length() : 0);
-
- for (int i=0; i<len; i++) {
- char c = str.charAt(i);
- Message msg = null;
-
- if (i == len-1) {
- msg = h.obtainMessage(EVENT_DTMF_DONE);
- }
-
- if (PhoneNumberUtils.is12Key(c)) {
- owner.cm.sendDtmf(c, msg);
- playedTone = true;
- }
- }
-
- if (!playedTone) {
- processNextPostDialChar();
- }
- } else {
- // make a new postDialString, with the wild char replacement string
- // at the beginning, followed by the remaining postDialString.
-
- StringBuilder buf = new StringBuilder(str);
- buf.append(postDialString.substring(nextPostDialChar));
- postDialString = buf.toString();
- nextPostDialChar = 0;
- if (Phone.DEBUG_PHONE) {
- log("proceedAfterWildChar: new postDialString is " +
- postDialString);
- }
-
- processNextPostDialChar();
- }
- }
-
- public void cancelPostDial() {
- setPostDialState(PostDialState.CANCELLED);
- }
-
- /**
- * Called when this Connection is being hung up locally (eg, user pressed "end")
- * Note that at this point, the hangup request has been dispatched to the radio
- * but no response has yet been received so update() has not yet been called
- */
- void
- onHangupLocal() {
- cause = DisconnectCause.LOCAL;
- }
-
- DisconnectCause
- disconnectCauseFromCode(int causeCode) {
- /**
- * See 22.001 Annex F.4 for mapping of cause codes
- * to local tones
- */
-
- switch (causeCode) {
- case CallFailCause.USER_BUSY:
- return DisconnectCause.BUSY;
- case CallFailCause.NO_CIRCUIT_AVAIL:
- return DisconnectCause.CONGESTION;
- case CallFailCause.ACM_LIMIT_EXCEEDED:
- return DisconnectCause.LIMIT_EXCEEDED;
- case CallFailCause.CALL_BARRED:
- return DisconnectCause.CALL_BARRED;
- case CallFailCause.FDN_BLOCKED:
- return DisconnectCause.FDN_BLOCKED;
- case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE:
- return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE;
- case CallFailCause.CDMA_DROP:
- return DisconnectCause.CDMA_DROP;
- case CallFailCause.CDMA_INTERCEPT:
- return DisconnectCause.CDMA_INTERCEPT;
- case CallFailCause.CDMA_REORDER:
- return DisconnectCause.CDMA_REORDER;
- case CallFailCause.CDMA_SO_REJECT:
- return DisconnectCause.CDMA_SO_REJECT;
- case CallFailCause.CDMA_RETRY_ORDER:
- return DisconnectCause.CDMA_RETRY_ORDER;
- case CallFailCause.CDMA_ACCESS_FAILURE:
- return DisconnectCause.CDMA_ACCESS_FAILURE;
- case CallFailCause.CDMA_PREEMPTED:
- return DisconnectCause.CDMA_PREEMPTED;
- case CallFailCause.CDMA_NOT_EMERGENCY:
- return DisconnectCause.CDMA_NOT_EMERGENCY;
- case CallFailCause.CDMA_ACCESS_BLOCKED:
- return DisconnectCause.CDMA_ACCESS_BLOCKED;
- case CallFailCause.ERROR_UNSPECIFIED:
- case CallFailCause.NORMAL_CLEARING:
- default:
- CDMAPhone phone = owner.phone;
- int serviceState = phone.getServiceState().getState();
- if (serviceState == ServiceState.STATE_POWER_OFF) {
- return DisconnectCause.POWER_OFF;
- } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
- || serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
- return DisconnectCause.OUT_OF_SERVICE;
- } else if (phone.mCdmaSubscriptionSource ==
- CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM
- && phone.getIccCard().getState() != IccCard.State.READY) {
- return DisconnectCause.ICC_ERROR;
- } else if (causeCode==CallFailCause.NORMAL_CLEARING) {
- return DisconnectCause.NORMAL;
- } else {
- return DisconnectCause.ERROR_UNSPECIFIED;
- }
- }
- }
-
- /*package*/ void
- onRemoteDisconnect(int causeCode) {
- onDisconnect(disconnectCauseFromCode(causeCode));
- }
-
- /** Called when the radio indicates the connection has been disconnected */
- /*package*/ void
- onDisconnect(DisconnectCause cause) {
- this.cause = cause;
-
- if (!disconnected) {
- doDisconnect();
- if (false) Log.d(LOG_TAG,
- "[CDMAConn] onDisconnect: cause=" + cause);
-
- owner.phone.notifyDisconnect(this);
-
- if (parent != null) {
- parent.connectionDisconnected(this);
- }
- }
- releaseWakeLock();
- }
-
- /** Called when the call waiting connection has been hung up */
- /*package*/ void
- onLocalDisconnect() {
- if (!disconnected) {
- doDisconnect();
- if (false) Log.d(LOG_TAG,
- "[CDMAConn] onLoalDisconnect" );
-
- if (parent != null) {
- parent.detach(this);
- }
- }
- releaseWakeLock();
- }
-
- // Returns true if state has changed, false if nothing changed
- /*package*/ boolean
- update (DriverCall dc) {
- CdmaCall newParent;
- boolean changed = false;
- boolean wasConnectingInOrOut = isConnectingInOrOut();
- boolean wasHolding = (getState() == CdmaCall.State.HOLDING);
-
- newParent = parentFromDCState(dc.state);
-
- if (Phone.DEBUG_PHONE) log("parent= " +parent +", newParent= " + newParent);
-
- if (!equalsHandlesNulls(address, dc.number)) {
- if (Phone.DEBUG_PHONE) log("update: phone # changed!");
- address = dc.number;
- changed = true;
- }
-
- // A null cnapName should be the same as ""
- if (TextUtils.isEmpty(dc.name)) {
- if (!TextUtils.isEmpty(cnapName)) {
- changed = true;
- cnapName = "";
- }
- } else if (!dc.name.equals(cnapName)) {
- changed = true;
- cnapName = dc.name;
- }
-
- if (Phone.DEBUG_PHONE) log("--dssds----"+cnapName);
- cnapNamePresentation = dc.namePresentation;
- numberPresentation = dc.numberPresentation;
-
- if (newParent != parent) {
- if (parent != null) {
- parent.detach(this);
- }
- newParent.attach(this, dc);
- parent = newParent;
- changed = true;
- } else {
- boolean parentStateChange;
- parentStateChange = parent.update (this, dc);
- changed = changed || parentStateChange;
- }
-
- /** Some state-transition events */
-
- if (Phone.DEBUG_PHONE) log(
- "Update, wasConnectingInOrOut=" + wasConnectingInOrOut +
- ", wasHolding=" + wasHolding +
- ", isConnectingInOrOut=" + isConnectingInOrOut() +
- ", changed=" + changed);
-
-
- if (wasConnectingInOrOut && !isConnectingInOrOut()) {
- onConnectedInOrOut();
- }
-
- if (changed && !wasHolding && (getState() == CdmaCall.State.HOLDING)) {
- // We've transitioned into HOLDING
- onStartedHolding();
- }
-
- return changed;
- }
-
- /**
- * Called when this Connection is in the foregroundCall
- * when a dial is initiated.
- * We know we're ACTIVE, and we know we're going to end up
- * HOLDING in the backgroundCall
- */
- void
- fakeHoldBeforeDial() {
- if (parent != null) {
- parent.detach(this);
- }
-
- parent = owner.backgroundCall;
- parent.attachFake(this, CdmaCall.State.HOLDING);
-
- onStartedHolding();
- }
-
- /*package*/ int
- getCDMAIndex() throws CallStateException {
- if (index >= 0) {
- return index + 1;
- } else {
- throw new CallStateException ("CDMA connection index not assigned");
- }
- }
-
- /**
- * An incoming or outgoing call has connected
- */
- void
- onConnectedInOrOut() {
- connectTime = System.currentTimeMillis();
- connectTimeReal = SystemClock.elapsedRealtime();
- duration = 0;
-
- // bug #678474: incoming call interpreted as missed call, even though
- // it sounds like the user has picked up the call.
- if (Phone.DEBUG_PHONE) {
- log("onConnectedInOrOut: connectTime=" + connectTime);
- }
-
- if (!isIncoming) {
- // outgoing calls only
- processNextPostDialChar();
- } else {
- // Only release wake lock for incoming calls, for outgoing calls the wake lock
- // will be released after any pause-dial is completed
- releaseWakeLock();
- }
- }
-
- private void
- doDisconnect() {
- index = -1;
- disconnectTime = System.currentTimeMillis();
- duration = SystemClock.elapsedRealtime() - connectTimeReal;
- disconnected = true;
- }
-
- private void
- onStartedHolding() {
- holdingStartTime = SystemClock.elapsedRealtime();
- }
- /**
- * Performs the appropriate action for a post-dial char, but does not
- * notify application. returns false if the character is invalid and
- * should be ignored
- */
- private boolean
- processPostDialChar(char c) {
- if (PhoneNumberUtils.is12Key(c)) {
- owner.cm.sendDtmf(c, h.obtainMessage(EVENT_DTMF_DONE));
- } else if (c == PhoneNumberUtils.PAUSE) {
- setPostDialState(PostDialState.PAUSE);
-
- // Upon occurrences of the separator, the UE shall
- // pause again for 2 seconds before sending any
- // further DTMF digits.
- h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
- PAUSE_DELAY_MILLIS);
- } else if (c == PhoneNumberUtils.WAIT) {
- setPostDialState(PostDialState.WAIT);
- } else if (c == PhoneNumberUtils.WILD) {
- setPostDialState(PostDialState.WILD);
- } else {
- return false;
- }
-
- return true;
- }
-
- public String getRemainingPostDialString() {
- if (postDialState == PostDialState.CANCELLED
- || postDialState == PostDialState.COMPLETE
- || postDialString == null
- || postDialString.length() <= nextPostDialChar) {
- return "";
- }
-
- String subStr = postDialString.substring(nextPostDialChar);
- if (subStr != null) {
- int wIndex = subStr.indexOf(PhoneNumberUtils.WAIT);
- int pIndex = subStr.indexOf(PhoneNumberUtils.PAUSE);
-
- if (wIndex > 0 && (wIndex < pIndex || pIndex <= 0)) {
- subStr = subStr.substring(0, wIndex);
- } else if (pIndex > 0) {
- subStr = subStr.substring(0, pIndex);
- }
- }
- return subStr;
- }
-
- public void updateParent(CdmaCall oldParent, CdmaCall newParent){
- if (newParent != oldParent) {
- if (oldParent != null) {
- oldParent.detach(this);
- }
- newParent.attachFake(this, CdmaCall.State.ACTIVE);
- parent = newParent;
- }
- }
-
- @Override
- protected void finalize()
- {
- /**
- * It is understood that This finializer is not guaranteed
- * to be called and the release lock call is here just in
- * case there is some path that doesn't call onDisconnect
- * and or onConnectedInOrOut.
- */
- if (mPartialWakeLock.isHeld()) {
- Log.e(LOG_TAG, "[CdmaConn] UNEXPECTED; mPartialWakeLock is held when finalizing.");
- }
- releaseWakeLock();
- }
-
- void processNextPostDialChar() {
- char c = 0;
- Registrant postDialHandler;
-
- if (postDialState == PostDialState.CANCELLED) {
- releaseWakeLock();
- //Log.v("CDMA", "##### processNextPostDialChar: postDialState == CANCELLED, bail");
- return;
- }
-
- if (postDialString == null ||
- postDialString.length() <= nextPostDialChar) {
- setPostDialState(PostDialState.COMPLETE);
-
- // We were holding a wake lock until pause-dial was complete, so give it up now
- releaseWakeLock();
-
- // notifyMessage.arg1 is 0 on complete
- c = 0;
- } else {
- boolean isValid;
-
- setPostDialState(PostDialState.STARTED);
-
- c = postDialString.charAt(nextPostDialChar++);
-
- isValid = processPostDialChar(c);
-
- if (!isValid) {
- // Will call processNextPostDialChar
- h.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget();
- // Don't notify application
- Log.e("CDMA", "processNextPostDialChar: c=" + c + " isn't valid!");
- return;
- }
- }
-
- postDialHandler = owner.phone.mPostDialHandler;
-
- Message notifyMessage;
-
- if (postDialHandler != null &&
- (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
- // The AsyncResult.result is the Connection object
- PostDialState state = postDialState;
- AsyncResult ar = AsyncResult.forMessage(notifyMessage);
- ar.result = this;
- ar.userObj = state;
-
- // arg1 is the character that was/is being processed
- notifyMessage.arg1 = c;
-
- notifyMessage.sendToTarget();
- }
- }
-
-
- /** "connecting" means "has never been ACTIVE" for both incoming
- * and outgoing calls
- */
- private boolean
- isConnectingInOrOut() {
- return parent == null || parent == owner.ringingCall
- || parent.state == CdmaCall.State.DIALING
- || parent.state == CdmaCall.State.ALERTING;
- }
-
- private CdmaCall
- parentFromDCState (DriverCall.State state) {
- switch (state) {
- case ACTIVE:
- case DIALING:
- case ALERTING:
- return owner.foregroundCall;
- //break;
-
- case HOLDING:
- return owner.backgroundCall;
- //break;
-
- case INCOMING:
- case WAITING:
- return owner.ringingCall;
- //break;
-
- default:
- throw new RuntimeException("illegal call state: " + state);
- }
- }
-
- /**
- * Set post dial state and acquire wake lock while switching to "started" or "wait"
- * state, the wake lock will be released if state switches out of "started" or "wait"
- * state or after WAKE_LOCK_TIMEOUT_MILLIS.
- * @param s new PostDialState
- */
- private void setPostDialState(PostDialState s) {
- if (s == PostDialState.STARTED ||
- s == PostDialState.PAUSE) {
- synchronized (mPartialWakeLock) {
- if (mPartialWakeLock.isHeld()) {
- h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
- } else {
- acquireWakeLock();
- }
- Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
- h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
- }
- } else {
- h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
- releaseWakeLock();
- }
- postDialState = s;
- }
-
- private void createWakeLock(Context context) {
- PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
- }
-
- private void acquireWakeLock() {
- log("acquireWakeLock");
- mPartialWakeLock.acquire();
- }
-
- private void releaseWakeLock() {
- synchronized (mPartialWakeLock) {
- if (mPartialWakeLock.isHeld()) {
- log("releaseWakeLock");
- mPartialWakeLock.release();
- }
- }
- }
-
- private static boolean isPause(char c) {
- return c == PhoneNumberUtils.PAUSE;
- }
-
- private static boolean isWait(char c) {
- return c == PhoneNumberUtils.WAIT;
- }
-
- // This function is to find the next PAUSE character index if
- // multiple pauses in a row. Otherwise it finds the next non PAUSE or
- // non WAIT character index.
- private static int
- findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) {
- boolean wMatched = isWait(phoneNumber.charAt(currIndex));
- int index = currIndex + 1;
- int length = phoneNumber.length();
- while (index < length) {
- char cNext = phoneNumber.charAt(index);
- // if there is any W inside P/W sequence,mark it
- if (isWait(cNext)) {
- wMatched = true;
- }
- // if any characters other than P/W chars after P/W sequence
- // we break out the loop and append the correct
- if (!isWait(cNext) && !isPause(cNext)) {
- break;
- }
- index++;
- }
-
- // It means the PAUSE character(s) is in the middle of dial string
- // and it needs to be handled one by one.
- if ((index < length) && (index > (currIndex + 1)) &&
- ((wMatched == false) && isPause(phoneNumber.charAt(currIndex)))) {
- return (currIndex + 1);
- }
- return index;
- }
-
- // This function returns either PAUSE or WAIT character to append.
- // It is based on the next non PAUSE/WAIT character in the phoneNumber and the
- // index for the current PAUSE/WAIT character
- private static char
- findPOrWCharToAppend(String phoneNumber, int currPwIndex, int nextNonPwCharIndex) {
- char c = phoneNumber.charAt(currPwIndex);
- char ret;
-
- // Append the PW char
- ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
-
- // If the nextNonPwCharIndex is greater than currPwIndex + 1,
- // it means the PW sequence contains not only P characters.
- // Since for the sequence that only contains P character,
- // the P character is handled one by one, the nextNonPwCharIndex
- // equals to currPwIndex + 1.
- // In this case, skip P, append W.
- if (nextNonPwCharIndex > (currPwIndex + 1)) {
- ret = PhoneNumberUtils.WAIT;
- }
- return ret;
- }
-
- /**
- * format original dial string
- * 1) convert international dialing prefix "+" to
- * string specified per region
- *
- * 2) handle corner cases for PAUSE/WAIT dialing:
- *
- * If PAUSE/WAIT sequence at the end, ignore them.
- *
- * If consecutive PAUSE/WAIT sequence in the middle of the string,
- * and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT.
- */
- public static String formatDialString(String phoneNumber) {
- /**
- * TODO(cleanup): This function should move to PhoneNumberUtils, and
- * tests should be added.
- */
-
- if (phoneNumber == null) {
- return null;
- }
- int length = phoneNumber.length();
- StringBuilder ret = new StringBuilder();
- char c;
- int currIndex = 0;
-
- while (currIndex < length) {
- c = phoneNumber.charAt(currIndex);
- if (isPause(c) || isWait(c)) {
- if (currIndex < length - 1) {
- // if PW not at the end
- int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex);
- // If there is non PW char following PW sequence
- if (nextIndex < length) {
- char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
- ret.append(pC);
- // If PW char sequence has more than 2 PW characters,
- // skip to the last PW character since the sequence already be
- // converted to WAIT character
- if (nextIndex > (currIndex + 1)) {
- currIndex = nextIndex - 1;
- }
- } else if (nextIndex == length) {
- // It means PW characters at the end, ignore
- currIndex = length - 1;
- }
- }
- } else {
- ret.append(c);
- }
- currIndex++;
- }
- return PhoneNumberUtils.cdmaCheckAndProcessPlusCode(ret.toString());
- }
-
- private void log(String msg) {
- Log.d(LOG_TAG, "[CDMAConn] " + msg);
- }
-
- @Override
- public int getNumberPresentation() {
- return numberPresentation;
- }
-
- @Override
- public UUSInfo getUUSInfo() {
- // UUS information not supported in CDMA
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
deleted file mode 100644
index 4ef05ea..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.cdma;
-
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RetryManager;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * {@hide}
- */
-public class CdmaDataConnection extends DataConnection {
-
- private static final String LOG_TAG = "CDMA";
-
- // ***** Constructor
- private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm,
- DataConnectionTracker dct) {
- super(phone, name, id, rm, dct);
- }
-
- /**
- * Create the connection object
- *
- * @param phone the Phone
- * @param id the connection id
- * @param rm the RetryManager
- * @return CdmaDataConnection that was created.
- */
- static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm,
- DataConnectionTracker dct) {
- synchronized (mCountLock) {
- mCount += 1;
- }
- CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDC-" + mCount,
- id, rm, dct);
- cdmaDc.start();
- if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
- return cdmaDc;
- }
-
- /**
- * Begin setting up a data connection, calls setupDataCall
- * and the ConnectionParams will be returned with the
- * EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj.
- *
- * @param cp is the connection parameters
- */
- @Override
- protected void onConnect(ConnectionParams cp) {
- if (DBG) log("CdmaDataConnection Connecting...");
-
- mApn = cp.apn;
- createTime = -1;
- lastFailTime = -1;
- lastFailCause = FailCause.NONE;
- int dataProfile;
- if ((cp.apn != null) && (cp.apn.types.length > 0) && (cp.apn.types[0] != null) &&
- (cp.apn.types[0].equals(Phone.APN_TYPE_DUN))) {
- if (DBG) log("CdmaDataConnection using DUN");
- dataProfile = RILConstants.DATA_PROFILE_TETHERED;
- } else {
- dataProfile = RILConstants.DATA_PROFILE_DEFAULT;
- }
-
- // msg.obj will be returned in AsyncResult.userObj;
- Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
- msg.obj = cp;
- phone.mCM.setupDataCall(
- Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_CDMA)),
- Integer.toString(dataProfile),
- null, null, null,
- Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP),
- RILConstants.SETUP_DATA_PROTOCOL_IP, msg);
- }
-
- @Override
- public String toString() {
- return "State=" + getCurrentState().getName() + " create=" + createTime + " lastFail="
- + lastFailTime + " lastFasilCause=" + lastFailCause;
- }
-
- @Override
- protected boolean isDnsOk(String[] domainNameServers) {
- if (NULL_IP.equals(domainNameServers[0])
- && NULL_IP.equals(domainNameServers[1])
- && !phone.isDnsCheckDisabled()) {
- return false;
- } else {
- return true;
- }
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[" + getName() + "] " + s);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("CdmaDataConnection extends:");
- super.dump(fd, pw, args);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
deleted file mode 100644
index a691eae..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ /dev/null
@@ -1,1040 +0,0 @@
-/*
- * 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.cdma;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.net.TrafficStats;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.cdma.CdmaCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-
-import com.android.internal.telephony.ApnSetting;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataCallState;
-import com.android.internal.telephony.DataConnection.FailCause;
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnectionAc;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.telephony.RILConstants;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public final class CdmaDataConnectionTracker extends DataConnectionTracker {
- protected final String LOG_TAG = "CDMA";
-
- private CDMAPhone mCdmaPhone;
- private CdmaSubscriptionSourceManager mCdmaSSM;
-
- /** The DataConnection being setup */
- private CdmaDataConnection mPendingDataConnection;
-
- private boolean mPendingRestartRadio = false;
- private static final int TIME_DELAYED_TO_RESTART_RADIO =
- SystemProperties.getInt("ro.cdma.timetoradiorestart", 60000);
-
- /**
- * Pool size of CdmaDataConnection objects.
- */
- private static final int DATA_CONNECTION_POOL_SIZE = 1;
-
- private static final String INTENT_RECONNECT_ALARM =
- "com.android.internal.telephony.cdma-reconnect";
-
- private static final String INTENT_DATA_STALL_ALARM =
- "com.android.internal.telephony.cdma-data-stall";
-
-
- /**
- * Constants for the data connection activity:
- * physical link down/up
- */
- private static final int DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE = 0;
- private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DOWN = 1;
- private static final int DATA_CONNECTION_ACTIVE_PH_LINK_UP = 2;
-
- private static final String[] mSupportedApnTypes = {
- Phone.APN_TYPE_DEFAULT,
- Phone.APN_TYPE_MMS,
- Phone.APN_TYPE_DUN,
- Phone.APN_TYPE_HIPRI };
-
- private static final String[] mDefaultApnTypes = {
- Phone.APN_TYPE_DEFAULT,
- Phone.APN_TYPE_MMS,
- Phone.APN_TYPE_HIPRI };
-
- private String[] mDunApnTypes = {
- Phone.APN_TYPE_DUN };
-
- private static final int mDefaultApnId = DataConnectionTracker.APN_DEFAULT_ID;
-
- /* Constructor */
-
- CdmaDataConnectionTracker(CDMAPhone p) {
- super(p);
- mCdmaPhone = p;
-
- p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
- p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- p.mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
- p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
- p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
- p.mSST.registerForDataConnectionAttached(this, EVENT_TRY_SETUP_DATA, null);
- p.mSST.registerForDataConnectionDetached(this, EVENT_CDMA_DATA_DETACHED, null);
- p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
- p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
- p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null);
- mCdmaSSM = CdmaSubscriptionSourceManager.getInstance (p.getContext(), p.mCM, this,
- EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
-
- mDataConnectionTracker = this;
-
- createAllDataConnectionList();
- broadcastMessenger();
-
- Context c = mCdmaPhone.getContext();
- String[] t = c.getResources().getStringArray(
- com.android.internal.R.array.config_cdma_dun_supported_types);
- if (t != null && t.length > 0) {
- ArrayList<String> temp = new ArrayList<String>();
- for(int i=0; i< t.length; i++) {
- if (!Phone.APN_TYPE_DUN.equalsIgnoreCase(t[i])) {
- temp.add(t[i]);
- }
- }
- temp.add(0, Phone.APN_TYPE_DUN);
- mDunApnTypes = temp.toArray(t);
- }
-
- }
-
- @Override
- public void dispose() {
- cleanUpConnection(false, null, false);
-
- super.dispose();
-
- // Unregister from all events
- mPhone.mCM.unregisterForAvailable(this);
- mPhone.mCM.unregisterForOffOrNotAvailable(this);
- mCdmaPhone.mIccRecords.unregisterForRecordsLoaded(this);
- mPhone.mCM.unregisterForDataNetworkStateChanged(this);
- mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
- mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
- mCdmaPhone.mSST.unregisterForDataConnectionAttached(this);
- mCdmaPhone.mSST.unregisterForDataConnectionDetached(this);
- mCdmaPhone.mSST.unregisterForRoamingOn(this);
- mCdmaPhone.mSST.unregisterForRoamingOff(this);
- mCdmaSSM.dispose(this);
- mPhone.mCM.unregisterForCdmaOtaProvision(this);
-
- destroyAllDataConnectionList();
- }
-
- @Override
- protected void finalize() {
- if(DBG) log("CdmaDataConnectionTracker finalized");
- }
-
- @Override
- protected String getActionIntentReconnectAlarm() {
- return INTENT_RECONNECT_ALARM;
- }
-
- @Override
- protected String getActionIntentDataStallAlarm() {
- return INTENT_DATA_STALL_ALARM;
- }
-
- @Override
- protected void restartDataStallAlarm() {}
-
- @Override
- protected void setState(State s) {
- if (DBG) log ("setState: " + s);
- if (mState != s) {
- EventLog.writeEvent(EventLogTags.CDMA_DATA_STATE_CHANGE,
- mState.toString(), s.toString());
- mState = s;
- }
- }
-
- @Override
- public synchronized State getState(String apnType) {
- return mState;
- }
-
- @Override
- protected boolean isApnTypeAvailable(String type) {
- for (String s : mSupportedApnTypes) {
- if (TextUtils.equals(type, s)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- protected boolean isDataAllowed() {
- final boolean internalDataEnabled;
- synchronized (mDataEnabledLock) {
- internalDataEnabled = mInternalDataEnabled;
- }
-
- int psState = mCdmaPhone.mSST.getCurrentDataConnectionState();
- boolean roaming = (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled());
- boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
- boolean subscriptionFromNv = (mCdmaSSM.getCdmaSubscriptionSource()
- == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV);
-
- boolean allowed =
- (psState == ServiceState.STATE_IN_SERVICE ||
- mAutoAttachOnCreation) &&
- (subscriptionFromNv ||
- mCdmaPhone.mIccRecords.getRecordsLoaded()) &&
- (mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
- mPhone.getState() == Phone.State.IDLE) &&
- !roaming &&
- internalDataEnabled &&
- desiredPowerState &&
- !mPendingRestartRadio &&
- ((mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) ||
- !mCdmaPhone.needsOtaServiceProvisioning());
- if (!allowed && DBG) {
- String reason = "";
- if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
- reason += " - psState= " + psState;
- }
- if (!subscriptionFromNv &&
- !mCdmaPhone.mIccRecords.getRecordsLoaded()) {
- reason += " - RUIM not loaded";
- }
- if (!(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
- mPhone.getState() == Phone.State.IDLE)) {
- reason += " - concurrentVoiceAndData not allowed and state= " + mPhone.getState();
- }
- if (roaming) reason += " - Roaming";
- if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
- if (!desiredPowerState) reason += " - desiredPowerState= false";
- if (mPendingRestartRadio) reason += " - mPendingRestartRadio= true";
- if (mCdmaPhone.needsOtaServiceProvisioning()) reason += " - needs Provisioning";
- log("Data not allowed due to" + reason);
- }
- return allowed;
- }
-
- @Override
- protected boolean isDataPossible(String apnType) {
- boolean possible = isDataAllowed() && !(getAnyDataEnabled() &&
- (mState == State.FAILED || mState == State.IDLE));
- if (!possible && DBG && isDataAllowed()) {
- log("Data not possible. No coverage: dataState = " + mState);
- }
- return possible;
- }
-
- private boolean trySetupData(String reason) {
- if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
-
- if (mPhone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- setState(State.CONNECTED);
- notifyDataConnection(reason);
- notifyOffApnsOfAvailability(reason);
-
- log("(fix?) We're on the simulator; assuming data is connected");
- return true;
- }
-
- int psState = mCdmaPhone.mSST.getCurrentDataConnectionState();
- boolean roaming = mPhone.getServiceState().getRoaming();
- boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
-
- if ((mState == State.IDLE || mState == State.SCANNING) &&
- isDataAllowed() && getAnyDataEnabled() && !isEmergency()) {
- boolean retValue = setupData(reason);
- notifyOffApnsOfAvailability(reason);
- return retValue;
- } else {
- notifyOffApnsOfAvailability(reason);
- return false;
- }
- }
-
- /**
- * Cleanup the CDMA data connection (only one is supported)
- *
- * @param tearDown true if the underlying DataConnection should be disconnected.
- * @param reason for the clean up.
- */
- private void cleanUpConnection(boolean tearDown, String reason, boolean doAll) {
- if (DBG) log("cleanUpConnection: reason: " + reason);
-
- // Clear the reconnect alarm, if set.
- if (mReconnectIntent != null) {
- AlarmManager am =
- (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
- am.cancel(mReconnectIntent);
- mReconnectIntent = null;
- }
-
- setState(State.DISCONNECTING);
- notifyOffApnsOfAvailability(reason);
-
- boolean notificationDeferred = false;
- for (DataConnection conn : mDataConnections.values()) {
- if(conn != null) {
- DataConnectionAc dcac =
- mDataConnectionAsyncChannels.get(conn.getDataConnectionId());
- if (tearDown) {
- if (doAll) {
- if (DBG) log("cleanUpConnection: teardown, conn.tearDownAll");
- conn.tearDownAll(reason, obtainMessage(EVENT_DISCONNECT_DONE,
- conn.getDataConnectionId(), 0, reason));
- } else {
- if (DBG) log("cleanUpConnection: teardown, conn.tearDown");
- conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE,
- conn.getDataConnectionId(), 0, reason));
- }
- notificationDeferred = true;
- } else {
- if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
- if (dcac != null) {
- dcac.resetSync();
- }
- notificationDeferred = false;
- }
- }
- }
-
- stopNetStatPoll();
-
- if (!notificationDeferred) {
- if (DBG) log("cleanupConnection: !notificationDeferred");
- gotoIdleAndNotifyDataConnection(reason);
- }
- }
-
- private CdmaDataConnection findFreeDataConnection() {
- for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
- if (dcac.isInactiveSync()) {
- log("found free GsmDataConnection");
- return (CdmaDataConnection) dcac.dataConnection;
- }
- }
- log("NO free CdmaDataConnection");
- return null;
- }
-
- private boolean setupData(String reason) {
- CdmaDataConnection conn = findFreeDataConnection();
-
- if (conn == null) {
- if (DBG) log("setupData: No free CdmaDataConnection found!");
- return false;
- }
-
- /** TODO: We probably want the connection being setup to a parameter passed around */
- mPendingDataConnection = conn;
- String[] types;
- int apnId;
- if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) {
- types = mDunApnTypes;
- apnId = DataConnectionTracker.APN_DUN_ID;
- } else {
- types = mDefaultApnTypes;
- apnId = mDefaultApnId;
- }
- mActiveApn = new ApnSetting(apnId, "", "", "", "", "", "", "", "", "",
- "", 0, types, "IP", "IP", true, 0);
- if (DBG) log("call conn.bringUp mActiveApn=" + mActiveApn);
-
- Message msg = obtainMessage();
- msg.what = EVENT_DATA_SETUP_COMPLETE;
- msg.obj = reason;
- conn.bringUp(msg, mActiveApn);
-
- setState(State.INITING);
- notifyDataConnection(reason);
- return true;
- }
-
- private void notifyDefaultData(String reason) {
- setState(State.CONNECTED);
- notifyDataConnection(reason);
- startNetStatPoll();
- mDataConnections.get(0).resetRetryCount();
- }
-
- private void resetPollStats() {
- mTxPkts = -1;
- mRxPkts = -1;
- mSentSinceLastRecv = 0;
- mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
- mNoRecvPollCount = 0;
- }
-
- @Override
- protected void startNetStatPoll() {
- if (mState == State.CONNECTED && mNetStatPollEnabled == false) {
- log("[DataConnection] Start poll NetStat");
- resetPollStats();
- mNetStatPollEnabled = true;
- mPollNetStat.run();
- }
- }
-
- @Override
- protected void stopNetStatPoll() {
- mNetStatPollEnabled = false;
- removeCallbacks(mPollNetStat);
- log("[DataConnection] Stop poll NetStat");
- }
-
- @Override
- protected void restartRadio() {
- if (DBG) log("Cleanup connection and wait " +
- (TIME_DELAYED_TO_RESTART_RADIO / 1000) + "s to restart radio");
- cleanUpAllConnections(null);
- sendEmptyMessageDelayed(EVENT_RESTART_RADIO, TIME_DELAYED_TO_RESTART_RADIO);
- mPendingRestartRadio = true;
- }
-
- private Runnable mPollNetStat = new Runnable() {
-
- public void run() {
- long sent, received;
- long preTxPkts = -1, preRxPkts = -1;
-
- Activity newActivity;
-
- preTxPkts = mTxPkts;
- preRxPkts = mRxPkts;
-
- mTxPkts = TrafficStats.getMobileTxPackets();
- mRxPkts = TrafficStats.getMobileRxPackets();
-
- //log("rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
-
- if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
- sent = mTxPkts - preTxPkts;
- received = mRxPkts - preRxPkts;
-
- if ( sent > 0 && received > 0 ) {
- mSentSinceLastRecv = 0;
- newActivity = Activity.DATAINANDOUT;
- } else if (sent > 0 && received == 0) {
- if (mPhone.getState() == Phone.State.IDLE) {
- mSentSinceLastRecv += sent;
- } else {
- mSentSinceLastRecv = 0;
- }
- newActivity = Activity.DATAOUT;
- } else if (sent == 0 && received > 0) {
- mSentSinceLastRecv = 0;
- newActivity = Activity.DATAIN;
- } else if (sent == 0 && received == 0) {
- newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE;
- } else {
- mSentSinceLastRecv = 0;
- newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE;
- }
-
- if (mActivity != newActivity && mIsScreenOn) {
- mActivity = newActivity;
- mPhone.notifyDataActivity();
- }
- }
-
- if (mSentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
- // Packets sent without ack exceeded threshold.
-
- if (mNoRecvPollCount == 0) {
- EventLog.writeEvent(
- EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED,
- mSentSinceLastRecv);
- }
-
- if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) {
- mNoRecvPollCount++;
- // Slow down the poll interval to let things happen
- mNetStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS;
- } else {
- if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) +
- " pkts since last received");
- // We've exceeded the threshold. Restart the radio.
- mNetStatPollEnabled = false;
- stopNetStatPoll();
- restartRadio();
- EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, NO_RECV_POLL_LIMIT);
- }
- } else {
- mNoRecvPollCount = 0;
- mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
- }
-
- if (mNetStatPollEnabled) {
- mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
- }
- }
- };
-
- /**
- * Returns true if the last fail cause is something that
- * seems like it deserves an error notification.
- * Transient errors are ignored
- */
- private boolean
- shouldPostNotification(FailCause cause) {
- return (cause != FailCause.UNKNOWN);
- }
-
- /**
- * Return true if data connection need to be setup after disconnected due to
- * reason.
- *
- * @param reason the reason why data is disconnected
- * @return true if try setup data connection is need for this reason
- */
- private boolean retryAfterDisconnected(String reason) {
- boolean retry = true;
-
- if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) {
- retry = false;
- }
- return retry;
- }
-
- private void reconnectAfterFail(FailCause lastFailCauseCode, String reason, int retryOverride) {
- if (mState == State.FAILED) {
- /**
- * For now With CDMA we never try to reconnect on
- * error and instead just continue to retry
- * at the last time until the state is changed.
- * TODO: Make this configurable?
- */
- int nextReconnectDelay = retryOverride;
- if (nextReconnectDelay < 0) {
- nextReconnectDelay = mDataConnections.get(0).getRetryTimer();
- mDataConnections.get(0).increaseRetryCount();
- }
- startAlarmForReconnect(nextReconnectDelay, reason);
-
- if (!shouldPostNotification(lastFailCauseCode)) {
- log("NOT Posting Data Connection Unavailable notification "
- + "-- likely transient error");
- } else {
- notifyNoData(lastFailCauseCode);
- }
- }
- }
-
- private void startAlarmForReconnect(int delay, String reason) {
-
- log("Data Connection activate failed. Scheduling next attempt for "
- + (delay / 1000) + "s");
-
- AlarmManager am =
- (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
- Intent intent = new Intent(INTENT_RECONNECT_ALARM);
- intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
- mReconnectIntent = PendingIntent.getBroadcast(
- mPhone.getContext(), 0, intent, 0);
- am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + delay, mReconnectIntent);
-
- }
-
- private void notifyNoData(FailCause lastFailCauseCode) {
- setState(State.FAILED);
- notifyOffApnsOfAvailability(null);
- }
-
- protected void gotoIdleAndNotifyDataConnection(String reason) {
- if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
- setState(State.IDLE);
- notifyDataConnection(reason);
- mActiveApn = null;
- }
-
- protected void onRecordsLoaded() {
- if (mState == State.FAILED) {
- cleanUpAllConnections(null);
- }
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
- }
-
- protected void onNVReady() {
- if (mState == State.FAILED) {
- cleanUpAllConnections(null);
- }
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected void onEnableNewApn() {
- // No mRequestedApnType check; only one connection is supported
- cleanUpConnection(true, Phone.REASON_APN_SWITCHED, false);
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected boolean onTrySetupData(String reason) {
- return trySetupData(reason);
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected void onRoamingOff() {
- if (mUserDataEnabled == false) return;
-
- if (getDataOnRoamingEnabled() == false) {
- notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
- trySetupData(Phone.REASON_ROAMING_OFF);
- } else {
- notifyDataConnection(Phone.REASON_ROAMING_OFF);
- }
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected void onRoamingOn() {
- if (mUserDataEnabled == false) return;
-
- if (getDataOnRoamingEnabled()) {
- trySetupData(Phone.REASON_ROAMING_ON);
- notifyDataConnection(Phone.REASON_ROAMING_ON);
- } else {
- if (DBG) log("Tear down data connection on roaming.");
- cleanUpAllConnections(null);
- notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
- }
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected void onRadioAvailable() {
- if (mPhone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- setState(State.CONNECTED);
- notifyDataConnection(null);
-
- log("We're on the simulator; assuming data is connected");
- }
-
- notifyOffApnsOfAvailability(null);
-
- if (mState != State.IDLE) {
- cleanUpAllConnections(null);
- }
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected void onRadioOffOrNotAvailable() {
- mDataConnections.get(0).resetRetryCount();
-
- if (mPhone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- log("We're on the simulator; assuming radio off is meaningless");
- } else {
- if (DBG) log("Radio is off and clean up all connection");
- cleanUpAllConnections(null);
- }
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected void onDataSetupComplete(AsyncResult ar) {
- String reason = null;
- if (ar.userObj instanceof String) {
- reason = (String) ar.userObj;
- }
-
- if (isDataSetupCompleteOk(ar)) {
- // Everything is setup
- notifyDefaultData(reason);
- } else {
- FailCause cause = (FailCause) (ar.result);
- if(DBG) log("Data Connection setup failed " + cause);
-
- // No try for permanent failure
- if (cause.isPermanentFail()) {
- notifyNoData(cause);
- return;
- }
-
- int retryOverride = -1;
- if (ar.exception instanceof DataConnection.CallSetupException) {
- retryOverride =
- ((DataConnection.CallSetupException)ar.exception).getRetryOverride();
- }
- if (retryOverride == RILConstants.MAX_INT) {
- if (DBG) log("No retry is suggested.");
- } else {
- startDelayedRetry(cause, reason, retryOverride);
- }
- }
- }
-
- /**
- * Called when EVENT_DISCONNECT_DONE is received.
- */
- @Override
- protected void onDisconnectDone(int connId, AsyncResult ar) {
- if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
- String reason = null;
- if (ar.userObj instanceof String) {
- reason = (String) ar.userObj;
- }
- setState(State.IDLE);
-
- // Since the pending request to turn off or restart radio will be processed here,
- // remove the pending event to restart radio from the message queue.
- if (mPendingRestartRadio) removeMessages(EVENT_RESTART_RADIO);
-
- // Process the pending request to turn off radio in ServiceStateTracker first.
- // If radio is turned off in ServiceStateTracker, ignore the pending event to restart radio.
- CdmaServiceStateTracker ssTracker = mCdmaPhone.mSST;
- if (ssTracker.processPendingRadioPowerOffAfterDataOff()) {
- mPendingRestartRadio = false;
- } else {
- onRestartRadio();
- }
-
- notifyDataConnection(reason);
- mActiveApn = null;
- if (retryAfterDisconnected(reason)) {
- // Wait a bit before trying, so we're not tying up RIL command channel.
- startAlarmForReconnect(APN_DELAY_MILLIS, reason);
- }
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected void onVoiceCallStarted() {
- if (mState == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) {
- stopNetStatPoll();
- notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
- notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_STARTED);
- }
- }
-
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
- @Override
- protected void onVoiceCallEnded() {
- if (mState == State.CONNECTED) {
- if (!mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) {
- startNetStatPoll();
- notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
- } else {
- // clean slate after call end.
- resetPollStats();
- }
- notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_ENDED);
- } else {
- mDataConnections.get(0).resetRetryCount();
- // in case data setup was attempted when we were on a voice call
- trySetupData(Phone.REASON_VOICE_CALL_ENDED);
- }
- }
-
- @Override
- protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
- // No apnId check; only one connection is supported
- cleanUpConnection(tearDown, reason, (apnId == APN_DUN_ID));
- }
-
- @Override
- protected void onCleanUpAllConnections(String cause) {
- // Only one CDMA connection is supported
- cleanUpConnection(true, cause, false);
- }
-
- private void createAllDataConnectionList() {
- CdmaDataConnection dataConn;
-
- String retryConfig = SystemProperties.get("ro.cdma.data_retry_config");
- for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
- RetryManager rm = new RetryManager();
- if (!rm.configure(retryConfig)) {
- if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple linear sequence.
- log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
- + DEFAULT_DATA_RETRY_CONFIG);
- rm.configure(20, 2000, 1000);
- }
- }
-
- int id = mUniqueIdGenerator.getAndIncrement();
- dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm, this);
- mDataConnections.put(id, dataConn);
- DataConnectionAc dcac = new DataConnectionAc(dataConn, LOG_TAG);
- int status = dcac.fullyConnectSync(mPhone.getContext(), this, dataConn.getHandler());
- if (status == AsyncChannel.STATUS_SUCCESSFUL) {
- log("Fully connected");
- mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac);
- } else {
- log("Could not connect to dcac.dataConnection=" + dcac.dataConnection +
- " status=" + status);
- }
-
- }
- }
-
- private void destroyAllDataConnectionList() {
- if(mDataConnections != null) {
- mDataConnections.clear();
- }
- }
-
- private void onCdmaDataDetached() {
- if (mState == State.CONNECTED) {
- startNetStatPoll();
- notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
- } else {
- if (mState == State.FAILED) {
- cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED, false);
- mDataConnections.get(0).resetRetryCount();
-
- CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
- EventLog.writeEvent(EventLogTags.CDMA_DATA_SETUP_FAILED,
- loc != null ? loc.getBaseStationId() : -1,
- TelephonyManager.getDefault().getNetworkType());
- }
- trySetupData(Phone.REASON_CDMA_DATA_DETACHED);
- }
- }
-
- private void onCdmaOtaProvision(AsyncResult ar) {
- if (ar.exception != null) {
- int [] otaPrivision = (int [])ar.result;
- if ((otaPrivision != null) && (otaPrivision.length > 1)) {
- switch (otaPrivision[0]) {
- case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
- case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
- mDataConnections.get(0).resetRetryCount();
- break;
- default:
- break;
- }
- }
- }
- }
-
- private void onRestartRadio() {
- if (mPendingRestartRadio) {
- log("************TURN OFF RADIO**************");
- mPhone.mCM.setRadioPower(false, null);
- /* Note: no need to call setRadioPower(true). Assuming the desired
- * radio power state is still ON (as tracked by ServiceStateTracker),
- * ServiceStateTracker will call setRadioPower when it receives the
- * RADIO_STATE_CHANGED notification for the power off. And if the
- * desired power state has changed in the interim, we don't want to
- * override it with an unconditional power on.
- */
- mPendingRestartRadio = false;
- }
- }
-
- private void writeEventLogCdmaDataDrop() {
- CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
- EventLog.writeEvent(EventLogTags.CDMA_DATA_DROP,
- loc != null ? loc.getBaseStationId() : -1,
- TelephonyManager.getDefault().getNetworkType());
- }
-
- protected void onDataStateChanged(AsyncResult ar) {
- ArrayList<DataCallState> dataCallStates = (ArrayList<DataCallState>)(ar.result);
-
- if (ar.exception != null) {
- // This is probably "radio not available" or something
- // of that sort. If so, the whole connection is going
- // to come down soon anyway
- return;
- }
-
- if (mState == State.CONNECTED) {
- boolean isActiveOrDormantConnectionPresent = false;
- int connectionState = DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE;
-
- // Check for an active or dormant connection element in
- // the DATA_CALL_LIST array
- for (int index = 0; index < dataCallStates.size(); index++) {
- connectionState = dataCallStates.get(index).active;
- if (connectionState != DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE) {
- isActiveOrDormantConnectionPresent = true;
- break;
- }
- }
-
- if (!isActiveOrDormantConnectionPresent) {
- // No active or dormant connection
- log("onDataStateChanged: No active connection"
- + "state is CONNECTED, disconnecting/cleanup");
- writeEventLogCdmaDataDrop();
- cleanUpConnection(true, null, false);
- return;
- }
-
- switch (connectionState) {
- case DATA_CONNECTION_ACTIVE_PH_LINK_UP:
- log("onDataStateChanged: active=LINK_ACTIVE && CONNECTED, ignore");
- mActivity = Activity.NONE;
- mPhone.notifyDataActivity();
- startNetStatPoll();
- break;
-
- case DATA_CONNECTION_ACTIVE_PH_LINK_DOWN:
- log("onDataStateChanged active=LINK_DOWN && CONNECTED, dormant");
- mActivity = Activity.DORMANT;
- mPhone.notifyDataActivity();
- stopNetStatPoll();
- break;
-
- default:
- log("onDataStateChanged: IGNORE unexpected DataCallState.active="
- + connectionState);
- }
- } else {
- // TODO: Do we need to do anything?
- log("onDataStateChanged: not connected, state=" + mState + " ignoring");
- }
- }
-
- private void startDelayedRetry(FailCause cause, String reason, int retryOverride) {
- notifyNoData(cause);
- reconnectAfterFail(cause, reason, retryOverride);
- }
-
- @Override
- public void handleMessage (Message msg) {
- if (DBG) log("CdmaDCT handleMessage msg=" + msg);
-
- if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
- log("Ignore CDMA msgs since CDMA phone is inactive");
- return;
- }
-
- switch (msg.what) {
- case EVENT_RECORDS_LOADED:
- onRecordsLoaded();
- break;
-
- case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
- if(mCdmaSSM.getCdmaSubscriptionSource() ==
- CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_NV) {
- onNVReady();
- }
- break;
-
- case EVENT_CDMA_DATA_DETACHED:
- onCdmaDataDetached();
- break;
-
- case EVENT_DATA_STATE_CHANGED:
- onDataStateChanged((AsyncResult) msg.obj);
- break;
-
- case EVENT_CDMA_OTA_PROVISION:
- onCdmaOtaProvision((AsyncResult) msg.obj);
- break;
-
- case EVENT_RESTART_RADIO:
- if (DBG) log("EVENT_RESTART_RADIO");
- onRestartRadio();
- break;
-
- default:
- // handle the message in the super class DataConnectionTracker
- super.handleMessage(msg);
- break;
- }
- }
-
- @Override
- public boolean isDisconnected() {
- return ((mState == State.IDLE) || (mState == State.FAILED));
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[CdmaDCT] " + s);
- }
-
- @Override
- protected void loge(String s) {
- Log.e(LOG_TAG, "[CdmaDCT] " + s);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("CdmaDataConnectionTracker extends:");
- super.dump(fd, pw, args);
- pw.println(" mCdmaPhone=" + mCdmaPhone);
- pw.println(" mCdmaSSM=" + mCdmaSSM);
- pw.println(" mPendingDataConnection=" + mPendingDataConnection);
- pw.println(" mPendingRestartRadio=" + mPendingRestartRadio);
- pw.println(" mSupportedApnTypes=" + mSupportedApnTypes);
- pw.println(" mDefaultApnTypes=" + mDefaultApnTypes);
- pw.println(" mDunApnTypes=" + mDunApnTypes);
- pw.println(" mDefaultApnId=" + mDefaultApnId);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
deleted file mode 100644
index ce6530a..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2009 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.cdma;
-import static com.android.internal.telephony.RILConstants.*;
-import android.os.Parcel;
-
-public final class CdmaInformationRecords {
- public Object record;
-
- /**
- * Record type identifier
- */
- public static final int RIL_CDMA_DISPLAY_INFO_REC = 0;
- public static final int RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC = 1;
- public static final int RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC = 2;
- public static final int RIL_CDMA_CONNECTED_NUMBER_INFO_REC = 3;
- public static final int RIL_CDMA_SIGNAL_INFO_REC = 4;
- public static final int RIL_CDMA_REDIRECTING_NUMBER_INFO_REC = 5;
- public static final int RIL_CDMA_LINE_CONTROL_INFO_REC = 6;
- public static final int RIL_CDMA_EXTENDED_DISPLAY_INFO_REC = 7;
- public static final int RIL_CDMA_T53_CLIR_INFO_REC = 8;
- public static final int RIL_CDMA_T53_RELEASE_INFO_REC = 9;
- public static final int RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC = 10;
-
- public CdmaInformationRecords(Parcel p) {
- int id = p.readInt();
- switch (id) {
- case RIL_CDMA_DISPLAY_INFO_REC:
- case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
- record = new CdmaDisplayInfoRec(id, p.readString());
- break;
-
- case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
- case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
- case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
- record = new CdmaNumberInfoRec(id, p.readString(), p.readInt(), p.readInt(),
- p.readInt(), p.readInt());
- break;
-
- case RIL_CDMA_SIGNAL_INFO_REC:
- record = new CdmaSignalInfoRec(p.readInt(), p.readInt(), p.readInt(), p.readInt());
- break;
-
- case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
- record = new CdmaRedirectingNumberInfoRec(p.readString(), p.readInt(), p.readInt(),
- p.readInt(), p.readInt(), p.readInt());
- break;
-
- case RIL_CDMA_LINE_CONTROL_INFO_REC:
- record = new CdmaLineControlInfoRec(p.readInt(), p.readInt(), p.readInt(),
- p.readInt());
- break;
-
- case RIL_CDMA_T53_CLIR_INFO_REC:
- record = new CdmaT53ClirInfoRec(p.readInt());
- break;
-
- case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
- record = new CdmaT53AudioControlInfoRec(p.readInt(), p.readInt());
- break;
-
- case RIL_CDMA_T53_RELEASE_INFO_REC:
- // TODO: WHAT to do, for now fall through and throw exception
- default:
- throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got "
- + CdmaInformationRecords.idToString(id) + " ");
-
- }
- }
-
- public static String idToString(int id) {
- switch(id) {
- case RIL_CDMA_DISPLAY_INFO_REC: return "RIL_CDMA_DISPLAY_INFO_REC";
- case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC";
- case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC";
- case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: return "RIL_CDMA_CONNECTED_NUMBER_INFO_REC";
- case RIL_CDMA_SIGNAL_INFO_REC: return "RIL_CDMA_SIGNAL_INFO_REC";
- case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: return "RIL_CDMA_REDIRECTING_NUMBER_INFO_REC";
- case RIL_CDMA_LINE_CONTROL_INFO_REC: return "RIL_CDMA_LINE_CONTROL_INFO_REC";
- case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: return "RIL_CDMA_EXTENDED_DISPLAY_INFO_REC";
- case RIL_CDMA_T53_CLIR_INFO_REC: return "RIL_CDMA_T53_CLIR_INFO_REC";
- case RIL_CDMA_T53_RELEASE_INFO_REC: return "RIL_CDMA_T53_RELEASE_INFO_REC";
- case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: return "RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC";
- default: return "<unknown record>";
- }
- }
-
- /**
- * Signal Information record from 3GPP2 C.S005 3.7.5.5
- */
- public static class CdmaSignalInfoRec {
- public boolean isPresent; /* non-zero if signal information record is present */
- public int signalType;
- public int alertPitch;
- public int signal;
-
- public CdmaSignalInfoRec() {}
-
- public CdmaSignalInfoRec(int isPresent, int signalType, int alertPitch, int signal) {
- this.isPresent = isPresent != 0;
- this.signalType = signalType;
- this.alertPitch = alertPitch;
- this.signal = signal;
- }
-
- @Override
- public String toString() {
- return "CdmaSignalInfo: {" +
- " isPresent: " + isPresent +
- ", signalType: " + signalType +
- ", alertPitch: " + alertPitch +
- ", signal: " + signal +
- " }";
- }
- }
-
- public static class CdmaDisplayInfoRec {
- public int id;
- public String alpha;
-
- public CdmaDisplayInfoRec(int id, String alpha) {
- this.id = id;
- this.alpha = alpha;
- }
-
- @Override
- public String toString() {
- return "CdmaDisplayInfoRec: {" +
- " id: " + CdmaInformationRecords.idToString(id) +
- ", alpha: " + alpha +
- " }";
- }
- }
-
- public static class CdmaNumberInfoRec {
- public int id;
- public String number;
- public byte numberType;
- public byte numberPlan;
- public byte pi;
- public byte si;
-
- public CdmaNumberInfoRec(int id, String number, int numberType, int numberPlan, int pi,
- int si) {
- this.number = number;
- this.numberType = (byte)numberType;
- this.numberPlan = (byte)numberPlan;
- this.pi = (byte)pi;
- this.si = (byte)si;
- }
-
- @Override
- public String toString() {
- return "CdmaNumberInfoRec: {" +
- " id: " + CdmaInformationRecords.idToString(id) +
- ", number: " + number +
- ", numberType: " + numberType +
- ", numberPlan: " + numberPlan +
- ", pi: " + pi +
- ", si: " + si +
- " }";
- }
- }
-
- public static class CdmaRedirectingNumberInfoRec {
- public static final int REASON_UNKNOWN = 0;
- public static final int REASON_CALL_FORWARDING_BUSY = 1;
- public static final int REASON_CALL_FORWARDING_NO_REPLY = 2;
- public static final int REASON_CALLED_DTE_OUT_OF_ORDER = 9;
- public static final int REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10;
- public static final int REASON_CALL_FORWARDING_UNCONDITIONAL = 15;
-
- public CdmaNumberInfoRec numberInfoRec;
- public int redirectingReason;
-
- public CdmaRedirectingNumberInfoRec(String number, int numberType, int numberPlan,
- int pi, int si, int reason) {
- numberInfoRec = new CdmaNumberInfoRec(RIL_CDMA_REDIRECTING_NUMBER_INFO_REC,
- number, numberType, numberPlan, pi, si);
- redirectingReason = reason;
- }
-
- @Override
- public String toString() {
- return "CdmaNumberInfoRec: {" +
- " numberInfoRec: " + numberInfoRec +
- ", redirectingReason: " + redirectingReason +
- " }";
- }
- }
-
- public static class CdmaLineControlInfoRec {
- public byte lineCtrlPolarityIncluded;
- public byte lineCtrlToggle;
- public byte lineCtrlReverse;
- public byte lineCtrlPowerDenial;
-
- public CdmaLineControlInfoRec(int lineCtrlPolarityIncluded, int lineCtrlToggle,
- int lineCtrlReverse, int lineCtrlPowerDenial) {
- this.lineCtrlPolarityIncluded = (byte)lineCtrlPolarityIncluded;
- this.lineCtrlToggle = (byte)lineCtrlToggle;
- this.lineCtrlReverse = (byte)lineCtrlReverse;
- this.lineCtrlPowerDenial = (byte)lineCtrlPowerDenial;
- }
-
- @Override
- public String toString() {
- return "CdmaLineControlInfoRec: {" +
- " lineCtrlPolarityIncluded: " + lineCtrlPolarityIncluded +
- " lineCtrlToggle: " + lineCtrlToggle +
- " lineCtrlReverse: " + lineCtrlReverse +
- " lineCtrlPowerDenial: " + lineCtrlPowerDenial +
- " }";
- }
- }
-
- public static class CdmaT53ClirInfoRec {
- public byte cause;
-
- public CdmaT53ClirInfoRec(int cause) {
- this.cause = (byte)cause;
- }
-
- @Override
- public String toString() {
- return "CdmaT53ClirInfoRec: {" +
- " cause: " + cause +
- " }";
- }
- }
-
- public static class CdmaT53AudioControlInfoRec {
- public byte uplink;
- public byte downlink;
-
- public CdmaT53AudioControlInfoRec(int uplink, int downlink) {
- this.uplink = (byte) uplink;
- this.downlink = (byte) downlink;
- }
-
- @Override
- public String toString() {
- return "CdmaT53AudioControlInfoRec: {" +
- " uplink: " + uplink +
- " downlink: " + downlink +
- " }";
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
deleted file mode 100644
index 0a40c75..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.IccCard;
-
-import android.content.Intent;
-import android.telephony.SignalStrength;
-import android.telephony.ServiceState;
-import android.telephony.cdma.CdmaCellLocation;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.provider.Telephony.Intents;
-
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.EventLog;
-
-import com.android.internal.telephony.gsm.GsmDataConnectionTracker;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
- CDMALTEPhone mCdmaLtePhone;
-
- private ServiceState mLteSS; // The last LTE state from Voice Registration
-
- public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
- super(phone);
- mCdmaLtePhone = phone;
-
- mLteSS = new ServiceState();
- if (DBG) log("CdmaLteServiceStateTracker Constructors");
- }
-
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
- int[] ints;
- String[] strings;
- switch (msg.what) {
- case EVENT_POLL_STATE_GPRS:
- if (DBG) log("handleMessage EVENT_POLL_STATE_GPRS");
- ar = (AsyncResult)msg.obj;
- handlePollStateResult(msg.what, ar);
- break;
- case EVENT_RUIM_RECORDS_LOADED:
- CdmaLteUiccRecords sim = (CdmaLteUiccRecords)phone.mIccRecords;
- if ((sim != null) && sim.isProvisioned()) {
- mMdn = sim.getMdn();
- mMin = sim.getMin();
- parseSidNid(sim.getSid(), sim.getNid());
- mPrlVersion = sim.getPrlVersion();;
- mIsMinInfoReady = true;
- updateOtaspState();
- }
- // SID/NID/PRL is loaded. Poll service state
- // again to update to the roaming state with
- // the latest variables.
- pollState();
- break;
- default:
- super.handleMessage(msg);
- }
- }
-
- /**
- * Set the cdmaSS for EVENT_POLL_STATE_REGISTRATION_CDMA
- */
- @Override
- protected void setCdmaTechnology(int radioTechnology) {
- // Called on voice registration state response.
- // Just record new CDMA radio technology
- newSS.setRadioTechnology(radioTechnology);
- }
-
- /**
- * Handle the result of one of the pollState()-related requests
- */
- @Override
- protected void handlePollStateResultMessage(int what, AsyncResult ar) {
- if (what == EVENT_POLL_STATE_GPRS) {
- if (DBG) log("handlePollStateResultMessage: EVENT_POLL_STATE_GPRS");
- String states[] = (String[])ar.result;
-
- int type = 0;
- int regState = -1;
- if (states.length > 0) {
- try {
- regState = Integer.parseInt(states[0]);
-
- // states[3] (if present) is the current radio technology
- if (states.length >= 4 && states[3] != null) {
- type = Integer.parseInt(states[3]);
- }
- } catch (NumberFormatException ex) {
- loge("handlePollStateResultMessage: error parsing GprsRegistrationState: "
- + ex);
- }
- }
-
- mLteSS.setRadioTechnology(type);
- mLteSS.setState(regCodeToServiceState(regState));
- } else {
- super.handlePollStateResultMessage(what, ar);
- }
- }
-
- @Override
- protected void setSignalStrengthDefaultValues() {
- // TODO Make a constructor only has boolean gsm as parameter
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, SignalStrength.INVALID_SNR, -1, false);
- }
-
- @Override
- protected void pollState() {
- pollingContext = new int[1];
- pollingContext[0] = 0;
-
- switch (cm.getRadioState()) {
- case RADIO_UNAVAILABLE:
- newSS.setStateOutOfService();
- newCellLoc.setStateInvalid();
- setSignalStrengthDefaultValues();
- mGotCountryCode = false;
-
- pollStateDone();
- break;
-
- case RADIO_OFF:
- newSS.setStateOff();
- newCellLoc.setStateInvalid();
- setSignalStrengthDefaultValues();
- mGotCountryCode = false;
-
- pollStateDone();
- break;
-
- default:
- // Issue all poll-related commands at once, then count
- // down the responses which are allowed to arrive
- // out-of-order.
-
- pollingContext[0]++;
- // RIL_REQUEST_OPERATOR is necessary for CDMA
- cm.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
-
- pollingContext[0]++;
- // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
- cm.getVoiceRegistrationState(obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA,
- pollingContext));
-
- int networkMode = android.provider.Settings.Secure.getInt(phone.getContext()
- .getContentResolver(),
- android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
- RILConstants.PREFERRED_NETWORK_MODE);
- if (DBG) log("pollState: network mode here is = " + networkMode);
- if ((networkMode == RILConstants.NETWORK_MODE_GLOBAL)
- || (networkMode == RILConstants.NETWORK_MODE_LTE_ONLY)) {
- pollingContext[0]++;
- // RIL_REQUEST_DATA_REGISTRATION_STATE
- cm.getDataRegistrationState(obtainMessage(EVENT_POLL_STATE_GPRS,
- pollingContext));
- }
- break;
- }
- }
-
- @Override
- protected void pollStateDone() {
- // determine data RadioTechnology from both LET and CDMA SS
- if (mLteSS.getState() == ServiceState.STATE_IN_SERVICE) {
- //in LTE service
- mNewRilRadioTechnology = mLteSS.getRilRadioTechnology();
- mNewDataConnectionState = mLteSS.getState();
- newSS.setRadioTechnology(mNewRilRadioTechnology);
- log("pollStateDone LTE/eHRPD STATE_IN_SERVICE mNewRilRadioTechnology = " +
- mNewRilRadioTechnology);
- } else {
- // LTE out of service, get CDMA Service State
- mNewRilRadioTechnology = newSS.getRilRadioTechnology();
- mNewDataConnectionState = radioTechnologyToDataServiceState(mNewRilRadioTechnology);
- log("pollStateDone CDMA STATE_IN_SERVICE mNewRilRadioTechnology = " +
- mNewRilRadioTechnology + " mNewDataConnectionState = " +
- mNewDataConnectionState);
- }
-
- // TODO: Add proper support for LTE Only, we should be looking at
- // the preferred network mode, to know when newSS state should
- // be coming from mLteSs state. This was needed to pass a VZW
- // LTE Only test.
- //
- // If CDMA service is OOS, double check if the device is running with LTE only
- // mode. If that is the case, derive the service state from LTE side.
- // To set in LTE only mode, sqlite3 /data/data/com.android.providers.settings/
- // databases/settings.db "update secure set value='11' where name='preferred_network_mode'"
- if (newSS.getState() == ServiceState.STATE_OUT_OF_SERVICE) {
- int networkMode = android.provider.Settings.Secure.getInt(phone.getContext()
- .getContentResolver(),
- android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
- RILConstants.PREFERRED_NETWORK_MODE);
- if (networkMode == RILConstants.NETWORK_MODE_LTE_ONLY) {
- if (DBG) log("pollState: LTE Only mode");
- newSS.setState(mLteSS.getState());
- }
- }
-
- if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]");
-
- boolean hasRegistered = ss.getState() != ServiceState.STATE_IN_SERVICE
- && newSS.getState() == ServiceState.STATE_IN_SERVICE;
-
- boolean hasDeregistered = ss.getState() == ServiceState.STATE_IN_SERVICE
- && newSS.getState() != ServiceState.STATE_IN_SERVICE;
-
- boolean hasCdmaDataConnectionAttached =
- mDataConnectionState != ServiceState.STATE_IN_SERVICE
- && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
-
- boolean hasCdmaDataConnectionDetached =
- mDataConnectionState == ServiceState.STATE_IN_SERVICE
- && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
-
- boolean hasCdmaDataConnectionChanged =
- mDataConnectionState != mNewDataConnectionState;
-
- boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
-
- boolean hasChanged = !newSS.equals(ss);
-
- boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
-
- boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
-
- boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
-
- boolean has4gHandoff =
- mNewDataConnectionState == ServiceState.STATE_IN_SERVICE &&
- (((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
- (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) ||
- ((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) &&
- (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE)));
-
- boolean hasMultiApnSupport =
- (((mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) ||
- (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) &&
- ((mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
- (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)));
-
- boolean hasLostMultiApnSupport =
- ((mNewRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) &&
- (mNewRilRadioTechnology <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A));
-
- if (DBG) {
- log("pollStateDone:"
- + " hasRegistered=" + hasRegistered
- + " hasDeegistered=" + hasDeregistered
- + " hasCdmaDataConnectionAttached=" + hasCdmaDataConnectionAttached
- + " hasCdmaDataConnectionDetached=" + hasCdmaDataConnectionDetached
- + " hasCdmaDataConnectionChanged=" + hasCdmaDataConnectionChanged
- + " hasRadioTechnologyChanged = " + hasRadioTechnologyChanged
- + " hasChanged=" + hasChanged
- + " hasRoamingOn=" + hasRoamingOn
- + " hasRoamingOff=" + hasRoamingOff
- + " hasLocationChanged=" + hasLocationChanged
- + " has4gHandoff = " + has4gHandoff
- + " hasMultiApnSupport=" + hasMultiApnSupport
- + " hasLostMultiApnSupport=" + hasLostMultiApnSupport);
- }
- // Add an event log when connection state changes
- if (ss.getState() != newSS.getState()
- || mDataConnectionState != mNewDataConnectionState) {
- EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, ss.getState(),
- mDataConnectionState, newSS.getState(), mNewDataConnectionState);
- }
-
- ServiceState tss;
- tss = ss;
- ss = newSS;
- newSS = tss;
- // clean slate for next time
- newSS.setStateOutOfService();
- mLteSS.setStateOutOfService();
-
- if ((hasMultiApnSupport)
- && (phone.mDataConnectionTracker instanceof CdmaDataConnectionTracker)) {
- if (DBG) log("GsmDataConnectionTracker Created");
- phone.mDataConnectionTracker.dispose();
- phone.mDataConnectionTracker = new GsmDataConnectionTracker(mCdmaLtePhone);
- }
-
- if ((hasLostMultiApnSupport)
- && (phone.mDataConnectionTracker instanceof GsmDataConnectionTracker)) {
- if (DBG)log("GsmDataConnectionTracker disposed");
- phone.mDataConnectionTracker.dispose();
- phone.mDataConnectionTracker = new CdmaDataConnectionTracker(phone);
- }
-
- CdmaCellLocation tcl = cellLoc;
- cellLoc = newCellLoc;
- newCellLoc = tcl;
-
- mDataConnectionState = mNewDataConnectionState;
- mRilRadioTechnology = mNewRilRadioTechnology;
- mNewRilRadioTechnology = 0;
-
- newSS.setStateOutOfService(); // clean slate for next time
-
- if (hasRadioTechnologyChanged) {
- phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
- ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
- }
-
- if (hasRegistered) {
- mNetworkAttachedRegistrants.notifyRegistrants();
- }
-
- if (hasChanged) {
- if (phone.isEriFileLoaded()) {
- String eriText;
- // Now the CDMAPhone sees the new ServiceState so it can get the
- // new ERI text
- if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
- eriText = phone.getCdmaEriText();
- } else if (ss.getState() == ServiceState.STATE_POWER_OFF) {
- eriText = phone.mIccRecords.getServiceProviderName();
- if (TextUtils.isEmpty(eriText)) {
- // Sets operator alpha property by retrieving from
- // build-time system property
- eriText = SystemProperties.get("ro.cdma.home.operator.alpha");
- }
- } else {
- // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used
- // for mRegistrationState 0,2,3 and 4
- eriText = phone.getContext()
- .getText(com.android.internal.R.string.roamingTextSearching).toString();
- }
- ss.setOperatorAlphaLong(eriText);
- }
-
- if (phone.getIccCard().getState() == IccCard.State.READY) {
- // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches
- // one configfured in SIM, use operator name from CSIM record.
- boolean showSpn =
- ((CdmaLteUiccRecords)phone.mIccRecords).getCsimSpnDisplayCondition();
- int iconIndex = ss.getCdmaEriIconIndex();
-
- if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) &&
- isInHomeSidNid(ss.getSystemId(), ss.getNetworkId())) {
- ss.setOperatorAlphaLong(phone.mIccRecords.getServiceProviderName());
- }
- }
-
- String operatorNumeric;
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
- ss.getOperatorAlphaLong());
-
- String prevOperatorNumeric =
- SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
- operatorNumeric = ss.getOperatorNumeric();
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
-
- if (operatorNumeric == null) {
- if (DBG) log("operatorNumeric is null");
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
- mGotCountryCode = false;
- } else {
- String isoCountryCode = "";
- String mcc = operatorNumeric.substring(0, 3);
- try {
- isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(operatorNumeric
- .substring(0, 3)));
- } catch (NumberFormatException ex) {
- loge("countryCodeForMcc error" + ex);
- } catch (StringIndexOutOfBoundsException ex) {
- loge("countryCodeForMcc error" + ex);
- }
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
- isoCountryCode);
- mGotCountryCode = true;
-
- if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
- mNeedFixZone)) {
- fixTimeZone(isoCountryCode);
- }
- }
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
- ss.getRoaming() ? "true" : "false");
-
- updateSpnDisplay();
- phone.notifyServiceStateChanged(ss);
- }
-
- if (hasCdmaDataConnectionAttached || has4gHandoff) {
- mAttachedRegistrants.notifyRegistrants();
- }
-
- if (hasCdmaDataConnectionDetached) {
- mDetachedRegistrants.notifyRegistrants();
- }
-
- if ((hasCdmaDataConnectionChanged || hasRadioTechnologyChanged)) {
- phone.notifyDataConnection(null);
- }
-
- if (hasRoamingOn) {
- mRoamingOnRegistrants.notifyRegistrants();
- }
-
- if (hasRoamingOff) {
- mRoamingOffRegistrants.notifyRegistrants();
- }
-
- if (hasLocationChanged) {
- phone.notifyLocationChanged();
- }
- }
-
- @Override
- protected void onSignalStrengthResult(AsyncResult ar) {
- SignalStrength oldSignalStrength = mSignalStrength;
-
- if (ar.exception != null) {
- // Most likely radio is resetting/disconnected change to default
- // values.
- setSignalStrengthDefaultValues();
- } else {
- int[] ints = (int[])ar.result;
-
- int lteRssi = -1;
- int lteRsrp = -1;
- int lteRsrq = -1;
- int lteRssnr = SignalStrength.INVALID_SNR;
- int lteCqi = -1;
-
- int offset = 2;
- int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
- int cdmaEcio = (ints[offset + 1] > 0) ? -ints[offset + 1] : -160;
- int evdoRssi = (ints[offset + 2] > 0) ? -ints[offset + 2] : -120;
- int evdoEcio = (ints[offset + 3] > 0) ? -ints[offset + 3] : -1;
- int evdoSnr = ((ints[offset + 4] > 0) && (ints[offset + 4] <= 8)) ? ints[offset + 4]
- : -1;
-
- if (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
- lteRssi = ints[offset+5];
- lteRsrp = ints[offset+6];
- lteRsrq = ints[offset+7];
- lteRssnr = ints[offset+8];
- lteCqi = ints[offset+9];
- }
-
- if (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
- mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
- evdoSnr, false);
- } else {
- mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
- evdoSnr, lteRssi, lteRsrp, lteRsrq, lteRssnr, lteCqi, true);
- }
- }
-
- try {
- phone.notifySignalStrength();
- } catch (NullPointerException ex) {
- loge("onSignalStrengthResult() Phone already destroyed: " + ex
- + "SignalStrength not notified");
- }
- }
-
- @Override
- public boolean isConcurrentVoiceAndDataAllowed() {
- // Note: it needs to be confirmed which CDMA network types
- // can support voice and data calls concurrently.
- // For the time-being, the return value will be false.
- return (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
- }
-
- /**
- * Check whether the specified SID and NID pair appears in the HOME SID/NID list
- * read from NV or SIM.
- *
- * @return true if provided sid/nid pair belongs to operator's home network.
- */
- private boolean isInHomeSidNid(int sid, int nid) {
- // if SID/NID is not available, assume this is home network.
- if (isSidsAllZeros()) return true;
-
- // length of SID/NID shold be same
- if (mHomeSystemId.length != mHomeNetworkId.length) return true;
-
- if (sid == 0) return true;
-
- for (int i = 0; i < mHomeSystemId.length; i++) {
- // Use SID only if NID is a reserved value.
- // SID 0 and NID 0 and 65535 are reserved. (C.0005 2.6.5.2)
- if ((mHomeSystemId[i] == sid) &&
- ((mHomeNetworkId[i] == 0) || (mHomeNetworkId[i] == 65535) ||
- (nid == 0) || (nid == 65535) || (mHomeNetworkId[i] == nid))) {
- return true;
- }
- }
- // SID/NID are not in the list. So device is not in home network
- return false;
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[CdmaLteSST] " + s);
- }
-
- @Override
- protected void loge(String s) {
- Log.e(LOG_TAG, "[CdmaLteSST] " + s);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("CdmaLteServiceStateTracker extends:");
- super.dump(fd, pw, args);
- pw.println(" mCdmaLtePhone=" + mCdmaLtePhone);
- pw.println(" mLteSS=" + mLteSS);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
deleted file mode 100644
index 93a6290..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2011 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.cdma;
-
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccFileHandler;
-import android.os.Message;
-
-/**
- * {@hide}
- */
-public final class CdmaLteUiccFileHandler extends IccFileHandler {
- static final String LOG_TAG = "CDMA";
-
- public CdmaLteUiccFileHandler(IccCard card, String aid, CommandsInterface ci) {
- super(card, aid, ci);
- }
-
- protected String getEFPath(int efid) {
- switch(efid) {
- case EF_CSIM_SPN:
- case EF_CSIM_LI:
- case EF_CSIM_MDN:
- case EF_CSIM_IMSIM:
- case EF_CSIM_CDMAHOME:
- case EF_CSIM_EPRL:
- return MF_SIM + DF_CDMA;
- case EF_AD:
- return MF_SIM + DF_GSM;
- case EF_IMPI:
- case EF_DOMAIN:
- case EF_IMPU:
- return MF_SIM + DF_ADFISIM;
- }
- return getCommonIccEFPath(efid);
- }
-
- @Override
- public void loadEFTransparent(int fileid, Message onLoaded) {
- if (fileid == EF_CSIM_EPRL) {
- // Entire PRL could be huge. We are only interested in
- // the first 4 bytes of the record.
- mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
- 0, 0, 4, null, null, mAid,
- obtainMessage(EVENT_READ_BINARY_DONE,
- fileid, 0, onLoaded));
- } else {
- super.loadEFTransparent(fileid, onLoaded);
- }
- }
-
-
- protected void logd(String msg) {
- Log.d(LOG_TAG, "[CdmaLteUiccFileHandler] " + msg);
- }
-
- protected void loge(String msg) {
- Log.e(LOG_TAG, "[CdmaLteUiccFileHandler] " + msg);
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
deleted file mode 100755
index eaa2ede..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2011 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.cdma;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.AdnRecordLoader;
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccCardApplication.AppType;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.telephony.gsm.SIMRecords;
-import com.android.internal.telephony.ims.IsimRecords;
-import com.android.internal.telephony.ims.IsimUiccRecords;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_TEST_CSIM;
-
-/**
- * {@hide}
- */
-public final class CdmaLteUiccRecords extends SIMRecords {
- // From CSIM application
- private byte[] mEFpl = null;
- private byte[] mEFli = null;
- boolean mCsimSpnDisplayCondition = false;
- private String mMdn;
- private String mMin;
- private String mPrlVersion;
- private String mHomeSystemId;
- private String mHomeNetworkId;
-
- private final IsimUiccRecords mIsimUiccRecords = new IsimUiccRecords();
-
- public CdmaLteUiccRecords(IccCard card, Context c, CommandsInterface ci) {
- super(card, c, ci);
- }
-
- // Refer to ETSI TS 102.221
- private class EfPlLoaded implements IccRecordLoaded {
- public String getEfName() {
- return "EF_PL";
- }
-
- public void onRecordLoaded(AsyncResult ar) {
- mEFpl = (byte[]) ar.result;
- if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEFpl));
- }
- }
-
- // Refer to C.S0065 5.2.26
- private class EfCsimLiLoaded implements IccRecordLoaded {
- public String getEfName() {
- return "EF_CSIM_LI";
- }
-
- public void onRecordLoaded(AsyncResult ar) {
- mEFli = (byte[]) ar.result;
- // convert csim efli data to iso 639 format
- for (int i = 0; i < mEFli.length; i+=2) {
- switch(mEFli[i+1]) {
- case 0x01: mEFli[i] = 'e'; mEFli[i+1] = 'n';break;
- case 0x02: mEFli[i] = 'f'; mEFli[i+1] = 'r';break;
- case 0x03: mEFli[i] = 'e'; mEFli[i+1] = 's';break;
- case 0x04: mEFli[i] = 'j'; mEFli[i+1] = 'a';break;
- case 0x05: mEFli[i] = 'k'; mEFli[i+1] = 'o';break;
- case 0x06: mEFli[i] = 'z'; mEFli[i+1] = 'h';break;
- case 0x07: mEFli[i] = 'h'; mEFli[i+1] = 'e';break;
- default: mEFli[i] = ' '; mEFli[i+1] = ' ';
- }
- }
-
- if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEFli));
- }
- }
-
- // Refer to C.S0065 5.2.32
- private class EfCsimSpnLoaded implements IccRecordLoaded {
- public String getEfName() {
- return "EF_CSIM_SPN";
- }
-
- public void onRecordLoaded(AsyncResult ar) {
- byte[] data = (byte[]) ar.result;
- if (DBG) log("CSIM_SPN=" +
- IccUtils.bytesToHexString(data));
-
- // C.S0065 for EF_SPN decoding
- mCsimSpnDisplayCondition = ((0x01 & data[0]) != 0);
-
- int encoding = data[1];
- int language = data[2];
- byte[] spnData = new byte[32];
- System.arraycopy(data, 3, spnData, 0, (data.length < 32) ? data.length : 32);
-
- int numBytes;
- for (numBytes = 0; numBytes < spnData.length; numBytes++) {
- if ((spnData[numBytes] & 0xFF) == 0xFF) break;
- }
-
- if (numBytes == 0) {
- spn = "";
- return;
- }
- try {
- switch (encoding) {
- case UserData.ENCODING_OCTET:
- case UserData.ENCODING_LATIN:
- spn = new String(spnData, 0, numBytes, "ISO-8859-1");
- break;
- case UserData.ENCODING_IA5:
- case UserData.ENCODING_GSM_7BIT_ALPHABET:
- case UserData.ENCODING_7BIT_ASCII:
- spn = GsmAlphabet.gsm7BitPackedToString(spnData, 0, (numBytes*8)/7);
- break;
- case UserData.ENCODING_UNICODE_16:
- spn = new String(spnData, 0, numBytes, "utf-16");
- break;
- default:
- log("SPN encoding not supported");
- }
- } catch(Exception e) {
- log("spn decode error: " + e);
- }
- if (DBG) log("spn=" + spn);
- if (DBG) log("spnCondition=" + mCsimSpnDisplayCondition);
- SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
- }
- }
-
- private class EfCsimMdnLoaded implements IccRecordLoaded {
- public String getEfName() {
- return "EF_CSIM_MDN";
- }
-
- public void onRecordLoaded(AsyncResult ar) {
- byte[] data = (byte[]) ar.result;
- if (DBG) log("CSIM_MDN=" + IccUtils.bytesToHexString(data));
- int mdnDigitsNum = 0x0F & data[0];
- mMdn = IccUtils.cdmaBcdToString(data, 1, mdnDigitsNum);
- if (DBG) log("CSIM MDN=" + mMdn);
- }
- }
-
- private class EfCsimImsimLoaded implements IccRecordLoaded {
- public String getEfName() {
- return "EF_CSIM_IMSIM";
- }
-
- public void onRecordLoaded(AsyncResult ar) {
- byte[] data = (byte[]) ar.result;
- if (DBG) log("CSIM_IMSIM=" + IccUtils.bytesToHexString(data));
- // C.S0065 section 5.2.2 for IMSI_M encoding
- // C.S0005 section 2.3.1 for MIN encoding in IMSI_M.
- boolean provisioned = ((data[7] & 0x80) == 0x80);
-
- if (provisioned) {
- int first3digits = ((0x03 & data[2]) << 8) + (0xFF & data[1]);
- int second3digits = (((0xFF & data[5]) << 8) | (0xFF & data[4])) >> 6;
- int digit7 = 0x0F & (data[4] >> 2);
- if (digit7 > 0x09) digit7 = 0;
- int last3digits = ((0x03 & data[4]) << 8) | (0xFF & data[3]);
- first3digits = adjstMinDigits(first3digits);
- second3digits = adjstMinDigits(second3digits);
- last3digits = adjstMinDigits(last3digits);
-
- StringBuilder builder = new StringBuilder();
- builder.append(String.format(Locale.US, "%03d", first3digits));
- builder.append(String.format(Locale.US, "%03d", second3digits));
- builder.append(String.format(Locale.US, "%d", digit7));
- builder.append(String.format(Locale.US, "%03d", last3digits));
- mMin = builder.toString();
- if (DBG) log("min present=" + mMin);
- } else {
- if (DBG) log("min not present");
- }
- }
- }
-
- private class EfCsimCdmaHomeLoaded implements IccRecordLoaded {
- public String getEfName() {
- return "EF_CSIM_CDMAHOME";
- }
-
- public void onRecordLoaded(AsyncResult ar) {
- // Per C.S0065 section 5.2.8
- ArrayList<byte[]> dataList = (ArrayList<byte[]>) ar.result;
- if (DBG) log("CSIM_CDMAHOME data size=" + dataList.size());
- if (dataList.isEmpty()) {
- return;
- }
- StringBuilder sidBuf = new StringBuilder();
- StringBuilder nidBuf = new StringBuilder();
-
- for (byte[] data : dataList) {
- if (data.length == 5) {
- int sid = ((data[1] & 0xFF) << 8) | (data[0] & 0xFF);
- int nid = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
- sidBuf.append(sid).append(',');
- nidBuf.append(nid).append(',');
- }
- }
- // remove trailing ","
- sidBuf.setLength(sidBuf.length()-1);
- nidBuf.setLength(nidBuf.length()-1);
-
- mHomeSystemId = sidBuf.toString();
- mHomeNetworkId = nidBuf.toString();
- }
- }
-
- private class EfCsimEprlLoaded implements IccRecordLoaded {
- public String getEfName() {
- return "EF_CSIM_EPRL";
- }
- public void onRecordLoaded(AsyncResult ar) {
- onGetCSimEprlDone(ar);
- }
- }
-
- @Override
- protected void onRecordLoaded() {
- // One record loaded successfully or failed, In either case
- // we need to update the recordsToLoad count
- recordsToLoad -= 1;
-
- if (recordsToLoad == 0 && recordsRequested == true) {
- onAllRecordsLoaded();
- } else if (recordsToLoad < 0) {
- Log.e(LOG_TAG, "SIMRecords: recordsToLoad <0, programmer error suspected");
- recordsToLoad = 0;
- }
- }
-
- @Override
- protected void onAllRecordsLoaded() {
- setLocaleFromCsim();
- super.onAllRecordsLoaded(); // broadcasts ICC state change to "LOADED"
- }
-
- @Override
- protected void fetchSimRecords() {
- recordsRequested = true;
-
- mCi.getIMSIForApp(mParentCard.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_PL,
- obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded()));
- recordsToLoad++;
-
- new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1,
- obtainMessage(EVENT_GET_MSISDN_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_CSIM_LI,
- obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimLiLoaded()));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_CSIM_SPN,
- obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimSpnLoaded()));
- recordsToLoad++;
-
- mFh.loadEFLinearFixed(EF_CSIM_MDN, 1,
- obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimMdnLoaded()));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_CSIM_IMSIM,
- obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimImsimLoaded()));
- recordsToLoad++;
-
- mFh.loadEFLinearFixedAll(EF_CSIM_CDMAHOME,
- obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimCdmaHomeLoaded()));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_CSIM_EPRL,
- obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfCsimEprlLoaded()));
- recordsToLoad++;
-
- // load ISIM records
- recordsToLoad += mIsimUiccRecords.fetchIsimRecords(mFh, this);
- }
-
- private int adjstMinDigits (int digits) {
- // Per C.S0005 section 2.3.1.
- digits += 111;
- digits = (digits % 10 == 0)?(digits - 10):digits;
- digits = ((digits / 10) % 10 == 0)?(digits - 100):digits;
- digits = ((digits / 100) % 10 == 0)?(digits - 1000):digits;
- return digits;
- }
-
- private void onGetCSimEprlDone(AsyncResult ar) {
- // C.S0065 section 5.2.57 for EFeprl encoding
- // C.S0016 section 3.5.5 for PRL format.
- byte[] data = (byte[]) ar.result;
- if (DBG) log("CSIM_EPRL=" + IccUtils.bytesToHexString(data));
-
- // Only need the first 4 bytes of record
- if (data.length > 3) {
- int prlId = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
- mPrlVersion = Integer.toString(prlId);
- }
- if (DBG) log("CSIM PRL version=" + mPrlVersion);
- }
-
- private void setLocaleFromCsim() {
- String prefLang = null;
- // check EFli then EFpl
- prefLang = findBestLanguage(mEFli);
-
- if (prefLang == null) {
- prefLang = findBestLanguage(mEFpl);
- }
-
- if (prefLang != null) {
- // check country code from SIM
- String imsi = getIMSI();
- String country = null;
- if (imsi != null) {
- country = MccTable.countryCodeForMcc(
- Integer.parseInt(imsi.substring(0,3)));
- }
- log("Setting locale to " + prefLang + "_" + country);
- MccTable.setSystemLocale(mContext, prefLang, country);
- } else {
- log ("No suitable CSIM selected locale");
- }
- }
-
- private String findBestLanguage(byte[] languages) {
- String bestMatch = null;
- String[] locales = mContext.getAssets().getLocales();
-
- if ((languages == null) || (locales == null)) return null;
-
- // Each 2-bytes consists of one language
- for (int i = 0; (i + 1) < languages.length; i += 2) {
- try {
- String lang = new String(languages, i, 2, "ISO-8859-1");
- for (int j = 0; j < locales.length; j++) {
- if (locales[j] != null && locales[j].length() >= 2 &&
- locales[j].substring(0, 2).equals(lang)) {
- return lang;
- }
- }
- if (bestMatch != null) break;
- } catch(java.io.UnsupportedEncodingException e) {
- log ("Failed to parse SIM language records");
- }
- }
- // no match found. return null
- return null;
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[CSIM] " + s);
- }
-
- @Override
- protected void loge(String s) {
- Log.e(LOG_TAG, "[CSIM] " + s);
- }
-
- public String getMdn() {
- return mMdn;
- }
-
- public String getMin() {
- return mMin;
- }
-
- public String getSid() {
- return mHomeSystemId;
- }
-
- public String getNid() {
- return mHomeNetworkId;
- }
-
- public String getPrlVersion() {
- return mPrlVersion;
- }
-
- public boolean getCsimSpnDisplayCondition() {
- return mCsimSpnDisplayCondition;
- }
-
- @Override
- public IsimRecords getIsimRecords() {
- return mIsimUiccRecords;
- }
-
- @Override
- public boolean isProvisioned() {
- // If UICC card has CSIM app, look for MDN and MIN field
- // to determine if the SIM is provisioned. Otherwise,
- // consider the SIM is provisioned. (for case of ordinal
- // USIM only UICC.)
- // If PROPERTY_TEST_CSIM is defined, bypess provision check
- // and consider the SIM is provisioned.
- if (SystemProperties.getBoolean(PROPERTY_TEST_CSIM, false)) {
- return true;
- }
-
- if (mParentCard == null) {
- return false;
- }
-
- if (mParentCard.isApplicationOnIcc(AppType.APPTYPE_CSIM) &&
- ((mMdn == null) || (mMin == null))) {
- return false;
- }
- return true;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java b/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
deleted file mode 100644
index 8dd8c2e..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * 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.cdma;
-
-import android.content.Context;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.MmiCode;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
-/**
- * This class can handle Puk code Mmi
- *
- * {@hide}
- *
- */
-public final class CdmaMmiCode extends Handler implements MmiCode {
- static final String LOG_TAG = "CDMA_MMI";
-
- // Constants
-
- // From TS 22.030 6.5.2
- static final String ACTION_REGISTER = "**";
-
- // Supp Service codes from TS 22.030 Annex B
- static final String SC_PUK = "05";
-
- // Event Constant
-
- static final int EVENT_SET_COMPLETE = 1;
-
- // Instance Variables
-
- CDMAPhone phone;
- Context context;
-
- String action; // ACTION_REGISTER
- String sc; // Service Code
- String sia, sib, sic; // Service Info a,b,c
- String poundString; // Entire MMI string up to and including #
- String dialingNumber;
- String pwd; // For password registration
-
- State state = State.PENDING;
- CharSequence message;
-
- // Class Variables
-
- static Pattern sPatternSuppService = Pattern.compile(
- "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
-/* 1 2 3 4 5 6 7 8 9 10 11 12
-
- 1 = Full string up to and including #
- 2 = action
- 3 = service code
- 5 = SIA
- 7 = SIB
- 9 = SIC
- 10 = dialing number
-*/
-
- static final int MATCH_GROUP_POUND_STRING = 1;
- static final int MATCH_GROUP_ACTION = 2;
- static final int MATCH_GROUP_SERVICE_CODE = 3;
- static final int MATCH_GROUP_SIA = 5;
- static final int MATCH_GROUP_SIB = 7;
- static final int MATCH_GROUP_SIC = 9;
- static final int MATCH_GROUP_PWD_CONFIRM = 11;
- static final int MATCH_GROUP_DIALING_NUMBER = 12;
-
-
- // Public Class methods
-
- /**
- * Check if provided string contains Mmi code in it and create corresponding
- * Mmi if it does
- */
-
- public static CdmaMmiCode
- newFromDialString(String dialString, CDMAPhone phone) {
- Matcher m;
- CdmaMmiCode ret = null;
-
- m = sPatternSuppService.matcher(dialString);
-
- // Is this formatted like a standard supplementary service code?
- if (m.matches()) {
- ret = new CdmaMmiCode(phone);
- ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
- ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
- ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
- ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
- ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
- ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
- ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
- ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
-
- }
-
- return ret;
- }
-
- // Private Class methods
-
- /** make empty strings be null.
- * Regexp returns empty strings for empty groups
- */
- private static String
- makeEmptyNull (String s) {
- if (s != null && s.length() == 0) return null;
-
- return s;
- }
-
- // Constructor
-
- CdmaMmiCode (CDMAPhone phone) {
- super(phone.getHandler().getLooper());
- this.phone = phone;
- this.context = phone.getContext();
- }
-
- // MmiCode implementation
-
- public State
- getState() {
- return state;
- }
-
- public CharSequence
- getMessage() {
- return message;
- }
-
- // inherited javadoc suffices
- public void
- cancel() {
- // Complete or failed cannot be cancelled
- if (state == State.COMPLETE || state == State.FAILED) {
- return;
- }
-
- state = State.CANCELLED;
- phone.onMMIDone (this);
- }
-
- public boolean isCancelable() {
- return false;
- }
-
- // Instance Methods
-
- /**
- * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
- */
- boolean isPukCommand() {
- return sc != null && sc.equals(SC_PUK);
- }
-
- boolean isRegister() {
- return action != null && action.equals(ACTION_REGISTER);
- }
-
- public boolean isUssdRequest() {
- Log.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode");
- return false;
- }
-
- /** Process a MMI PUK code */
- void
- processCode () {
- try {
- if (isPukCommand()) {
- // sia = old PUK
- // sib = new PIN
- // sic = new PIN
- String oldPinOrPuk = sia;
- String newPin = sib;
- int pinLen = newPin.length();
- if (isRegister()) {
- if (!newPin.equals(sic)) {
- // password mismatch; return error
- handlePasswordError(com.android.internal.R.string.mismatchPin);
- } else if (pinLen < 4 || pinLen > 8 ) {
- // invalid length
- handlePasswordError(com.android.internal.R.string.invalidPin);
- } else {
- phone.mCM.supplyIccPuk(oldPinOrPuk, newPin,
- obtainMessage(EVENT_SET_COMPLETE, this));
- }
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
- } catch (RuntimeException exc) {
- state = State.FAILED;
- message = context.getText(com.android.internal.R.string.mmiError);
- phone.onMMIDone(this);
- }
- }
-
- private void handlePasswordError(int res) {
- state = State.FAILED;
- StringBuilder sb = new StringBuilder(getScString());
- sb.append("\n");
- sb.append(context.getText(res));
- message = sb;
- phone.onMMIDone(this);
- }
-
- public void
- handleMessage (Message msg) {
- AsyncResult ar;
-
- if (msg.what == EVENT_SET_COMPLETE) {
- ar = (AsyncResult) (msg.obj);
- onSetComplete(ar);
- } else {
- Log.e(LOG_TAG, "Unexpected reply");
- }
- }
- // Private instance methods
-
- private CharSequence getScString() {
- if (sc != null) {
- if (isPukCommand()) {
- return context.getText(com.android.internal.R.string.PinMmi);
- }
- }
-
- return "";
- }
-
- private void
- onSetComplete(AsyncResult ar){
- StringBuilder sb = new StringBuilder(getScString());
- sb.append("\n");
-
- if (ar.exception != null) {
- state = State.FAILED;
- if (ar.exception instanceof CommandException) {
- CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
- if (err == CommandException.Error.PASSWORD_INCORRECT) {
- if (isPukCommand()) {
- sb.append(context.getText(
- com.android.internal.R.string.badPuk));
- } else {
- sb.append(context.getText(
- com.android.internal.R.string.passwordIncorrect));
- }
- } else {
- sb.append(context.getText(
- com.android.internal.R.string.mmiError));
- }
- } else {
- sb.append(context.getText(
- com.android.internal.R.string.mmiError));
- }
- } else if (isRegister()) {
- state = State.COMPLETE;
- sb.append(context.getText(
- com.android.internal.R.string.serviceRegistered));
- } else {
- state = State.FAILED;
- sb.append(context.getText(
- com.android.internal.R.string.mmiError));
- }
-
- message = sb;
- phone.onMMIDone(this);
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
deleted file mode 100755
index a6b32f9..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Telephony;
-import android.provider.Telephony.Sms.Intents;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsCbMessage;
-import android.telephony.SmsManager;
-import android.telephony.SmsMessage.MessageClass;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.telephony.cdma.CdmaSmsCbProgramResults;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.telephony.SmsStorageMonitor;
-import com.android.internal.telephony.SmsUsageMonitor;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.WspTypeDecoder;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-import com.android.internal.telephony.cdma.sms.UserData;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-
-
-final class CdmaSMSDispatcher extends SMSDispatcher {
- private static final String TAG = "CDMA";
-
- private byte[] mLastDispatchedSmsFingerprint;
- private byte[] mLastAcknowledgedSmsFingerprint;
-
- private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean(
- com.android.internal.R.bool.config_duplicate_port_omadm_wappush);
-
- CdmaSMSDispatcher(CDMAPhone phone, SmsStorageMonitor storageMonitor,
- SmsUsageMonitor usageMonitor) {
- super(phone, storageMonitor, usageMonitor);
- mCm.setOnNewCdmaSms(this, EVENT_NEW_SMS, null);
- }
-
- @Override
- public void dispose() {
- mCm.unSetOnNewCdmaSms(this);
- }
-
- @Override
- protected String getFormat() {
- return android.telephony.SmsMessage.FORMAT_3GPP2;
- }
-
- private void handleCdmaStatusReport(SmsMessage sms) {
- for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
- SmsTracker tracker = deliveryPendingList.get(i);
- if (tracker.mMessageRef == sms.messageRef) {
- // Found it. Remove from list and broadcast.
- deliveryPendingList.remove(i);
- PendingIntent intent = tracker.mDeliveryIntent;
- Intent fillIn = new Intent();
- fillIn.putExtra("pdu", sms.getPdu());
- fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2);
- try {
- intent.send(mContext, Activity.RESULT_OK, fillIn);
- } catch (CanceledException ex) {}
- break; // Only expect to see one tracker matching this message.
- }
- }
- }
-
- /**
- * Dispatch service category program data to the CellBroadcastReceiver app, which filters
- * the broadcast alerts to display.
- * @param sms the SMS message containing one or more
- * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects.
- */
- private void handleServiceCategoryProgramData(SmsMessage sms) {
- ArrayList<CdmaSmsCbProgramData> programDataList = sms.getSmsCbProgramData();
- if (programDataList == null) {
- Log.e(TAG, "handleServiceCategoryProgramData: program data list is null!");
- return;
- }
-
- Intent intent = new Intent(Intents.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION);
- intent.putExtra("sender", sms.getOriginatingAddress());
- intent.putParcelableArrayListExtra("program_data", programDataList);
- dispatch(intent, RECEIVE_SMS_PERMISSION, mScpResultsReceiver);
- }
-
- /** {@inheritDoc} */
- @Override
- public int dispatchMessage(SmsMessageBase smsb) {
-
- // If sms is null, means there was a parsing error.
- if (smsb == null) {
- Log.e(TAG, "dispatchMessage: message is null");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
-
- String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- if (inEcm.equals("true")) {
- return Activity.RESULT_OK;
- }
-
- if (mSmsReceiveDisabled) {
- // Device doesn't support receiving SMS,
- Log.d(TAG, "Received short message on device which doesn't support "
- + "receiving SMS. Ignored.");
- return Intents.RESULT_SMS_HANDLED;
- }
-
- SmsMessage sms = (SmsMessage) smsb;
-
- // Handle CMAS emergency broadcast messages.
- if (SmsEnvelope.MESSAGE_TYPE_BROADCAST == sms.getMessageType()) {
- Log.d(TAG, "Broadcast type message");
- SmsCbMessage message = sms.parseBroadcastSms();
- if (message != null) {
- dispatchBroadcastMessage(message);
- }
- return Intents.RESULT_SMS_HANDLED;
- }
-
- // See if we have a network duplicate SMS.
- mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint();
- if (mLastAcknowledgedSmsFingerprint != null &&
- Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) {
- return Intents.RESULT_SMS_HANDLED;
- }
- // Decode BD stream and set sms variables.
- sms.parseSms();
- int teleService = sms.getTeleService();
- boolean handled = false;
-
- if ((SmsEnvelope.TELESERVICE_VMN == teleService) ||
- (SmsEnvelope.TELESERVICE_MWI == teleService)) {
- // handling Voicemail
- int voicemailCount = sms.getNumOfVoicemails();
- Log.d(TAG, "Voicemail count=" + voicemailCount);
- // Store the voicemail count in preferences.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
- mContext);
- SharedPreferences.Editor editor = sp.edit();
- editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount);
- editor.apply();
- mPhone.setVoiceMessageWaiting(1, voicemailCount);
- handled = true;
- } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) ||
- (SmsEnvelope.TELESERVICE_WEMT == teleService)) &&
- sms.isStatusReportMessage()) {
- handleCdmaStatusReport(sms);
- handled = true;
- } else if (SmsEnvelope.TELESERVICE_SCPT == teleService) {
- handleServiceCategoryProgramData(sms);
- handled = true;
- } else if ((sms.getUserData() == null)) {
- if (false) {
- Log.d(TAG, "Received SMS without user data");
- }
- handled = true;
- }
-
- if (handled) {
- return Intents.RESULT_SMS_HANDLED;
- }
-
- if (!mStorageMonitor.isStorageAvailable() &&
- sms.getMessageClass() != MessageClass.CLASS_0) {
- // It's a storable message and there's no storage available. Bail.
- // (See C.S0015-B v2.0 for a description of "Immediate Display"
- // messages, which we represent as CLASS_0.)
- return Intents.RESULT_SMS_OUT_OF_MEMORY;
- }
-
- if (SmsEnvelope.TELESERVICE_WAP == teleService) {
- return processCdmaWapPdu(sms.getUserData(), sms.messageRef,
- sms.getOriginatingAddress());
- }
-
- // Reject (NAK) any messages with teleservice ids that have
- // not yet been handled and also do not correspond to the two
- // kinds that are processed below.
- if ((SmsEnvelope.TELESERVICE_WMT != teleService) &&
- (SmsEnvelope.TELESERVICE_WEMT != teleService) &&
- (SmsEnvelope.MESSAGE_TYPE_BROADCAST != sms.getMessageType())) {
- return Intents.RESULT_SMS_UNSUPPORTED;
- }
-
- return dispatchNormalMessage(smsb);
- }
-
- /**
- * Processes inbound messages that are in the WAP-WDP PDU format. See
- * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format.
- * WDP segments are gathered until a datagram completes and gets dispatched.
- *
- * @param pdu The WAP-WDP PDU segment
- * @return a result code from {@link Telephony.Sms.Intents}, or
- * {@link Activity#RESULT_OK} if the message has been broadcast
- * to applications
- */
- protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) {
- int index = 0;
-
- int msgType = (0xFF & pdu[index++]);
- if (msgType != 0) {
- Log.w(TAG, "Received a WAP SMS which is not WDP. Discard.");
- return Intents.RESULT_SMS_HANDLED;
- }
- int totalSegments = (0xFF & pdu[index++]); // >= 1
- int segment = (0xFF & pdu[index++]); // >= 0
-
- if (segment >= totalSegments) {
- Log.e(TAG, "WDP bad segment #" + segment + " expecting 0-" + (totalSegments - 1));
- return Intents.RESULT_SMS_HANDLED;
- }
-
- // Only the first segment contains sourcePort and destination Port
- int sourcePort = 0;
- int destinationPort = 0;
- if (segment == 0) {
- //process WDP segment
- sourcePort = (0xFF & pdu[index++]) << 8;
- sourcePort |= 0xFF & pdu[index++];
- destinationPort = (0xFF & pdu[index++]) << 8;
- destinationPort |= 0xFF & pdu[index++];
- // Some carriers incorrectly send duplicate port fields in omadm wap pushes.
- // If configured, check for that here
- if (mCheckForDuplicatePortsInOmadmWapPush) {
- if (checkDuplicatePortOmadmWappush(pdu,index)) {
- index = index + 4; // skip duplicate port fields
- }
- }
- }
-
- // Lookup all other related parts
- Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address
- + ", src-port = " + sourcePort + ", dst-port = " + destinationPort
- + ", ID = " + referenceNumber + ", segment# = " + segment + '/' + totalSegments);
-
- // pass the user data portion of the PDU to the shared handler in SMSDispatcher
- byte[] userData = new byte[pdu.length - index];
- System.arraycopy(pdu, index, userData, 0, pdu.length - index);
-
- return processMessagePart(userData, address, referenceNumber, segment, totalSegments,
- 0L, destinationPort, true);
- }
-
- /** {@inheritDoc} */
- @Override
- protected void sendData(String destAddr, String scAddr, int destPort,
- byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
- scAddr, destAddr, destPort, data, (deliveryIntent != null));
- sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr);
- }
-
- /** {@inheritDoc} */
- @Override
- protected void sendText(String destAddr, String scAddr, String text,
- PendingIntent sentIntent, PendingIntent deliveryIntent) {
- SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
- scAddr, destAddr, text, (deliveryIntent != null), null);
- sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr);
- }
-
- /** {@inheritDoc} */
- @Override
- protected TextEncodingDetails calculateLength(CharSequence messageBody,
- boolean use7bitOnly) {
- return SmsMessage.calculateLength(messageBody, use7bitOnly);
- }
-
- /** {@inheritDoc} */
- @Override
- protected void sendNewSubmitPdu(String destinationAddress, String scAddress,
- String message, SmsHeader smsHeader, int encoding,
- PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) {
- UserData uData = new UserData();
- uData.payloadStr = message;
- uData.userDataHeader = smsHeader;
- if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
- uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
- } else { // assume UTF-16
- uData.msgEncoding = UserData.ENCODING_UNICODE_16;
- }
- uData.msgEncodingSet = true;
-
- /* By setting the statusReportRequested bit only for the
- * last message fragment, this will result in only one
- * callback to the sender when that last fragment delivery
- * has been acknowledged. */
- SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destinationAddress,
- uData, (deliveryIntent != null) && lastPart);
-
- sendSubmitPdu(submitPdu, sentIntent, deliveryIntent, destinationAddress);
- }
-
- protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu,
- PendingIntent sentIntent, PendingIntent deliveryIntent, String destAddr) {
- if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) {
- if (sentIntent != null) {
- try {
- sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE);
- } catch (CanceledException ex) {}
- }
- if (false) {
- Log.d(TAG, "Block SMS in Emergency Callback mode");
- }
- return;
- }
- sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, destAddr);
- }
-
- /** {@inheritDoc} */
- @Override
- protected void sendSms(SmsTracker tracker) {
- HashMap<String, Object> map = tracker.mData;
-
- // byte smsc[] = (byte[]) map.get("smsc"); // unused for CDMA
- byte pdu[] = (byte[]) map.get("pdu");
-
- Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
- mCm.sendCdmaSms(pdu, reply);
- }
-
- /** {@inheritDoc} */
- @Override
- protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) {
- String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- if (inEcm.equals("true")) {
- return;
- }
-
- int causeCode = resultToCause(result);
- mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response);
-
- if (causeCode == 0) {
- mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint;
- }
- mLastDispatchedSmsFingerprint = null;
- }
-
- private static int resultToCause(int rc) {
- switch (rc) {
- case Activity.RESULT_OK:
- case Intents.RESULT_SMS_HANDLED:
- // Cause code is ignored on success.
- return 0;
- case Intents.RESULT_SMS_OUT_OF_MEMORY:
- return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE;
- case Intents.RESULT_SMS_UNSUPPORTED:
- return CommandsInterface.CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID;
- case Intents.RESULT_SMS_GENERIC_ERROR:
- default:
- return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM;
- }
- }
-
- /**
- * Optional check to see if the received WapPush is an OMADM notification with erroneous
- * extra port fields.
- * - Some carriers make this mistake.
- * ex: MSGTYPE-TotalSegments-CurrentSegment
- * -SourcePortDestPort-SourcePortDestPort-OMADM PDU
- * @param origPdu The WAP-WDP PDU segment
- * @param index Current Index while parsing the PDU.
- * @return True if OrigPdu is OmaDM Push Message which has duplicate ports.
- * False if OrigPdu is NOT OmaDM Push Message which has duplicate ports.
- */
- private static boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) {
- index += 4;
- byte[] omaPdu = new byte[origPdu.length - index];
- System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length);
-
- WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu);
- int wspIndex = 2;
-
- // Process header length field
- if (pduDecoder.decodeUintvarInteger(wspIndex) == false) {
- return false;
- }
-
- wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field
-
- // Process content type field
- if (pduDecoder.decodeContentType(wspIndex) == false) {
- return false;
- }
-
- String mimeType = pduDecoder.getValueString();
- if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) {
- return true;
- }
- return false;
- }
-
- // Receiver for Service Category Program Data results.
- // We already ACK'd the original SCPD SMS, so this sends a new response SMS.
- // TODO: handle retries if the RIL returns an error.
- private final BroadcastReceiver mScpResultsReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- int rc = getResultCode();
- boolean success = (rc == Activity.RESULT_OK) || (rc == Intents.RESULT_SMS_HANDLED);
- if (!success) {
- Log.e(TAG, "SCP results error: result code = " + rc);
- return;
- }
- Bundle extras = getResultExtras(false);
- if (extras == null) {
- Log.e(TAG, "SCP results error: missing extras");
- return;
- }
- String sender = extras.getString("sender");
- if (sender == null) {
- Log.e(TAG, "SCP results error: missing sender extra.");
- return;
- }
- ArrayList<CdmaSmsCbProgramResults> results
- = extras.getParcelableArrayList("results");
- if (results == null) {
- Log.e(TAG, "SCP results error: missing results extra.");
- return;
- }
-
- BearerData bData = new BearerData();
- bData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
- bData.messageId = SmsMessage.getNextMessageId();
- bData.serviceCategoryProgramResults = results;
- byte[] encodedBearerData = BearerData.encode(bData);
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
- DataOutputStream dos = new DataOutputStream(baos);
- try {
- dos.writeInt(SmsEnvelope.TELESERVICE_SCPT);
- dos.writeInt(0); //servicePresent
- dos.writeInt(0); //serviceCategory
- CdmaSmsAddress destAddr = CdmaSmsAddress.parse(
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode(sender));
- dos.write(destAddr.digitMode);
- dos.write(destAddr.numberMode);
- dos.write(destAddr.ton); // number_type
- dos.write(destAddr.numberPlan);
- dos.write(destAddr.numberOfDigits);
- dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits
- // Subaddress is not supported.
- dos.write(0); //subaddressType
- dos.write(0); //subaddr_odd
- dos.write(0); //subaddr_nbr_of_digits
- dos.write(encodedBearerData.length);
- dos.write(encodedBearerData, 0, encodedBearerData.length);
- // Ignore the RIL response. TODO: implement retry if SMS send fails.
- mCm.sendCdmaSms(baos.toByteArray(), null);
- } catch (IOException e) {
- Log.e(TAG, "exception creating SCP results PDU", e);
- } finally {
- try {
- dos.close();
- } catch (IOException ignored) {
- }
- }
- }
- };
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
deleted file mode 100755
index 564ce3b..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ /dev/null
@@ -1,1752 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.CommandsInterface.RadioState;
-
-import android.app.AlarmManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.ContentObserver;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.provider.Settings.Secure;
-import android.provider.Settings.SettingNotFoundException;
-import android.provider.Telephony.Intents;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.cdma.CdmaCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.TimeUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * {@hide}
- */
-public class CdmaServiceStateTracker extends ServiceStateTracker {
- static final String LOG_TAG = "CDMA";
-
- CDMAPhone phone;
- CdmaCellLocation cellLoc;
- CdmaCellLocation newCellLoc;
-
- // Min values used to by getOtasp()
- private static final String UNACTIVATED_MIN2_VALUE = "000000";
- private static final String UNACTIVATED_MIN_VALUE = "1111110111";
-
- // Current Otasp value
- int mCurrentOtaspMode = OTASP_UNINITIALIZED;
-
- /** if time between NITZ updates is less than mNitzUpdateSpacing the update may be ignored. */
- private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10;
- private int mNitzUpdateSpacing = SystemProperties.getInt("ro.nitz_update_spacing",
- NITZ_UPDATE_SPACING_DEFAULT);
-
- /** If mNitzUpdateSpacing hasn't been exceeded but update is > mNitzUpdate do the update */
- private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000;
- private int mNitzUpdateDiff = SystemProperties.getInt("ro.nitz_update_diff",
- NITZ_UPDATE_DIFF_DEFAULT);
-
- private boolean mCdmaRoaming = false;
- private int mRoamingIndicator;
- private boolean mIsInPrl;
- private int mDefaultRoamingIndicator;
-
- /**
- * Initially assume no data connection.
- */
- protected int mDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
- protected int mNewDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
- protected int mRegistrationState = -1;
- protected RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
-
- /**
- * Sometimes we get the NITZ time before we know what country we
- * are in. Keep the time zone information from the NITZ string so
- * we can fix the time zone once know the country.
- */
- protected boolean mNeedFixZone = false;
- private int mZoneOffset;
- private boolean mZoneDst;
- private long mZoneTime;
- protected boolean mGotCountryCode = false;
- String mSavedTimeZone;
- long mSavedTime;
- long mSavedAtTime;
-
- /**
- * We can't register for SIM_RECORDS_LOADED immediately because the
- * SIMRecords object may not be instantiated yet.
- */
- private boolean mNeedToRegForRuimLoaded = false;
-
- /** Wake lock used while setting time of day. */
- private PowerManager.WakeLock mWakeLock;
- private static final String WAKELOCK_TAG = "ServiceStateTracker";
-
- /** Contains the name of the registered network in CDMA (either ONS or ERI text). */
- protected String mCurPlmn = null;
-
- protected String mMdn;
- protected int mHomeSystemId[] = null;
- protected int mHomeNetworkId[] = null;
- protected String mMin;
- protected String mPrlVersion;
- protected boolean mIsMinInfoReady = false;
-
- private boolean isEriTextLoaded = false;
- protected boolean isSubscriptionFromRuim = false;
- private CdmaSubscriptionSourceManager mCdmaSSM;
-
- /* Used only for debugging purposes. */
- private String mRegistrationDeniedReason;
-
- private ContentResolver cr;
- private String currentCarrier = null;
-
- private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
- @Override
- public void onChange(boolean selfChange) {
- if (DBG) log("Auto time state changed");
- revertToNitzTime();
- }
- };
-
- private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
- @Override
- public void onChange(boolean selfChange) {
- if (DBG) log("Auto time zone state changed");
- revertToNitzTimeZone();
- }
- };
-
- public CdmaServiceStateTracker(CDMAPhone phone) {
- super();
-
- this.phone = phone;
- cr = phone.getContext().getContentResolver();
- cm = phone.mCM;
- ss = new ServiceState();
- newSS = new ServiceState();
- cellLoc = new CdmaCellLocation();
- newCellLoc = new CdmaCellLocation();
- mSignalStrength = new SignalStrength();
-
- mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(phone.getContext(), cm, this,
- EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
- isSubscriptionFromRuim = (mCdmaSSM.getCdmaSubscriptionSource() ==
- CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
-
- PowerManager powerManager =
- (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
- mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
-
- cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
-
- cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
- cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
- cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
-
- cm.registerForCdmaPrlChanged(this, EVENT_CDMA_PRL_VERSION_CHANGED, null);
- phone.registerForEriFileLoaded(this, EVENT_ERI_FILE_LOADED, null);
- cm.registerForCdmaOtaProvision(this,EVENT_OTA_PROVISION_STATUS_CHANGE, null);
-
- // System setting property AIRPLANE_MODE_ON is set in Settings.
- int airplaneMode = Settings.System.getInt(cr, Settings.System.AIRPLANE_MODE_ON, 0);
- mDesiredPowerState = ! (airplaneMode > 0);
-
- cr.registerContentObserver(
- Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
- mAutoTimeObserver);
- cr.registerContentObserver(
- Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true,
- mAutoTimeZoneObserver);
- setSignalStrengthDefaultValues();
-
- mNeedToRegForRuimLoaded = true;
- }
-
- public void dispose() {
- // Unregister for all events.
- cm.unregisterForRadioStateChanged(this);
- cm.unregisterForVoiceNetworkStateChanged(this);
- phone.getIccCard().unregisterForReady(this);
- cm.unregisterForCdmaOtaProvision(this);
- phone.unregisterForEriFileLoaded(this);
- phone.mIccRecords.unregisterForRecordsLoaded(this);
- cm.unSetOnSignalStrengthUpdate(this);
- cm.unSetOnNITZTime(this);
- cr.unregisterContentObserver(mAutoTimeObserver);
- cr.unregisterContentObserver(mAutoTimeZoneObserver);
- mCdmaSSM.dispose(this);
- cm.unregisterForCdmaPrlChanged(this);
- }
-
- @Override
- protected void finalize() {
- if (DBG) log("CdmaServiceStateTracker finalized");
- }
-
- /**
- * Registration point for subscription info ready
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- cdmaForSubscriptionInfoReadyRegistrants.add(r);
-
- if (isMinInfoReady()) {
- r.notifyRegistrant();
- }
- }
-
- public void unregisterForSubscriptionInfoReady(Handler h) {
- cdmaForSubscriptionInfoReadyRegistrants.remove(h);
- }
-
- /**
- * Save current source of cdma subscription
- * @param source - 1 for NV, 0 for RUIM
- */
- private void saveCdmaSubscriptionSource(int source) {
- log("Storing cdma subscription source: " + source);
- Secure.putInt(phone.getContext().getContentResolver(),
- Secure.CDMA_SUBSCRIPTION_MODE,
- source );
- }
-
- private void getSubscriptionInfoAndStartPollingThreads() {
- cm.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
-
- // Get Registration Information
- pollState();
- }
-
- @Override
- public void handleMessage (Message msg) {
- AsyncResult ar;
- int[] ints;
- String[] strings;
-
- if (!phone.mIsTheCurrentActivePhone) {
- loge("Received message " + msg + "[" + msg.what + "]" +
- " while being destroyed. Ignoring.");
- return;
- }
-
- switch (msg.what) {
- case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
- handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
- break;
-
- case EVENT_RUIM_READY:
- // TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
- // cm.setCurrentPreferredNetworkType();
-
- // The RUIM is now ready i.e if it was locked it has been
- // unlocked. At this stage, the radio is already powered on.
- if (mNeedToRegForRuimLoaded) {
- phone.mIccRecords.registerForRecordsLoaded(this,
- EVENT_RUIM_RECORDS_LOADED, null);
- mNeedToRegForRuimLoaded = false;
- }
-
- if (phone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
- // Subscription will be read from SIM I/O
- if (DBG) log("Receive EVENT_RUIM_READY");
- pollState();
- } else {
- if (DBG) log("Receive EVENT_RUIM_READY and Send Request getCDMASubscription.");
- getSubscriptionInfoAndStartPollingThreads();
- }
- phone.prepareEri();
- break;
-
- case EVENT_NV_READY:
- // For Non-RUIM phones, the subscription information is stored in
- // Non Volatile. Here when Non-Volatile is ready, we can poll the CDMA
- // subscription info.
- getSubscriptionInfoAndStartPollingThreads();
- break;
-
- case EVENT_RADIO_STATE_CHANGED:
- if(cm.getRadioState() == RadioState.RADIO_ON) {
- handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
-
- // Signal strength polling stops when radio is off.
- queueNextSignalStrengthPoll();
- }
- // This will do nothing in the 'radio not available' case.
- setPowerStateToDesired();
- pollState();
- break;
-
- case EVENT_NETWORK_STATE_CHANGED_CDMA:
- pollState();
- break;
-
- case EVENT_GET_SIGNAL_STRENGTH:
- // This callback is called when signal strength is polled
- // all by itself.
-
- if (!(cm.getRadioState().isOn())) {
- // Polling will continue when radio turns back on.
- return;
- }
- ar = (AsyncResult) msg.obj;
- onSignalStrengthResult(ar);
- queueNextSignalStrengthPoll();
-
- break;
-
- case EVENT_GET_LOC_DONE_CDMA:
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception == null) {
- String states[] = (String[])ar.result;
- int baseStationId = -1;
- int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
- int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
- int systemId = -1;
- int networkId = -1;
-
- if (states.length > 9) {
- try {
- if (states[4] != null) {
- baseStationId = Integer.parseInt(states[4]);
- }
- if (states[5] != null) {
- baseStationLatitude = Integer.parseInt(states[5]);
- }
- if (states[6] != null) {
- baseStationLongitude = Integer.parseInt(states[6]);
- }
- // Some carriers only return lat-lngs of 0,0
- if (baseStationLatitude == 0 && baseStationLongitude == 0) {
- baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
- baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
- }
- if (states[8] != null) {
- systemId = Integer.parseInt(states[8]);
- }
- if (states[9] != null) {
- networkId = Integer.parseInt(states[9]);
- }
- } catch (NumberFormatException ex) {
- loge("error parsing cell location data: " + ex);
- }
- }
-
- cellLoc.setCellLocationData(baseStationId, baseStationLatitude,
- baseStationLongitude, systemId, networkId);
- phone.notifyLocationChanged();
- }
-
- // Release any temporary cell lock, which could have been
- // acquired to allow a single-shot location update.
- disableSingleLocationUpdate();
- break;
-
- case EVENT_POLL_STATE_REGISTRATION_CDMA:
- case EVENT_POLL_STATE_OPERATOR_CDMA:
- ar = (AsyncResult) msg.obj;
- handlePollStateResult(msg.what, ar);
- break;
-
- case EVENT_POLL_STATE_CDMA_SUBSCRIPTION: // Handle RIL_CDMA_SUBSCRIPTION
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception == null) {
- String cdmaSubscription[] = (String[])ar.result;
- if (cdmaSubscription != null && cdmaSubscription.length >= 5) {
- mMdn = cdmaSubscription[0];
- parseSidNid(cdmaSubscription[1], cdmaSubscription[2]);
-
- mMin = cdmaSubscription[3];
- mPrlVersion = cdmaSubscription[4];
- if (DBG) log("GET_CDMA_SUBSCRIPTION: MDN=" + mMdn);
-
- mIsMinInfoReady = true;
-
- updateOtaspState();
- phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
- null);
- } else {
- if (DBG) {
- log("GET_CDMA_SUBSCRIPTION: error parsing cdmaSubscription params num="
- + cdmaSubscription.length);
- }
- }
- }
- break;
-
- case EVENT_POLL_SIGNAL_STRENGTH:
- // Just poll signal strength...not part of pollState()
-
- cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
- break;
-
- case EVENT_NITZ_TIME:
- ar = (AsyncResult) msg.obj;
-
- String nitzString = (String)((Object[])ar.result)[0];
- long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
-
- setTimeFromNITZString(nitzString, nitzReceiveTime);
- break;
-
- case EVENT_SIGNAL_STRENGTH_UPDATE:
- // This is a notification from CommandsInterface.setOnSignalStrengthUpdate.
-
- ar = (AsyncResult) msg.obj;
-
- // The radio is telling us about signal strength changes,
- // so we don't have to ask it.
- dontPollSignalStrength = true;
-
- onSignalStrengthResult(ar);
- break;
-
- case EVENT_RUIM_RECORDS_LOADED:
- updateSpnDisplay();
- break;
-
- case EVENT_LOCATION_UPDATES_ENABLED:
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception == null) {
- cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null));
- }
- break;
-
- case EVENT_ERI_FILE_LOADED:
- // Repoll the state once the ERI file has been loaded.
- if (DBG) log("[CdmaServiceStateTracker] ERI file has been loaded, repolling.");
- pollState();
- break;
-
- case EVENT_OTA_PROVISION_STATUS_CHANGE:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- ints = (int[]) ar.result;
- int otaStatus = ints[0];
- if (otaStatus == Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED
- || otaStatus == Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED) {
- if (DBG) log("EVENT_OTA_PROVISION_STATUS_CHANGE: Complete, Reload MDN");
- cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
- }
- }
- break;
-
- case EVENT_CDMA_PRL_VERSION_CHANGED:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- ints = (int[]) ar.result;
- mPrlVersion = Integer.toString(ints[0]);
- }
- break;
-
- default:
- super.handleMessage(msg);
- break;
- }
- }
-
- //***** Private Instance Methods
-
- private void handleCdmaSubscriptionSource(int newSubscriptionSource) {
- log("Subscription Source : " + newSubscriptionSource);
- isSubscriptionFromRuim =
- (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM);
- saveCdmaSubscriptionSource(newSubscriptionSource);
- if (!isSubscriptionFromRuim) {
- // NV is ready when subscription source is NV
- sendMessage(obtainMessage(EVENT_NV_READY));
- } else {
- phone.getIccCard().registerForReady(this, EVENT_RUIM_READY, null);
- }
- }
-
- @Override
- protected void setPowerStateToDesired() {
- // If we want it on and it's off, turn it on
- if (mDesiredPowerState
- && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
- cm.setRadioPower(true, null);
- } else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
- DataConnectionTracker dcTracker = phone.mDataConnectionTracker;
-
- // If it's on and available and we want it off gracefully
- powerOffRadioSafely(dcTracker);
- } // Otherwise, we're in the desired state
- }
-
- @Override
- protected void updateSpnDisplay() {
- // mOperatorAlphaLong contains the ERI text
- String plmn = ss.getOperatorAlphaLong();
- if (!TextUtils.equals(plmn, mCurPlmn)) {
- // Allow A blank plmn, "" to set showPlmn to true. Previously, we
- // would set showPlmn to true only if plmn was not empty, i.e. was not
- // null and not blank. But this would cause us to incorrectly display
- // "No Service". Now showPlmn is set to true for any non null string.
- boolean showPlmn = plmn != null;
- if (DBG) {
- log(String.format("updateSpnDisplay: changed sending intent" +
- " showPlmn='%b' plmn='%s'", showPlmn, plmn));
- }
- Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra(Intents.EXTRA_SHOW_SPN, false);
- intent.putExtra(Intents.EXTRA_SPN, "");
- intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn);
- intent.putExtra(Intents.EXTRA_PLMN, plmn);
- phone.getContext().sendStickyBroadcast(intent);
- }
-
- mCurPlmn = plmn;
- }
-
- @Override
- protected Phone getPhone() {
- return phone;
- }
-
- /**
- * Determine data network type based on radio technology.
- */
- protected void setCdmaTechnology(int radioTech){
- mNewDataConnectionState = radioTechnologyToDataServiceState(radioTech);
- newSS.setRadioTechnology(radioTech);
- mNewRilRadioTechnology = radioTech;
- }
-
- /**
- * Hanlde the PollStateResult message
- */
- protected void handlePollStateResultMessage(int what, AsyncResult ar){
- int ints[];
- String states[];
- switch (what) {
- case EVENT_POLL_STATE_REGISTRATION_CDMA: // Handle RIL_REQUEST_REGISTRATION_STATE.
- states = (String[])ar.result;
-
- int registrationState = 4; //[0] registrationState
- int radioTechnology = -1; //[3] radioTechnology
- int baseStationId = -1; //[4] baseStationId
- //[5] baseStationLatitude
- int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
- //[6] baseStationLongitude
- int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
- int cssIndicator = 0; //[7] init with 0, because it is treated as a boolean
- int systemId = 0; //[8] systemId
- int networkId = 0; //[9] networkId
- int roamingIndicator = -1; //[10] Roaming indicator
- int systemIsInPrl = 0; //[11] Indicates if current system is in PRL
- int defaultRoamingIndicator = 0; //[12] Is default roaming indicator from PRL
- int reasonForDenial = 0; //[13] Denial reason if registrationState = 3
-
- if (states.length >= 14) {
- try {
- if (states[0] != null) {
- registrationState = Integer.parseInt(states[0]);
- }
- if (states[3] != null) {
- radioTechnology = Integer.parseInt(states[3]);
- }
- if (states[4] != null) {
- baseStationId = Integer.parseInt(states[4]);
- }
- if (states[5] != null) {
- baseStationLatitude = Integer.parseInt(states[5]);
- }
- if (states[6] != null) {
- baseStationLongitude = Integer.parseInt(states[6]);
- }
- // Some carriers only return lat-lngs of 0,0
- if (baseStationLatitude == 0 && baseStationLongitude == 0) {
- baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
- baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
- }
- if (states[7] != null) {
- cssIndicator = Integer.parseInt(states[7]);
- }
- if (states[8] != null) {
- systemId = Integer.parseInt(states[8]);
- }
- if (states[9] != null) {
- networkId = Integer.parseInt(states[9]);
- }
- if (states[10] != null) {
- roamingIndicator = Integer.parseInt(states[10]);
- }
- if (states[11] != null) {
- systemIsInPrl = Integer.parseInt(states[11]);
- }
- if (states[12] != null) {
- defaultRoamingIndicator = Integer.parseInt(states[12]);
- }
- if (states[13] != null) {
- reasonForDenial = Integer.parseInt(states[13]);
- }
- } catch (NumberFormatException ex) {
- loge("EVENT_POLL_STATE_REGISTRATION_CDMA: error parsing: " + ex);
- }
- } else {
- throw new RuntimeException("Warning! Wrong number of parameters returned from "
- + "RIL_REQUEST_REGISTRATION_STATE: expected 14 or more "
- + "strings and got " + states.length + " strings");
- }
-
- mRegistrationState = registrationState;
- // When registration state is roaming and TSB58
- // roaming indicator is not in the carrier-specified
- // list of ERIs for home system, mCdmaRoaming is true.
- mCdmaRoaming =
- regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]);
- newSS.setState (regCodeToServiceState(registrationState));
-
- setCdmaTechnology(radioTechnology);
-
- newSS.setCssIndicator(cssIndicator);
- newSS.setSystemAndNetworkId(systemId, networkId);
- mRoamingIndicator = roamingIndicator;
- mIsInPrl = (systemIsInPrl == 0) ? false : true;
- mDefaultRoamingIndicator = defaultRoamingIndicator;
-
-
- // Values are -1 if not available.
- newCellLoc.setCellLocationData(baseStationId, baseStationLatitude,
- baseStationLongitude, systemId, networkId);
-
- if (reasonForDenial == 0) {
- mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN;
- } else if (reasonForDenial == 1) {
- mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH;
- } else {
- mRegistrationDeniedReason = "";
- }
-
- if (mRegistrationState == 3) {
- if (DBG) log("Registration denied, " + mRegistrationDeniedReason);
- }
- break;
-
- case EVENT_POLL_STATE_OPERATOR_CDMA: // Handle RIL_REQUEST_OPERATOR
- String opNames[] = (String[])ar.result;
-
- if (opNames != null && opNames.length >= 3) {
- // If the NUMERIC field isn't valid use PROPERTY_CDMA_HOME_OPERATOR_NUMERIC
- if ((opNames[2] == null) || (opNames[2].length() < 5)
- || ("00000".equals(opNames[2]))) {
- opNames[2] = SystemProperties.get(
- CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC, "00000");
- if (DBG) {
- log("RIL_REQUEST_OPERATOR.response[2], the numeric, " +
- " is bad. Using SystemProperties '" +
- CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC +
- "'= " + opNames[2]);
- }
- }
-
- if (!isSubscriptionFromRuim) {
- // In CDMA in case on NV, the ss.mOperatorAlphaLong is set later with the
- // ERI text, so here it is ignored what is coming from the modem.
- newSS.setOperatorName(null, opNames[1], opNames[2]);
- } else {
- newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
- }
- } else {
- if (DBG) log("EVENT_POLL_STATE_OPERATOR_CDMA: error parsing opNames");
- }
- break;
- default:
- loge("handlePollStateResultMessage: RIL response handle in wrong phone!"
- + " Expected CDMA RIL request and get GSM RIL request.");
- break;
- }
- }
-
- /**
- * Handle the result of one of the pollState() - related requests
- */
- @Override
- protected void handlePollStateResult(int what, AsyncResult ar) {
- // Ignore stale requests from last poll.
- if (ar.userObj != pollingContext) return;
-
- if (ar.exception != null) {
- CommandException.Error err=null;
-
- if (ar.exception instanceof CommandException) {
- err = ((CommandException)(ar.exception)).getCommandError();
- }
-
- if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
- // Radio has crashed or turned off.
- cancelPollState();
- return;
- }
-
- if (!cm.getRadioState().isOn()) {
- // Radio has crashed or turned off.
- cancelPollState();
- return;
- }
-
- if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
- loge("handlePollStateResult: RIL returned an error where it must succeed"
- + ar.exception);
- }
- } else try {
- handlePollStateResultMessage(what, ar);
- } catch (RuntimeException ex) {
- loge("handlePollStateResult: Exception while polling service state. "
- + "Probably malformed RIL response." + ex);
- }
-
- pollingContext[0]--;
-
- if (pollingContext[0] == 0) {
- boolean namMatch = false;
- if (!isSidsAllZeros() && isHomeSid(newSS.getSystemId())) {
- namMatch = true;
- }
-
- // Setting SS Roaming (general)
- if (isSubscriptionFromRuim) {
- newSS.setRoaming(isRoamingBetweenOperators(mCdmaRoaming, newSS));
- } else {
- newSS.setRoaming(mCdmaRoaming);
- }
-
- // Setting SS CdmaRoamingIndicator and CdmaDefaultRoamingIndicator
- newSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator);
- newSS.setCdmaRoamingIndicator(mRoamingIndicator);
- boolean isPrlLoaded = true;
- if (TextUtils.isEmpty(mPrlVersion)) {
- isPrlLoaded = false;
- }
- if (!isPrlLoaded) {
- newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
- } else if (!isSidsAllZeros()) {
- if (!namMatch && !mIsInPrl) {
- // Use default
- newSS.setCdmaRoamingIndicator(mDefaultRoamingIndicator);
- } else if (namMatch && !mIsInPrl) {
- newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
- } else if (!namMatch && mIsInPrl) {
- // Use the one from PRL/ERI
- newSS.setCdmaRoamingIndicator(mRoamingIndicator);
- } else {
- // It means namMatch && mIsInPrl
- if ((mRoamingIndicator <= 2)) {
- newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
- } else {
- // Use the one from PRL/ERI
- newSS.setCdmaRoamingIndicator(mRoamingIndicator);
- }
- }
- }
-
- int roamingIndicator = newSS.getCdmaRoamingIndicator();
- newSS.setCdmaEriIconIndex(phone.mEriManager.getCdmaEriIconIndex(roamingIndicator,
- mDefaultRoamingIndicator));
- newSS.setCdmaEriIconMode(phone.mEriManager.getCdmaEriIconMode(roamingIndicator,
- mDefaultRoamingIndicator));
-
- // NOTE: Some operator may require overriding mCdmaRoaming
- // (set by the modem), depending on the mRoamingIndicator.
-
- if (DBG) {
- log("Set CDMA Roaming Indicator to: " + newSS.getCdmaRoamingIndicator()
- + ". mCdmaRoaming = " + mCdmaRoaming + ", isPrlLoaded = " + isPrlLoaded
- + ". namMatch = " + namMatch + " , mIsInPrl = " + mIsInPrl
- + ", mRoamingIndicator = " + mRoamingIndicator
- + ", mDefaultRoamingIndicator= " + mDefaultRoamingIndicator);
- }
- pollStateDone();
- }
-
- }
-
- protected void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false);
- }
-
- /**
- * A complete "service state" from our perspective is
- * composed of a handful of separate requests to the radio.
- *
- * We make all of these requests at once, but then abandon them
- * and start over again if the radio notifies us that some
- * event has changed
- */
- protected void
- pollState() {
- pollingContext = new int[1];
- pollingContext[0] = 0;
-
- switch (cm.getRadioState()) {
- case RADIO_UNAVAILABLE:
- newSS.setStateOutOfService();
- newCellLoc.setStateInvalid();
- setSignalStrengthDefaultValues();
- mGotCountryCode = false;
-
- pollStateDone();
- break;
-
- case RADIO_OFF:
- newSS.setStateOff();
- newCellLoc.setStateInvalid();
- setSignalStrengthDefaultValues();
- mGotCountryCode = false;
-
- pollStateDone();
- break;
-
- default:
- // Issue all poll-related commands at once, then count
- // down the responses which are allowed to arrive
- // out-of-order.
-
- pollingContext[0]++;
- // RIL_REQUEST_OPERATOR is necessary for CDMA
- cm.getOperator(
- obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
-
- pollingContext[0]++;
- // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
- cm.getVoiceRegistrationState(
- obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext));
-
- break;
- }
- }
-
- protected void fixTimeZone(String isoCountryCode) {
- TimeZone zone = null;
- // If the offset is (0, false) and the time zone property
- // is set, use the time zone property rather than GMT.
- String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
- if (DBG) {
- log("fixTimeZone zoneName='" + zoneName +
- "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
- " iso-cc='" + isoCountryCode +
- "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode));
- }
- if ((mZoneOffset == 0) && (mZoneDst == false) && (zoneName != null)
- && (zoneName.length() > 0)
- && (Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode) < 0)) {
- // For NITZ string without time zone,
- // need adjust time to reflect default time zone setting
- zone = TimeZone.getDefault();
- if (mNeedFixZone) {
- long ctm = System.currentTimeMillis();
- long tzOffset = zone.getOffset(ctm);
- if (DBG) {
- log("fixTimeZone: tzOffset=" + tzOffset +
- " ltod=" + TimeUtils.logTimeOfDay(ctm));
- }
- if (getAutoTime()) {
- long adj = ctm - tzOffset;
- if (DBG) log("fixTimeZone: adj ltod=" + TimeUtils.logTimeOfDay(adj));
- setAndBroadcastNetworkSetTime(adj);
- } else {
- // Adjust the saved NITZ time to account for tzOffset.
- mSavedTime = mSavedTime - tzOffset;
- if (DBG) log("fixTimeZone: adj mSavedTime=" + mSavedTime);
- }
- }
- if (DBG) log("fixTimeZone: using default TimeZone");
- } else if (isoCountryCode.equals("")) {
- // Country code not found. This is likely a test network.
- // Get a TimeZone based only on the NITZ parameters (best guess).
- zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
- if (DBG) log("fixTimeZone: using NITZ TimeZone");
- } else {
- zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, isoCountryCode);
- if (DBG) log("fixTimeZone: using getTimeZone(off, dst, time, iso)");
- }
-
- mNeedFixZone = false;
-
- if (zone != null) {
- log("fixTimeZone: zone != null zone.getID=" + zone.getID());
- if (getAutoTimeZone()) {
- setAndBroadcastNetworkSetTimeZone(zone.getID());
- } else {
- log("fixTimeZone: skip changing zone as getAutoTimeZone was false");
- }
- saveNitzTimeZone(zone.getID());
- } else {
- log("fixTimeZone: zone == null, do nothing for zone");
- }
- }
-
- protected void pollStateDone() {
- if (DBG) log("pollStateDone: oldSS=[" + ss + "] newSS=[" + newSS + "]");
-
- boolean hasRegistered =
- ss.getState() != ServiceState.STATE_IN_SERVICE
- && newSS.getState() == ServiceState.STATE_IN_SERVICE;
-
- boolean hasDeregistered =
- ss.getState() == ServiceState.STATE_IN_SERVICE
- && newSS.getState() != ServiceState.STATE_IN_SERVICE;
-
- boolean hasCdmaDataConnectionAttached =
- mDataConnectionState != ServiceState.STATE_IN_SERVICE
- && mNewDataConnectionState == ServiceState.STATE_IN_SERVICE;
-
- boolean hasCdmaDataConnectionDetached =
- mDataConnectionState == ServiceState.STATE_IN_SERVICE
- && mNewDataConnectionState != ServiceState.STATE_IN_SERVICE;
-
- boolean hasCdmaDataConnectionChanged =
- mDataConnectionState != mNewDataConnectionState;
-
- boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
-
- boolean hasChanged = !newSS.equals(ss);
-
- boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
-
- boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
-
- boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
-
- // Add an event log when connection state changes
- if (ss.getState() != newSS.getState() ||
- mDataConnectionState != mNewDataConnectionState) {
- EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE,
- ss.getState(), mDataConnectionState,
- newSS.getState(), mNewDataConnectionState);
- }
-
- ServiceState tss;
- tss = ss;
- ss = newSS;
- newSS = tss;
- // clean slate for next time
- newSS.setStateOutOfService();
-
- CdmaCellLocation tcl = cellLoc;
- cellLoc = newCellLoc;
- newCellLoc = tcl;
-
- mDataConnectionState = mNewDataConnectionState;
- mRilRadioTechnology = mNewRilRadioTechnology;
- // this new state has been applied - forget it until we get a new new state
- mNewRilRadioTechnology = 0;
-
- newSS.setStateOutOfService(); // clean slate for next time
-
- if (hasRadioTechnologyChanged) {
- phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
- ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
- }
-
- if (hasRegistered) {
- mNetworkAttachedRegistrants.notifyRegistrants();
- }
-
- if (hasChanged) {
- if ((cm.getRadioState().isOn()) && (!isSubscriptionFromRuim)) {
- String eriText;
- // Now the CDMAPhone sees the new ServiceState so it can get the new ERI text
- if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
- eriText = phone.getCdmaEriText();
- } else {
- // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used for
- // mRegistrationState 0,2,3 and 4
- eriText = phone.getContext().getText(
- com.android.internal.R.string.roamingTextSearching).toString();
- }
- ss.setOperatorAlphaLong(eriText);
- }
-
- String operatorNumeric;
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
- ss.getOperatorAlphaLong());
-
- String prevOperatorNumeric =
- SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
- operatorNumeric = ss.getOperatorNumeric();
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
-
- if (operatorNumeric == null) {
- if (DBG) log("operatorNumeric is null");
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
- mGotCountryCode = false;
- } else {
- String isoCountryCode = "";
- String mcc = operatorNumeric.substring(0, 3);
- try{
- isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(
- operatorNumeric.substring(0,3)));
- } catch ( NumberFormatException ex){
- loge("pollStateDone: countryCodeForMcc error" + ex);
- } catch ( StringIndexOutOfBoundsException ex) {
- loge("pollStateDone: countryCodeForMcc error" + ex);
- }
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
- isoCountryCode);
- mGotCountryCode = true;
-
- if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
- mNeedFixZone)) {
- fixTimeZone(isoCountryCode);
- }
- }
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
- ss.getRoaming() ? "true" : "false");
-
- updateSpnDisplay();
- phone.notifyServiceStateChanged(ss);
- }
-
- if (hasCdmaDataConnectionAttached) {
- mAttachedRegistrants.notifyRegistrants();
- }
-
- if (hasCdmaDataConnectionDetached) {
- mDetachedRegistrants.notifyRegistrants();
- }
-
- if (hasCdmaDataConnectionChanged || hasRadioTechnologyChanged) {
- phone.notifyDataConnection(null);
- }
-
- if (hasRoamingOn) {
- mRoamingOnRegistrants.notifyRegistrants();
- }
-
- if (hasRoamingOff) {
- mRoamingOffRegistrants.notifyRegistrants();
- }
-
- if (hasLocationChanged) {
- phone.notifyLocationChanged();
- }
- }
-
- /**
- * Returns a TimeZone object based only on parameters from the NITZ string.
- */
- private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
- TimeZone guess = findTimeZone(offset, dst, when);
- if (guess == null) {
- // Couldn't find a proper timezone. Perhaps the DST data is wrong.
- guess = findTimeZone(offset, !dst, when);
- }
- if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
- return guess;
- }
-
- private TimeZone findTimeZone(int offset, boolean dst, long when) {
- int rawOffset = offset;
- if (dst) {
- rawOffset -= 3600000;
- }
- String[] zones = TimeZone.getAvailableIDs(rawOffset);
- TimeZone guess = null;
- Date d = new Date(when);
- for (String zone : zones) {
- TimeZone tz = TimeZone.getTimeZone(zone);
- if (tz.getOffset(when) == offset &&
- tz.inDaylightTime(d) == dst) {
- guess = tz;
- break;
- }
- }
-
- return guess;
- }
-
- /**
- * TODO: This code is exactly the same as in GsmServiceStateTracker
- * and has a TODO to not poll signal strength if screen is off.
- * This code should probably be hoisted to the base class so
- * the fix, when added, works for both.
- */
- private void
- queueNextSignalStrengthPoll() {
- if (dontPollSignalStrength) {
- // The radio is telling us about signal strength changes
- // we don't have to ask it
- return;
- }
-
- Message msg;
-
- msg = obtainMessage();
- msg.what = EVENT_POLL_SIGNAL_STRENGTH;
-
- // TODO Don't poll signal strength if screen is off
- sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
- }
-
- /**
- * send signal-strength-changed notification if changed
- * Called both for solicited and unsolicited signal strength updates
- */
- protected void
- onSignalStrengthResult(AsyncResult ar) {
- SignalStrength oldSignalStrength = mSignalStrength;
-
- if (ar.exception != null) {
- // Most likely radio is resetting/disconnected change to default values.
- setSignalStrengthDefaultValues();
- } else {
- int[] ints = (int[])ar.result;
- int offset = 2;
- int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
- int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -160;
- int evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120;
- int evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1;
- int evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1;
-
- //log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d",
- // cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr));
- mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
- evdoRssi, evdoEcio, evdoSnr, false);
- }
-
- try {
- phone.notifySignalStrength();
- } catch (NullPointerException ex) {
- loge("onSignalStrengthResult() Phone already destroyed: " + ex
- + "SignalStrength not notified");
- }
- }
-
-
- protected int radioTechnologyToDataServiceState(int code) {
- int retVal = ServiceState.STATE_OUT_OF_SERVICE;
- switch(code) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- break;
- case 6: // RADIO_TECHNOLOGY_1xRTT
- case 7: // RADIO_TECHNOLOGY_EVDO_0
- case 8: // RADIO_TECHNOLOGY_EVDO_A
- case 12: // RADIO_TECHNOLOGY_EVDO_B
- case 13: // RADIO_TECHNOLOGY_EHRPD
- retVal = ServiceState.STATE_IN_SERVICE;
- break;
- default:
- loge("radioTechnologyToDataServiceState: Wrong radioTechnology code.");
- break;
- }
- return(retVal);
- }
-
- /** code is registration state 0-5 from TS 27.007 7.2 */
- protected int
- regCodeToServiceState(int code) {
- switch (code) {
- case 0: // Not searching and not registered
- return ServiceState.STATE_OUT_OF_SERVICE;
- case 1:
- return ServiceState.STATE_IN_SERVICE;
- case 2: // 2 is "searching", fall through
- case 3: // 3 is "registration denied", fall through
- case 4: // 4 is "unknown", not valid in current baseband
- return ServiceState.STATE_OUT_OF_SERVICE;
- case 5:// 5 is "Registered, roaming"
- return ServiceState.STATE_IN_SERVICE;
-
- default:
- loge("regCodeToServiceState: unexpected service state " + code);
- return ServiceState.STATE_OUT_OF_SERVICE;
- }
- }
-
- public int getCurrentDataConnectionState() {
- return mDataConnectionState;
- }
-
- /**
- * code is registration state 0-5 from TS 27.007 7.2
- * returns true if registered roam, false otherwise
- */
- private boolean
- regCodeIsRoaming (int code) {
- // 5 is "in service -- roam"
- return 5 == code;
- }
-
- /**
- * Determine whether a roaming indicator is in the carrier-specified list of ERIs for
- * home system
- *
- * @param roamInd roaming indicator in String
- * @return true if the roamInd is in the carrier-specified list of ERIs for home network
- */
- private boolean isRoamIndForHomeSystem(String roamInd) {
- // retrieve the carrier-specified list of ERIs for home system
- String homeRoamIndicators = SystemProperties.get("ro.cdma.homesystem");
-
- if (!TextUtils.isEmpty(homeRoamIndicators)) {
- // searches through the comma-separated list for a match,
- // return true if one is found.
- for (String homeRoamInd : homeRoamIndicators.split(",")) {
- if (homeRoamInd.equals(roamInd)) {
- return true;
- }
- }
- // no matches found against the list!
- return false;
- }
-
- // no system property found for the roaming indicators for home system
- return false;
- }
-
- /**
- * Set roaming state when cdmaRoaming is true and ons is different from spn
- * @param cdmaRoaming TS 27.007 7.2 CREG registered roaming
- * @param s ServiceState hold current ons
- * @return true for roaming state set
- */
- private
- boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) {
- String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
-
- // NOTE: in case of RUIM we should completely ignore the ERI data file and
- // mOperatorAlphaLong is set from RIL_REQUEST_OPERATOR response 0 (alpha ONS)
- String onsl = s.getOperatorAlphaLong();
- String onss = s.getOperatorAlphaShort();
-
- boolean equalsOnsl = onsl != null && spn.equals(onsl);
- boolean equalsOnss = onss != null && spn.equals(onss);
-
- return cdmaRoaming && !(equalsOnsl || equalsOnss);
- }
-
-
- /**
- * nitzReceiveTime is time_t that the NITZ time was posted
- */
-
- private
- void setTimeFromNITZString (String nitz, long nitzReceiveTime)
- {
- // "yy/mm/dd,hh:mm:ss(+/-)tz"
- // tz is in number of quarter-hours
-
- long start = SystemClock.elapsedRealtime();
- if (DBG) {
- log("NITZ: " + nitz + "," + nitzReceiveTime +
- " start=" + start + " delay=" + (start - nitzReceiveTime));
- }
-
- try {
- /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
- * offset as well (which we won't worry about until later) */
- Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
-
- c.clear();
- c.set(Calendar.DST_OFFSET, 0);
-
- String[] nitzSubs = nitz.split("[/:,+-]");
-
- int year = 2000 + Integer.parseInt(nitzSubs[0]);
- c.set(Calendar.YEAR, year);
-
- // month is 0 based!
- int month = Integer.parseInt(nitzSubs[1]) - 1;
- c.set(Calendar.MONTH, month);
-
- int date = Integer.parseInt(nitzSubs[2]);
- c.set(Calendar.DATE, date);
-
- int hour = Integer.parseInt(nitzSubs[3]);
- c.set(Calendar.HOUR, hour);
-
- int minute = Integer.parseInt(nitzSubs[4]);
- c.set(Calendar.MINUTE, minute);
-
- int second = Integer.parseInt(nitzSubs[5]);
- c.set(Calendar.SECOND, second);
-
- boolean sign = (nitz.indexOf('-') == -1);
-
- int tzOffset = Integer.parseInt(nitzSubs[6]);
-
- int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
- : 0;
-
- // The zone offset received from NITZ is for current local time,
- // so DST correction is already applied. Don't add it again.
- //
- // tzOffset += dst * 4;
- //
- // We could unapply it if we wanted the raw offset.
-
- tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
-
- TimeZone zone = null;
-
- // As a special extension, the Android emulator appends the name of
- // the host computer's timezone to the nitz string. this is zoneinfo
- // timezone name of the form Area!Location or Area!Location!SubLocation
- // so we need to convert the ! into /
- if (nitzSubs.length >= 9) {
- String tzname = nitzSubs[8].replace('!','/');
- zone = TimeZone.getTimeZone( tzname );
- }
-
- String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
-
- if (zone == null) {
- if (mGotCountryCode) {
- if (iso != null && iso.length() > 0) {
- zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
- c.getTimeInMillis(),
- iso);
- } else {
- // We don't have a valid iso country code. This is
- // most likely because we're on a test network that's
- // using a bogus MCC (eg, "001"), so get a TimeZone
- // based only on the NITZ parameters.
- zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
- }
- }
- }
-
- if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
- // We got the time before the country or the zone has changed
- // so we don't know how to identify the DST rules yet. Save
- // the information and hope to fix it up later.
-
- mNeedFixZone = true;
- mZoneOffset = tzOffset;
- mZoneDst = dst != 0;
- mZoneTime = c.getTimeInMillis();
- }
- if (DBG) {
- log("NITZ: tzOffset=" + tzOffset + " dst=" + dst + " zone=" +
- (zone!=null ? zone.getID() : "NULL") +
- " iso=" + iso + " mGotCountryCode=" + mGotCountryCode +
- " mNeedFixZone=" + mNeedFixZone);
- }
-
- if (zone != null) {
- if (getAutoTimeZone()) {
- setAndBroadcastNetworkSetTimeZone(zone.getID());
- }
- saveNitzTimeZone(zone.getID());
- }
-
- String ignore = SystemProperties.get("gsm.ignore-nitz");
- if (ignore != null && ignore.equals("yes")) {
- if (DBG) log("NITZ: Not setting clock because gsm.ignore-nitz is set");
- return;
- }
-
- try {
- mWakeLock.acquire();
-
- /**
- * Correct the NITZ time by how long its taken to get here.
- */
- long millisSinceNitzReceived
- = SystemClock.elapsedRealtime() - nitzReceiveTime;
-
- if (millisSinceNitzReceived < 0) {
- // Sanity check: something is wrong
- if (DBG) {
- log("NITZ: not setting time, clock has rolled "
- + "backwards since NITZ time was received, "
- + nitz);
- }
- return;
- }
-
- if (millisSinceNitzReceived > Integer.MAX_VALUE) {
- // If the time is this far off, something is wrong > 24 days!
- if (DBG) {
- log("NITZ: not setting time, processing has taken "
- + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
- + " days");
- }
- return;
- }
-
- // Note: with range checks above, cast to int is safe
- c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
-
- if (getAutoTime()) {
- /**
- * Update system time automatically
- */
- long gained = c.getTimeInMillis() - System.currentTimeMillis();
- long timeSinceLastUpdate = SystemClock.elapsedRealtime() - mSavedAtTime;
- int nitzUpdateSpacing = Settings.Secure.getInt(cr,
- Settings.Secure.NITZ_UPDATE_SPACING, mNitzUpdateSpacing);
- int nitzUpdateDiff = Settings.Secure.getInt(cr,
- Settings.Secure.NITZ_UPDATE_DIFF, mNitzUpdateDiff);
-
- if ((mSavedAtTime == 0) || (timeSinceLastUpdate > nitzUpdateSpacing)
- || (Math.abs(gained) > nitzUpdateDiff)) {
- if (DBG) {
- log("NITZ: Auto updating time of day to " + c.getTime()
- + " NITZ receive delay=" + millisSinceNitzReceived
- + "ms gained=" + gained + "ms from " + nitz);
- }
-
- setAndBroadcastNetworkSetTime(c.getTimeInMillis());
- } else {
- if (DBG) {
- log("NITZ: ignore, a previous update was "
- + timeSinceLastUpdate + "ms ago and gained=" + gained + "ms");
- }
- return;
- }
- }
-
- /**
- * Update properties and save the time we did the update
- */
- if (DBG) log("NITZ: update nitz time property");
- SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
- mSavedTime = c.getTimeInMillis();
- mSavedAtTime = SystemClock.elapsedRealtime();
- } finally {
- long end = SystemClock.elapsedRealtime();
- if (DBG) log("NITZ: end=" + end + " dur=" + (end - start));
- mWakeLock.release();
- }
- } catch (RuntimeException ex) {
- loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
- }
- }
-
- private boolean getAutoTime() {
- try {
- return Settings.System.getInt(cr, Settings.System.AUTO_TIME) > 0;
- } catch (SettingNotFoundException snfe) {
- return true;
- }
- }
-
- private boolean getAutoTimeZone() {
- try {
- return Settings.System.getInt(cr, Settings.System.AUTO_TIME_ZONE) > 0;
- } catch (SettingNotFoundException snfe) {
- return true;
- }
- }
-
- private void saveNitzTimeZone(String zoneId) {
- mSavedTimeZone = zoneId;
- }
-
- /**
- * Set the timezone and send out a sticky broadcast so the system can
- * determine if the timezone was set by the carrier.
- *
- * @param zoneId timezone set by carrier
- */
- private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
- if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
- AlarmManager alarm =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
- alarm.setTimeZone(zoneId);
- Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra("time-zone", zoneId);
- phone.getContext().sendStickyBroadcast(intent);
- }
-
- /**
- * Set the time and Send out a sticky broadcast so the system can determine
- * if the time was set by the carrier.
- *
- * @param time time set by network
- */
- private void setAndBroadcastNetworkSetTime(long time) {
- if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
- SystemClock.setCurrentTimeMillis(time);
- Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra("time", time);
- phone.getContext().sendStickyBroadcast(intent);
- }
-
- private void revertToNitzTime() {
- if (Settings.System.getInt(cr, Settings.System.AUTO_TIME, 0) == 0) {
- return;
- }
- if (DBG) {
- log("revertToNitzTime: mSavedTime=" + mSavedTime + " mSavedAtTime=" + mSavedAtTime);
- }
- if (mSavedTime != 0 && mSavedAtTime != 0) {
- setAndBroadcastNetworkSetTime(mSavedTime
- + (SystemClock.elapsedRealtime() - mSavedAtTime));
- }
- }
-
- private void revertToNitzTimeZone() {
- if (Settings.System.getInt(phone.getContext().getContentResolver(),
- Settings.System.AUTO_TIME_ZONE, 0) == 0) {
- return;
- }
- if (DBG) log("revertToNitzTimeZone: tz='" + mSavedTimeZone);
- if (mSavedTimeZone != null) {
- setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
- }
- }
-
- protected boolean isSidsAllZeros() {
- if (mHomeSystemId != null) {
- for (int i=0; i < mHomeSystemId.length; i++) {
- if (mHomeSystemId[i] != 0) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Check whether a specified system ID that matches one of the home system IDs.
- */
- private boolean isHomeSid(int sid) {
- if (mHomeSystemId != null) {
- for (int i=0; i < mHomeSystemId.length; i++) {
- if (sid == mHomeSystemId[i]) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * @return true if phone is camping on a technology
- * that could support voice and data simultaneously.
- */
- public boolean isConcurrentVoiceAndDataAllowed() {
- // Note: it needs to be confirmed which CDMA network types
- // can support voice and data calls concurrently.
- // For the time-being, the return value will be false.
- return false;
- }
-
- public String getMdnNumber() {
- return mMdn;
- }
-
- public String getCdmaMin() {
- return mMin;
- }
-
- /** Returns null if NV is not yet ready */
- public String getPrlVersion() {
- return mPrlVersion;
- }
-
- /**
- * Returns IMSI as MCC + MNC + MIN
- */
- String getImsi() {
- // TODO: When RUIM is enabled, IMSI will come from RUIM not build-time props.
- String operatorNumeric = SystemProperties.get(
- TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
-
- if (!TextUtils.isEmpty(operatorNumeric) && getCdmaMin() != null) {
- return (operatorNumeric + getCdmaMin());
- } else {
- return null;
- }
- }
-
- /**
- * Check if subscription data has been assigned to mMin
- *
- * return true if MIN info is ready; false otherwise.
- */
- public boolean isMinInfoReady() {
- return mIsMinInfoReady;
- }
-
- /**
- * Returns OTASP_UNKNOWN, OTASP_NEEDED or OTASP_NOT_NEEDED
- */
- int getOtasp() {
- int provisioningState;
- if (mMin == null || (mMin.length() < 6)) {
- if (DBG) log("getOtasp: bad mMin='" + mMin + "'");
- provisioningState = OTASP_UNKNOWN;
- } else {
- if ((mMin.equals(UNACTIVATED_MIN_VALUE)
- || mMin.substring(0,6).equals(UNACTIVATED_MIN2_VALUE))
- || SystemProperties.getBoolean("test_cdma_setup", false)) {
- provisioningState = OTASP_NEEDED;
- } else {
- provisioningState = OTASP_NOT_NEEDED;
- }
- }
- if (DBG) log("getOtasp: state=" + provisioningState);
- return provisioningState;
- }
-
- @Override
- protected void hangupAndPowerOff() {
- // hang up all active voice calls
- phone.mCT.ringingCall.hangupIfAlive();
- phone.mCT.backgroundCall.hangupIfAlive();
- phone.mCT.foregroundCall.hangupIfAlive();
- cm.setRadioPower(false, null);
- }
-
- protected void parseSidNid (String sidStr, String nidStr) {
- if (sidStr != null) {
- String[] sid = sidStr.split(",");
- mHomeSystemId = new int[sid.length];
- for (int i = 0; i < sid.length; i++) {
- try {
- mHomeSystemId[i] = Integer.parseInt(sid[i]);
- } catch (NumberFormatException ex) {
- loge("error parsing system id: " + ex);
- }
- }
- }
- if (DBG) log("CDMA_SUBSCRIPTION: SID=" + sidStr);
-
- if (nidStr != null) {
- String[] nid = nidStr.split(",");
- mHomeNetworkId = new int[nid.length];
- for (int i = 0; i < nid.length; i++) {
- try {
- mHomeNetworkId[i] = Integer.parseInt(nid[i]);
- } catch (NumberFormatException ex) {
- loge("CDMA_SUBSCRIPTION: error parsing network id: " + ex);
- }
- }
- }
- if (DBG) log("CDMA_SUBSCRIPTION: NID=" + nidStr);
- }
-
- protected void updateOtaspState() {
- int otaspMode = getOtasp();
- int oldOtaspMode = mCurrentOtaspMode;
- mCurrentOtaspMode = otaspMode;
-
- // Notify apps subscription info is ready
- if (cdmaForSubscriptionInfoReadyRegistrants != null) {
- if (DBG) log("CDMA_SUBSCRIPTION: call notifyRegistrants()");
- cdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants();
- }
- if (oldOtaspMode != mCurrentOtaspMode) {
- if (DBG) {
- log("CDMA_SUBSCRIPTION: call notifyOtaspChanged old otaspMode=" +
- oldOtaspMode + " new otaspMode=" + mCurrentOtaspMode);
- }
- phone.notifyOtaspChanged(mCurrentOtaspMode);
- }
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[CdmaSST] " + s);
- }
-
- @Override
- protected void loge(String s) {
- Log.e(LOG_TAG, "[CdmaSST] " + s);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("CdmaServiceStateTracker extends:");
- super.dump(fd, pw, args);
- pw.println(" phone=" + phone);
- pw.println(" cellLoc=" + cellLoc);
- pw.println(" newCellLoc=" + newCellLoc);
- pw.println(" mCurrentOtaspMode=" + mCurrentOtaspMode);
- pw.println(" mCdmaRoaming=" + mCdmaRoaming);
- pw.println(" mRoamingIndicator=" + mRoamingIndicator);
- pw.println(" mIsInPrl=" + mIsInPrl);
- pw.println(" mDefaultRoamingIndicator=" + mDefaultRoamingIndicator);
- pw.println(" mDataConnectionState=" + mDataConnectionState);
- pw.println(" mNewDataConnectionState=" + mNewDataConnectionState);
- pw.println(" mRegistrationState=" + mRegistrationState);
- pw.println(" mNeedFixZone=" + mNeedFixZone);
- pw.println(" mZoneOffset=" + mZoneOffset);
- pw.println(" mZoneDst=" + mZoneDst);
- pw.println(" mZoneTime=" + mZoneTime);
- pw.println(" mGotCountryCode=" + mGotCountryCode);
- pw.println(" mSavedTimeZone=" + mSavedTimeZone);
- pw.println(" mSavedTime=" + mSavedTime);
- pw.println(" mSavedAtTime=" + mSavedAtTime);
- pw.println(" mNeedToRegForRuimLoaded=" + mNeedToRegForRuimLoaded);
- pw.println(" mWakeLock=" + mWakeLock);
- pw.println(" mCurPlmn=" + mCurPlmn);
- pw.println(" mMdn=" + mMdn);
- pw.println(" mHomeSystemId=" + mHomeSystemId);
- pw.println(" mHomeNetworkId=" + mHomeNetworkId);
- pw.println(" mMin=" + mMin);
- pw.println(" mPrlVersion=" + mPrlVersion);
- pw.println(" mIsMinInfoReady=" + mIsMinInfoReady);
- pw.println(" isEriTextLoaded=" + isEriTextLoaded);
- pw.println(" isSubscriptionFromRuim=" + isSubscriptionFromRuim);
- pw.println(" mCdmaSSM=" + mCdmaSSM);
- pw.println(" mRegistrationDeniedReason=" + mRegistrationDeniedReason);
- pw.println(" currentCarrier=" + currentCarrier);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
deleted file mode 100644
index 80af9d4..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (c) 2011 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.cdma;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.RILConstants;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.provider.Settings;
-import android.util.Log;
-
-/**
- * Class that handles the CDMA subscription source changed events from RIL
- */
-public class CdmaSubscriptionSourceManager extends Handler {
- static final String LOG_TAG = "CDMA";
- private static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1;
- private static final int EVENT_GET_CDMA_SUBSCRIPTION_SOURCE = 2;
- private static final int EVENT_RADIO_ON = 3;
-
- public static final int SUBSCRIPTION_SOURCE_UNKNOWN = -1;
- public static final int SUBSCRIPTION_FROM_RUIM = 0; /* CDMA subscription from RUIM */
- public static final int SUBSCRIPTION_FROM_NV = 1; /* CDMA subscription from NV */
- public static final int PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_NV;
-
- private static CdmaSubscriptionSourceManager sInstance;
- private static final Object sReferenceCountMonitor = new Object();
- private static int sReferenceCount = 0;
-
- // ***** Instance Variables
- private CommandsInterface mCM;
- private Context mContext;
- private RegistrantList mCdmaSubscriptionSourceChangedRegistrants = new RegistrantList();
-
- // Type of CDMA subscription source
- private AtomicInteger mCdmaSubscriptionSource = new AtomicInteger(SUBSCRIPTION_FROM_NV);
-
- // Constructor
- private CdmaSubscriptionSourceManager(Context context, CommandsInterface ci) {
- mContext = context;
- mCM = ci;
- mCM.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
- mCM.registerForOn(this, EVENT_RADIO_ON, null);
- int subscriptionSource = getDefaultCdmaSubscriptionSource();
- mCdmaSubscriptionSource.set(subscriptionSource);
- }
-
- /**
- * This function creates a single instance of this class
- *
- * @return object of type CdmaSubscriptionSourceManager
- */
- public static CdmaSubscriptionSourceManager getInstance(Context context,
- CommandsInterface ci, Handler h, int what, Object obj) {
- synchronized (sReferenceCountMonitor) {
- if (null == sInstance) {
- sInstance = new CdmaSubscriptionSourceManager(context, ci);
- }
- sInstance.sReferenceCount++;
- }
- sInstance.registerForCdmaSubscriptionSourceChanged(h, what, obj);
- return sInstance;
- }
-
- /**
- * Unregisters for the registered event with RIL
- */
- public void dispose(Handler h) {
- mCdmaSubscriptionSourceChangedRegistrants.remove(h);
- synchronized (sReferenceCountMonitor) {
- sReferenceCount--;
- if (sReferenceCount <= 0) {
- mCM.unregisterForCdmaSubscriptionChanged(this);
- mCM.unregisterForOn(this);
- sInstance = null;
- }
- }
- }
-
- /*
- * (non-Javadoc)
- * @see android.os.Handler#handleMessage(android.os.Message)
- */
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
- switch (msg.what) {
- case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
- case EVENT_GET_CDMA_SUBSCRIPTION_SOURCE:
- {
- log("CDMA_SUBSCRIPTION_SOURCE event = " + msg.what);
- ar = (AsyncResult) msg.obj;
- handleGetCdmaSubscriptionSource(ar);
- }
- break;
- case EVENT_RADIO_ON: {
- mCM.getCdmaSubscriptionSource(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_SOURCE));
- }
- break;
- default:
- super.handleMessage(msg);
- }
- }
-
- /**
- * Returns the current CDMA subscription source value
- * @return CDMA subscription source value
- */
- public int getCdmaSubscriptionSource() {
- return mCdmaSubscriptionSource.get();
- }
-
- /**
- * Gets the default CDMA subscription source
- *
- * @return Default CDMA subscription source from Settings DB if present.
- */
- private int getDefaultCdmaSubscriptionSource() {
- // Get the default value from the Settings
- int subscriptionSource = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.CDMA_SUBSCRIPTION_MODE, PREFERRED_CDMA_SUBSCRIPTION);
- return subscriptionSource;
- }
-
- /**
- * Clients automatically register for CDMA subscription source changed event
- * when they get an instance of this object.
- */
- private void registerForCdmaSubscriptionSourceChanged(Handler h, int what, Object obj) {
- Registrant r = new Registrant (h, what, obj);
- mCdmaSubscriptionSourceChangedRegistrants.add(r);
- }
-
- /**
- * Handles the call to get the subscription source
- *
- * @param ar AsyncResult object that contains the result of get CDMA
- * subscription source call
- */
- private void handleGetCdmaSubscriptionSource(AsyncResult ar) {
- if ((ar.exception == null) && (ar.result != null)) {
- int newSubscriptionSource = ((int[]) ar.result)[0];
-
- if (newSubscriptionSource != mCdmaSubscriptionSource.get()) {
- log("Subscription Source Changed : " + mCdmaSubscriptionSource + " >> "
- + newSubscriptionSource);
- mCdmaSubscriptionSource.set(newSubscriptionSource);
-
- // Notify registrants of the new CDMA subscription source
- mCdmaSubscriptionSourceChangedRegistrants.notifyRegistrants(new AsyncResult(null,
- null, null));
- }
- } else {
- // GET_CDMA_SUBSCRIPTION is returning Failure. Probably
- // because modem created GSM Phone. If modem created
- // GSMPhone, then PhoneProxy will trigger a change in
- // Phone objects and this object will be destroyed.
- logw("Unable to get CDMA Subscription Source, Exception: " + ar.exception
- + ", result: " + ar.result);
- }
- }
-
- private void log(String s) {
- Log.d(LOG_TAG, "[CdmaSSM] " + s);
- }
-
- private void loge(String s) {
- Log.e(LOG_TAG, "[CdmaSSM] " + s);
- }
-
- private void logw(String s) {
- Log.w(LOG_TAG, "[CdmaSSM] " + s);
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriInfo.java b/telephony/java/com/android/internal/telephony/cdma/EriInfo.java
deleted file mode 100644
index 3e5d37e..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/EriInfo.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2009 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.cdma;
-
-public final class EriInfo {
-
- public static final int ROAMING_INDICATOR_ON = 0;
- public static final int ROAMING_INDICATOR_OFF = 1;
- public static final int ROAMING_INDICATOR_FLASH = 2;
-
- public static final int ROAMING_ICON_MODE_NORMAL = 0;
- public static final int ROAMING_ICON_MODE_FLASH = 1;
-
- public int mRoamingIndicator;
- public int mIconIndex;
- public int mIconMode;
- public String mEriText;
- public int mCallPromptId;
- public int mAlertId;
-
- public EriInfo (int roamingIndicator, int iconIndex, int iconMode, String eriText,
- int callPromptId, int alertId) {
-
- this.mRoamingIndicator = roamingIndicator;
- this.mIconIndex = iconIndex;
- this.mIconMode = iconMode;
- this.mEriText = eriText;
- this.mCallPromptId = callPromptId;
- this.mAlertId = alertId;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
deleted file mode 100644
index 1bcc90a..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/EriManager.java
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * Copyright (C) 2009 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.cdma;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.os.Message;
-import android.util.Log;
-import android.util.Xml;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.util.XmlUtils;
-
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.HashMap;
-
-/**
- * EriManager loads the ERI file definitions and manages the CDMA roaming information.
- *
- */
-public final class EriManager {
-
- class EriFile {
-
- public int mVersionNumber; // File version number
- public int mNumberOfEriEntries; // Number of entries
- public int mEriFileType; // Eri Phase 0/1
- //public int mNumberOfIconImages; // reserved for future use
- //public int mIconImageType; // reserved for future use
- public String[] mCallPromptId; // reserved for future use
- public HashMap<Integer, EriInfo> mRoamIndTable; // Roaming Indicator Table
-
- public EriFile() {
- this.mVersionNumber = -1;
- this.mNumberOfEriEntries = 0;
- this.mEriFileType = -1;
- this.mCallPromptId = new String[] { "", "", "" };
- this.mRoamIndTable = new HashMap<Integer, EriInfo>();
- }
- }
-
- class EriDisplayInformation {
- public int mEriIconIndex;
- public int mEriIconMode;
- public String mEriIconText;
-
- public EriDisplayInformation(int eriIconIndex, int eriIconMode, String eriIconText) {
- mEriIconIndex = eriIconIndex;
- mEriIconMode = eriIconMode;
- mEriIconText = eriIconText;
- }
-
-// public void setParameters(int eriIconIndex, int eriIconMode, String eriIconText){
-// this.mEriIconIndex = eriIconIndex;
-// this.mEriIconMode = eriIconMode;
-// this.mEriIconText = eriIconText;
-// }
-
- @Override
- public String toString() {
- return "EriDisplayInformation: {" + " IconIndex: " + mEriIconIndex + " EriIconMode: "
- + mEriIconMode + " EriIconText: " + mEriIconText + " }";
- }
- }
-
- private static final String LOG_TAG = "CDMA";
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
-
- public static final int ERI_FROM_XML = 0;
- public static final int ERI_FROM_FILE_SYSTEM = 1;
- public static final int ERI_FROM_MODEM = 2;
-
- private PhoneBase mPhone;
- private Context mContext;
- private int mEriFileSource = ERI_FROM_XML;
- private boolean isEriFileLoaded;
- private EriFile mEriFile;
-
- public EriManager(PhoneBase phone, Context context, int eriFileSource) {
- this.mPhone = phone;
- this.mContext = context;
- this.mEriFileSource = eriFileSource;
- this.mEriFile = new EriFile();
- }
-
- public void dispose() {
- mEriFile = new EriFile();
- isEriFileLoaded = false;
- }
-
-
- public void loadEriFile() {
- switch (mEriFileSource) {
- case ERI_FROM_MODEM:
- loadEriFileFromModem();
- break;
-
- case ERI_FROM_FILE_SYSTEM:
- loadEriFileFromFileSystem();
- break;
-
- case ERI_FROM_XML:
- default:
- loadEriFileFromXml();
- break;
- }
- }
-
- /**
- * Load the ERI file from the MODEM through chipset specific RIL_REQUEST_OEM_HOOK
- *
- * In this case the ERI file can be updated from the Phone Support Tool available
- * from the Chipset vendor
- */
- private void loadEriFileFromModem() {
- // NOT IMPLEMENTED, Chipset vendor/Operator specific
- }
-
- /**
- * Load the ERI file from a File System file
- *
- * In this case the a Phone Support Tool to update the ERI file must be provided
- * to the Operator
- */
- private void loadEriFileFromFileSystem() {
- // NOT IMPLEMENTED, Chipset vendor/Operator specific
- }
-
- /**
- * Load the ERI file from the application framework resources encoded in XML
- *
- */
- private void loadEriFileFromXml() {
- XmlPullParser parser = null;
- FileInputStream stream = null;
- Resources r = mContext.getResources();
-
- try {
- if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: check for alternate file");
- stream = new FileInputStream(
- r.getString(com.android.internal.R.string.alternate_eri_file));
- parser = Xml.newPullParser();
- parser.setInput(stream, null);
- if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: opened alternate file");
- } catch (FileNotFoundException e) {
- if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no alternate file");
- parser = null;
- } catch (XmlPullParserException e) {
- if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no parser for alternate file");
- parser = null;
- }
-
- if (parser == null) {
- if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: open normal file");
- parser = r.getXml(com.android.internal.R.xml.eri);
- }
-
- try {
- XmlUtils.beginDocument(parser, "EriFile");
- mEriFile.mVersionNumber = Integer.parseInt(
- parser.getAttributeValue(null, "VersionNumber"));
- mEriFile.mNumberOfEriEntries = Integer.parseInt(
- parser.getAttributeValue(null, "NumberOfEriEntries"));
- mEriFile.mEriFileType = Integer.parseInt(
- parser.getAttributeValue(null, "EriFileType"));
-
- int parsedEriEntries = 0;
- while(true) {
- XmlUtils.nextElement(parser);
- String name = parser.getName();
- if (name == null) {
- if (parsedEriEntries != mEriFile.mNumberOfEriEntries)
- Log.e(LOG_TAG, "Error Parsing ERI file: " + mEriFile.mNumberOfEriEntries
- + " defined, " + parsedEriEntries + " parsed!");
- break;
- } else if (name.equals("CallPromptId")) {
- int id = Integer.parseInt(parser.getAttributeValue(null, "Id"));
- String text = parser.getAttributeValue(null, "CallPromptText");
- if (id >= 0 && id <= 2) {
- mEriFile.mCallPromptId[id] = text;
- } else {
- Log.e(LOG_TAG, "Error Parsing ERI file: found" + id + " CallPromptId");
- }
-
- } else if (name.equals("EriInfo")) {
- int roamingIndicator = Integer.parseInt(
- parser.getAttributeValue(null, "RoamingIndicator"));
- int iconIndex = Integer.parseInt(parser.getAttributeValue(null, "IconIndex"));
- int iconMode = Integer.parseInt(parser.getAttributeValue(null, "IconMode"));
- String eriText = parser.getAttributeValue(null, "EriText");
- int callPromptId = Integer.parseInt(
- parser.getAttributeValue(null, "CallPromptId"));
- int alertId = Integer.parseInt(parser.getAttributeValue(null, "AlertId"));
- parsedEriEntries++;
- mEriFile.mRoamIndTable.put(roamingIndicator, new EriInfo (roamingIndicator,
- iconIndex, iconMode, eriText, callPromptId, alertId));
- }
- }
-
- if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: eri parsing successful, file loaded");
- isEriFileLoaded = true;
-
- } catch (Exception e) {
- Log.e(LOG_TAG, "Got exception while loading ERI file.", e);
- } finally {
- if (parser instanceof XmlResourceParser) {
- ((XmlResourceParser)parser).close();
- }
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException e) {
- // Ignore
- }
- }
- }
-
- /**
- * Returns the version of the ERI file
- *
- */
- public int getEriFileVersion() {
- return mEriFile.mVersionNumber;
- }
-
- /**
- * Returns the number of ERI entries parsed
- *
- */
- public int getEriNumberOfEntries() {
- return mEriFile.mNumberOfEriEntries;
- }
-
- /**
- * Returns the ERI file type value ( 0 for Phase 0, 1 for Phase 1)
- *
- */
- public int getEriFileType() {
- return mEriFile.mEriFileType;
- }
-
- /**
- * Returns if the ERI file has been loaded
- *
- */
- public boolean isEriFileLoaded() {
- return isEriFileLoaded;
- }
-
- /**
- * Returns the EriInfo record associated with roamingIndicator
- * or null if the entry is not found
- */
- private EriInfo getEriInfo(int roamingIndicator) {
- if (mEriFile.mRoamIndTable.containsKey(roamingIndicator)) {
- return mEriFile.mRoamIndTable.get(roamingIndicator);
- } else {
- return null;
- }
- }
-
- private EriDisplayInformation getEriDisplayInformation(int roamInd, int defRoamInd){
- EriDisplayInformation ret;
-
- // Carrier can use eri.xml to customize any built-in roaming display indications
- if (isEriFileLoaded) {
- EriInfo eriInfo = getEriInfo(roamInd);
- if (eriInfo != null) {
- if (VDBG) Log.v(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file");
- ret = new EriDisplayInformation(
- eriInfo.mIconIndex,
- eriInfo.mIconMode,
- eriInfo.mEriText);
- return ret;
- }
- }
-
- switch (roamInd) {
- // Handling the standard roaming indicator (non-ERI)
- case EriInfo.ROAMING_INDICATOR_ON:
- ret = new EriDisplayInformation(
- EriInfo.ROAMING_INDICATOR_ON,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText0).toString());
- break;
-
- case EriInfo.ROAMING_INDICATOR_OFF:
- ret = new EriDisplayInformation(
- EriInfo.ROAMING_INDICATOR_OFF,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText1).toString());
- break;
-
- case EriInfo.ROAMING_INDICATOR_FLASH:
- ret = new EriDisplayInformation(
- EriInfo.ROAMING_INDICATOR_FLASH,
- EriInfo.ROAMING_ICON_MODE_FLASH,
- mContext.getText(com.android.internal.R.string.roamingText2).toString());
- break;
-
-
- // Handling the standard ERI
- case 3:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText3).toString());
- break;
-
- case 4:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText4).toString());
- break;
-
- case 5:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText5).toString());
- break;
-
- case 6:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText6).toString());
- break;
-
- case 7:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText7).toString());
- break;
-
- case 8:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText8).toString());
- break;
-
- case 9:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText9).toString());
- break;
-
- case 10:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText10).toString());
- break;
-
- case 11:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText11).toString());
- break;
-
- case 12:
- ret = new EriDisplayInformation(
- roamInd,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal.R.string.roamingText12).toString());
- break;
-
- // Handling the non standard Enhanced Roaming Indicator (roamInd > 63)
- default:
- if (!isEriFileLoaded) {
- // ERI file NOT loaded
- if (DBG) Log.d(LOG_TAG, "ERI File not loaded");
- if(defRoamInd > 2) {
- if (VDBG) Log.v(LOG_TAG, "ERI defRoamInd > 2 ...flashing");
- ret = new EriDisplayInformation(
- EriInfo.ROAMING_INDICATOR_FLASH,
- EriInfo.ROAMING_ICON_MODE_FLASH,
- mContext.getText(com.android.internal
- .R.string.roamingText2).toString());
- } else {
- if (VDBG) Log.v(LOG_TAG, "ERI defRoamInd <= 2");
- switch (defRoamInd) {
- case EriInfo.ROAMING_INDICATOR_ON:
- ret = new EriDisplayInformation(
- EriInfo.ROAMING_INDICATOR_ON,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal
- .R.string.roamingText0).toString());
- break;
-
- case EriInfo.ROAMING_INDICATOR_OFF:
- ret = new EriDisplayInformation(
- EriInfo.ROAMING_INDICATOR_OFF,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal
- .R.string.roamingText1).toString());
- break;
-
- case EriInfo.ROAMING_INDICATOR_FLASH:
- ret = new EriDisplayInformation(
- EriInfo.ROAMING_INDICATOR_FLASH,
- EriInfo.ROAMING_ICON_MODE_FLASH,
- mContext.getText(com.android.internal
- .R.string.roamingText2).toString());
- break;
-
- default:
- ret = new EriDisplayInformation(-1, -1, "ERI text");
- }
- }
- } else {
- // ERI file loaded
- EriInfo eriInfo = getEriInfo(roamInd);
- EriInfo defEriInfo = getEriInfo(defRoamInd);
- if (eriInfo == null) {
- if (VDBG) {
- Log.v(LOG_TAG, "ERI roamInd " + roamInd
- + " not found in ERI file ...using defRoamInd " + defRoamInd);
- }
- if(defEriInfo == null) {
- Log.e(LOG_TAG, "ERI defRoamInd " + defRoamInd
- + " not found in ERI file ...on");
- ret = new EriDisplayInformation(
- EriInfo.ROAMING_INDICATOR_ON,
- EriInfo.ROAMING_ICON_MODE_NORMAL,
- mContext.getText(com.android.internal
- .R.string.roamingText0).toString());
-
- } else {
- if (VDBG) {
- Log.v(LOG_TAG, "ERI defRoamInd " + defRoamInd + " found in ERI file");
- }
- ret = new EriDisplayInformation(
- defEriInfo.mIconIndex,
- defEriInfo.mIconMode,
- defEriInfo.mEriText);
- }
- } else {
- if (VDBG) Log.v(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file");
- ret = new EriDisplayInformation(
- eriInfo.mIconIndex,
- eriInfo.mIconMode,
- eriInfo.mEriText);
- }
- }
- break;
- }
- if (VDBG) Log.v(LOG_TAG, "Displaying ERI " + ret.toString());
- return ret;
- }
-
- public int getCdmaEriIconIndex(int roamInd, int defRoamInd){
- return getEriDisplayInformation(roamInd, defRoamInd).mEriIconIndex;
- }
-
- public int getCdmaEriIconMode(int roamInd, int defRoamInd){
- return getEriDisplayInformation(roamInd, defRoamInd).mEriIconMode;
- }
-
- public String getCdmaEriText(int roamInd, int defRoamInd){
- return getEriDisplayInformation(roamInd, defRoamInd).mEriIconText;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
deleted file mode 100644
index f440935..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-import android.os.*;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccException;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccFileTypeMismatch;
-import com.android.internal.telephony.IccIoResult;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.PhoneProxy;
-
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public final class RuimFileHandler extends IccFileHandler {
- static final String LOG_TAG = "CDMA";
-
- //***** Instance Variables
-
- //***** Constructor
- public RuimFileHandler(IccCard card, String aid, CommandsInterface ci) {
- super(card, aid, ci);
- }
-
- protected void finalize() {
- Log.d(LOG_TAG, "RuimFileHandler finalized");
- }
-
- //***** Overridden from IccFileHandler
-
- @Override
- public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset,
- int length, Message onLoaded) {
- Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0,
- onLoaded);
-
- mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, "img", 0, 0,
- GET_RESPONSE_EF_IMG_SIZE_BYTES, null, null,
- mAid, response);
- }
-
- @Override
- public void handleMessage(Message msg) {
-
- super.handleMessage(msg);
- }
-
- protected String getEFPath(int efid) {
- switch(efid) {
- case EF_SMS:
- case EF_CST:
- case EF_RUIM_SPN:
- return MF_SIM + DF_CDMA;
- }
- return getCommonIccEFPath(efid);
- }
-
- protected void logd(String msg) {
- Log.d(LOG_TAG, "[RuimFileHandler] " + msg);
- }
-
- protected void loge(String msg) {
- Log.e(LOG_TAG, "[RuimFileHandler] " + msg);
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
deleted file mode 100644
index 04ee2dd8..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-** 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
-**
-** 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.cdma;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-
-/**
- * RuimPhoneBookInterfaceManager to provide an inter-process communication to
- * access ADN-like SIM records.
- */
-
-
-public class RuimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
- static final String LOG_TAG = "CDMA";
-
- public RuimPhoneBookInterfaceManager(CDMAPhone phone) {
- super(phone);
- adnCache = phone.mIccRecords.getAdnCache();
- //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
- }
-
- public void dispose() {
- super.dispose();
- }
-
- protected void finalize() {
- try {
- super.finalize();
- } catch (Throwable throwable) {
- Log.e(LOG_TAG, "Error while finalizing:", throwable);
- }
- if(DBG) Log.d(LOG_TAG, "RuimPhoneBookInterfaceManager finalized");
- }
-
- public int[] getAdnRecordsSize(int efid) {
- if (DBG) logd("getAdnRecordsSize: efid=" + efid);
- synchronized(mLock) {
- checkThread();
- recordSize = new int[3];
-
- //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
- AtomicBoolean status = new AtomicBoolean(false);
- Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
-
- phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
- waitForResult(status);
- }
-
- return recordSize;
- }
-
- protected void logd(String msg) {
- Log.d(LOG_TAG, "[RuimPbInterfaceManager] " + msg);
- }
-
- protected void loge(String msg) {
- Log.e(LOG_TAG, "[RuimPbInterfaceManager] " + msg);
- }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
deleted file mode 100755
index 2fefa3f..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.AdnRecordCache;
-import com.android.internal.telephony.AdnRecordLoader;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccRefreshResponse;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.MccTable;
-
-// can't be used since VoiceMailConstants is not public
-//import com.android.internal.telephony.gsm.VoiceMailConstants;
-import com.android.internal.telephony.IccException;
-import com.android.internal.telephony.IccRecords;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneProxy;
-
-
-/**
- * {@hide}
- */
-public final class RuimRecords extends IccRecords {
- static final String LOG_TAG = "CDMA";
-
- private static final boolean DBG = true;
- private boolean m_ota_commited=false;
-
- // ***** Instance Variables
-
- private String mImsi;
- private String mMyMobileNumber;
- private String mMin2Min1;
-
- private String mPrlVersion;
-
- // ***** Event Constants
-
- private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
- private static final int EVENT_GET_IMSI_DONE = 3;
- private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4;
- private static final int EVENT_GET_ICCID_DONE = 5;
- private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10;
- private static final int EVENT_UPDATE_DONE = 14;
- private static final int EVENT_GET_SST_DONE = 17;
- private static final int EVENT_GET_ALL_SMS_DONE = 18;
- private static final int EVENT_MARK_SMS_READ_DONE = 19;
-
- private static final int EVENT_SMS_ON_RUIM = 21;
- private static final int EVENT_GET_SMS_DONE = 22;
-
- private static final int EVENT_RUIM_REFRESH = 31;
-
-
- public RuimRecords(IccCard card, Context c, CommandsInterface ci) {
- super(card, c, ci);
-
- adnCache = new AdnRecordCache(mFh);
-
- recordsRequested = false; // No load request is made till SIM ready
-
- // recordsToLoad is set to 0 because no requests are made yet
- recordsToLoad = 0;
-
- mCi.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- // NOTE the EVENT_SMS_ON_RUIM is not registered
- mCi.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null);
-
- // Start off by setting empty state
- onRadioOffOrNotAvailable();
-
- }
-
- @Override
- public void dispose() {
- if (DBG) log("Disposing RuimRecords " + this);
- //Unregister for all events
- mCi.unregisterForOffOrNotAvailable( this);
- mCi.unregisterForIccRefresh(this);
- super.dispose();
- }
-
- @Override
- protected void finalize() {
- if(DBG) log("RuimRecords finalized");
- }
-
- @Override
- protected void onRadioOffOrNotAvailable() {
- countVoiceMessages = 0;
- mncLength = UNINITIALIZED;
- iccid = null;
-
- adnCache.reset();
-
- // Don't clean up PROPERTY_ICC_OPERATOR_ISO_COUNTRY and
- // PROPERTY_ICC_OPERATOR_NUMERIC here. Since not all CDMA
- // devices have RUIM, these properties should keep the original
- // values, e.g. build time settings, when there is no RUIM but
- // set new values when RUIM is available and loaded.
-
- // recordsRequested is set to false indicating that the SIM
- // read requests made so far are not valid. This is set to
- // true only when fresh set of read requests are made.
- recordsRequested = false;
- }
-
- public String getMdnNumber() {
- return mMyMobileNumber;
- }
-
- public String getCdmaMin() {
- return mMin2Min1;
- }
-
- /** Returns null if RUIM is not yet ready */
- public String getPrlVersion() {
- return mPrlVersion;
- }
-
- @Override
- public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){
- // In CDMA this is Operator/OEM dependent
- AsyncResult.forMessage((onComplete)).exception =
- new IccException("setVoiceMailNumber not implemented");
- onComplete.sendToTarget();
- loge("method setVoiceMailNumber is not implemented");
- }
-
- /**
- * Called by CCAT Service when REFRESH is received.
- * @param fileChanged indicates whether any files changed
- * @param fileList if non-null, a list of EF files that changed
- */
- @Override
- public void onRefresh(boolean fileChanged, int[] fileList) {
- if (fileChanged) {
- // A future optimization would be to inspect fileList and
- // only reload those files that we care about. For now,
- // just re-fetch all RUIM records that we cache.
- fetchRuimRecords();
- }
- }
-
- /**
- * Returns the 5 or 6 digit MCC/MNC of the operator that
- * provided the RUIM card. Returns null of RUIM is not yet ready
- */
- public String getRUIMOperatorNumeric() {
- if (mImsi == null) {
- return null;
- }
-
- if (mncLength != UNINITIALIZED && mncLength != UNKNOWN) {
- // Length = length of MCC + length of MNC
- // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3)
- return mImsi.substring(0, 3 + mncLength);
- }
-
- // Guess the MNC length based on the MCC if we don't
- // have a valid value in ef[ad]
-
- int mcc = Integer.parseInt(mImsi.substring(0,3));
- return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
- }
-
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- byte data[];
-
- boolean isRecordLoadResponse = false;
-
- if (mDestroyed) {
- loge("Received message " + msg +
- "[" + msg.what + "] while being destroyed. Ignoring.");
- return;
- }
-
- try { switch (msg.what) {
- case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
- onRadioOffOrNotAvailable();
- break;
-
- case EVENT_GET_DEVICE_IDENTITY_DONE:
- log("Event EVENT_GET_DEVICE_IDENTITY_DONE Received");
- break;
-
- /* IO events */
- case EVENT_GET_IMSI_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- if (ar.exception != null) {
- loge("Exception querying IMSI, Exception:" + ar.exception);
- break;
- }
-
- mImsi = (String) ar.result;
-
- // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
- // than 15 (and usually 15).
- if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
- loge("invalid IMSI " + mImsi);
- mImsi = null;
- }
-
- log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx");
-
- String operatorNumeric = getRUIMOperatorNumeric();
- if (operatorNumeric != null) {
- if(operatorNumeric.length() <= 6){
- MccTable.updateMccMncConfiguration(mContext, operatorNumeric);
- }
- }
- break;
-
- case EVENT_GET_CDMA_SUBSCRIPTION_DONE:
- ar = (AsyncResult)msg.obj;
- String localTemp[] = (String[])ar.result;
- if (ar.exception != null) {
- break;
- }
-
- mMyMobileNumber = localTemp[0];
- mMin2Min1 = localTemp[3];
- mPrlVersion = localTemp[4];
-
- log("MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);
-
- break;
-
- case EVENT_GET_ICCID_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- iccid = IccUtils.bcdToString(data, 0, data.length);
-
- log("iccid: " + iccid);
-
- break;
-
- case EVENT_UPDATE_DONE:
- ar = (AsyncResult)msg.obj;
- if (ar.exception != null) {
- Log.i(LOG_TAG, "RuimRecords update failed", ar.exception);
- }
- break;
-
- case EVENT_GET_ALL_SMS_DONE:
- case EVENT_MARK_SMS_READ_DONE:
- case EVENT_SMS_ON_RUIM:
- case EVENT_GET_SMS_DONE:
- Log.w(LOG_TAG, "Event not supported: " + msg.what);
- break;
-
- // TODO: probably EF_CST should be read instead
- case EVENT_GET_SST_DONE:
- log("Event EVENT_GET_SST_DONE Received");
- break;
-
- case EVENT_RUIM_REFRESH:
- isRecordLoadResponse = false;
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- handleRuimRefresh((IccRefreshResponse)ar.result);
- }
- break;
-
- }}catch (RuntimeException exc) {
- // I don't want these exceptions to be fatal
- Log.w(LOG_TAG, "Exception parsing RUIM record", exc);
- } finally {
- // Count up record load responses even if they are fails
- if (isRecordLoadResponse) {
- onRecordLoaded();
- }
- }
- }
-
- @Override
- protected void onRecordLoaded() {
- // One record loaded successfully or failed, In either case
- // we need to update the recordsToLoad count
- recordsToLoad -= 1;
- if (DBG) log("RuimRecords:onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
-
- if (recordsToLoad == 0 && recordsRequested == true) {
- onAllRecordsLoaded();
- } else if (recordsToLoad < 0) {
- loge("RuimRecords: recordsToLoad <0, programmer error suspected");
- recordsToLoad = 0;
- }
- }
-
- @Override
- protected void onAllRecordsLoaded() {
- // Further records that can be inserted are Operator/OEM dependent
-
- String operator = getRUIMOperatorNumeric();
- log("RuimRecords: onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
- operator + "'");
- SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
-
- if (mImsi != null) {
- SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
- MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3))));
- }
- recordsLoadedRegistrants.notifyRegistrants(
- new AsyncResult(null, null, null));
- mParentCard.broadcastIccStateChangedIntent(
- IccCard.INTENT_VALUE_ICC_LOADED, null);
- }
-
- @Override
- public void onReady() {
- /* broadcast intent ICC_READY here so that we can make sure
- READY is sent before IMSI ready
- */
-
- mParentCard.broadcastIccStateChangedIntent(
- IccCard.INTENT_VALUE_ICC_READY, null);
-
- fetchRuimRecords();
-
- mCi.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
- }
-
-
- private void fetchRuimRecords() {
- recordsRequested = true;
-
- Log.v(LOG_TAG, "RuimRecords:fetchRuimRecords " + recordsToLoad);
-
- mCi.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_ICCID,
- obtainMessage(EVENT_GET_ICCID_DONE));
- recordsToLoad++;
-
- log("RuimRecords:fetchRuimRecords " + recordsToLoad + " requested: " + recordsRequested);
- // Further records that can be inserted are Operator/OEM dependent
- }
-
- /**
- * {@inheritDoc}
- *
- * No Display rule for RUIMs yet.
- */
- @Override
- public int getDisplayRule(String plmn) {
- // TODO together with spn
- return 0;
- }
-
- @Override
- public void setVoiceMessageWaiting(int line, int countWaiting) {
- if (line != 1) {
- // only profile 1 is supported
- return;
- }
-
- // range check
- if (countWaiting < 0) {
- countWaiting = -1;
- } else if (countWaiting > 0xff) {
- // C.S0015-B v2, 4.5.12
- // range: 0-99
- countWaiting = 0xff;
- }
- countVoiceMessages = countWaiting;
-
- mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
- }
-
- private void handleRuimRefresh(IccRefreshResponse refreshResponse) {
- if (refreshResponse == null) {
- if (DBG) log("handleRuimRefresh received without input");
- return;
- }
-
- if (refreshResponse.aid != null &&
- !refreshResponse.aid.equals(mParentCard.getAid())) {
- // This is for different app. Ignore.
- return;
- }
-
- switch (refreshResponse.refreshResult) {
- case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
- if (DBG) log("handleRuimRefresh with SIM_REFRESH_FILE_UPDATED");
- adnCache.reset();
- fetchRuimRecords();
- break;
- case IccRefreshResponse.REFRESH_RESULT_INIT:
- if (DBG) log("handleRuimRefresh with SIM_REFRESH_INIT");
- // need to reload all files (that we care about)
- fetchRuimRecords();
- break;
- case IccRefreshResponse.REFRESH_RESULT_RESET:
- if (DBG) log("handleRuimRefresh with SIM_REFRESH_RESET");
- mCi.setRadioPower(false, null);
- /* Note: no need to call setRadioPower(true). Assuming the desired
- * radio power state is still ON (as tracked by ServiceStateTracker),
- * ServiceStateTracker will call setRadioPower when it receives the
- * RADIO_STATE_CHANGED notification for the power off. And if the
- * desired power state has changed in the interim, we don't want to
- * override it with an unconditional power on.
- */
- break;
- default:
- // unknown refresh operation
- if (DBG) log("handleRuimRefresh with unknown operation");
- break;
- }
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[RuimRecords] " + s);
- }
-
- @Override
- protected void loge(String s) {
- Log.e(LOG_TAG, "[RuimRecords] " + s);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
deleted file mode 100644
index 9cd059d..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.internal.telephony.cdma;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.SmsRawData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
-
-/**
- * RuimSmsInterfaceManager to provide an inter-process communication to
- * access Sms in Ruim.
- */
-public class RuimSmsInterfaceManager extends IccSmsInterfaceManager {
- static final String LOG_TAG = "CDMA";
- static final boolean DBG = true;
-
- private final Object mLock = new Object();
- private boolean mSuccess;
- private List<SmsRawData> mSms;
-
- private static final int EVENT_LOAD_DONE = 1;
- private static final int EVENT_UPDATE_DONE = 2;
-
- Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_UPDATE_DONE:
- ar = (AsyncResult) msg.obj;
- synchronized (mLock) {
- mSuccess = (ar.exception == null);
- mLock.notifyAll();
- }
- break;
- case EVENT_LOAD_DONE:
- ar = (AsyncResult)msg.obj;
- synchronized (mLock) {
- if (ar.exception == null) {
- mSms = buildValidRawData((ArrayList<byte[]>) ar.result);
- } else {
- if(DBG) log("Cannot load Sms records");
- if (mSms != null)
- mSms.clear();
- }
- mLock.notifyAll();
- }
- break;
- }
- }
- };
-
- public RuimSmsInterfaceManager(CDMAPhone phone, SMSDispatcher dispatcher) {
- super(phone);
- mDispatcher = dispatcher;
- }
-
- public void dispose() {
- }
-
- protected void finalize() {
- try {
- super.finalize();
- } catch (Throwable throwable) {
- Log.e(LOG_TAG, "Error while finalizing:", throwable);
- }
- if(DBG) Log.d(LOG_TAG, "RuimSmsInterfaceManager finalized");
- }
-
- /**
- * Update the specified message on the RUIM.
- *
- * @param index record index of message to update
- * @param status 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
- *
- */
- public boolean
- updateMessageOnIccEf(int index, int status, byte[] pdu) {
- if (DBG) log("updateMessageOnIccEf: index=" + index +
- " status=" + status + " ==> " +
- "("+ pdu + ")");
- enforceReceiveAndSend("Updating message on RUIM");
- synchronized(mLock) {
- mSuccess = false;
- Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
-
- if (status == STATUS_ON_ICC_FREE) {
- // Special case FREE: call deleteSmsOnRuim instead of
- // manipulating the RUIM record
- mPhone.mCM.deleteSmsOnRuim(index, response);
- } else {
- byte[] record = makeSmsRecordData(status, pdu);
- mPhone.getIccFileHandler().updateEFLinearFixed(
- IccConstants.EF_SMS, index, record, null, response);
- }
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to update by index");
- }
- }
- return mSuccess;
- }
-
- /**
- * Copy a raw SMS PDU to the RUIM.
- *
- * @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 success or not
- *
- */
- public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
- //NOTE smsc not used in RUIM
- if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
- "pdu=("+ Arrays.toString(pdu) + ")");
- enforceReceiveAndSend("Copying message to RUIM");
- synchronized(mLock) {
- mSuccess = false;
- Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
-
- mPhone.mCM.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu),
- response);
-
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to update by index");
- }
- }
- return mSuccess;
- }
-
- /**
- * Retrieves all messages currently stored on RUIM.
- */
- public List<SmsRawData> getAllMessagesFromIccEf() {
- if (DBG) log("getAllMessagesFromEF");
-
- Context context = mPhone.getContext();
-
- context.enforceCallingPermission(
- "android.permission.RECEIVE_SMS",
- "Reading messages from RUIM");
- synchronized(mLock) {
- Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
- mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
-
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to load from the RUIM");
- }
- }
- return mSms;
- }
-
- public boolean enableCellBroadcast(int messageIdentifier) {
- // Not implemented
- Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
- return false;
- }
-
- public boolean disableCellBroadcast(int messageIdentifier) {
- // Not implemented
- Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
- return false;
- }
-
- public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
- // Not implemented
- Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
- return false;
- }
-
- public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
- // Not implemented
- Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
- return false;
- }
-
- protected void log(String msg) {
- Log.d(LOG_TAG, "[RuimSmsInterfaceManager] " + msg);
- }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
deleted file mode 100644
index a149e72..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2009 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.cdma;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import android.util.Log;
-import android.media.ToneGenerator;
-
-public class SignalToneUtil {
- /** A marker that isn't a valid TONE */
- public static final int CDMA_INVALID_TONE = -1;
-
- // public final int int IS95_CONST_IR_SIGNAL_TYPE_TYPE;
- static public final int IS95_CONST_IR_SIGNAL_TONE = 0;
- static public final int IS95_CONST_IR_SIGNAL_ISDN = 1;
- static public final int IS95_CONST_IR_SIGNAL_IS54B = 2;
- static public final int IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT = 4;
-
- // public final int int IS95_CONST_IR_ALERT_PITCH_TYPE;
- static public final int IS95_CONST_IR_ALERT_MED = 0;
- static public final int IS95_CONST_IR_ALERT_HIGH = 1;
- static public final int IS95_CONST_IR_ALERT_LOW = 2;
-
- // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal,
- // set TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN to 0 to avoid
- // the alert pitch to be involved in hash calculation for
- // signal type other than IS54B.
- static public final int TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN = 0;
-
- // public final int int IS95_CONST_IR_SIGNAL_TYPE;
- static public final int IS95_CONST_IR_SIG_ISDN_NORMAL = 0;
- static public final int IS95_CONST_IR_SIG_ISDN_INTGRP = 1;
- static public final int IS95_CONST_IR_SIG_ISDN_SP_PRI = 2;
- static public final int IS95_CONST_IR_SIG_ISDN_PAT_3 = 3;
- static public final int IS95_CONST_IR_SIG_ISDN_PING = 4;
- static public final int IS95_CONST_IR_SIG_ISDN_PAT_5 = 5;
- static public final int IS95_CONST_IR_SIG_ISDN_PAT_6 = 6;
- static public final int IS95_CONST_IR_SIG_ISDN_PAT_7 = 7;
- static public final int IS95_CONST_IR_SIG_ISDN_OFF = 15;
- static public final int IS95_CONST_IR_SIG_TONE_DIAL = 0;
- static public final int IS95_CONST_IR_SIG_TONE_RING = 1;
- static public final int IS95_CONST_IR_SIG_TONE_INT = 2;
- static public final int IS95_CONST_IR_SIG_TONE_ABB_INT = 3;
- static public final int IS95_CONST_IR_SIG_TONE_REORDER = 4;
- static public final int IS95_CONST_IR_SIG_TONE_ABB_RE = 5;
- static public final int IS95_CONST_IR_SIG_TONE_BUSY = 6;
- static public final int IS95_CONST_IR_SIG_TONE_CONFIRM = 7;
- static public final int IS95_CONST_IR_SIG_TONE_ANSWER = 8;
- static public final int IS95_CONST_IR_SIG_TONE_CALL_W = 9;
- static public final int IS95_CONST_IR_SIG_TONE_PIP = 10;
- static public final int IS95_CONST_IR_SIG_TONE_NO_TONE = 63;
- static public final int IS95_CONST_IR_SIG_IS54B_NO_TONE = 0;
- static public final int IS95_CONST_IR_SIG_IS54B_L = 1;
- static public final int IS95_CONST_IR_SIG_IS54B_SS = 2;
- static public final int IS95_CONST_IR_SIG_IS54B_SSL = 3;
- static public final int IS95_CONST_IR_SIG_IS54B_SS_2 = 4;
- static public final int IS95_CONST_IR_SIG_IS54B_SLS = 5;
- static public final int IS95_CONST_IR_SIG_IS54B_S_X4 = 6;
- static public final int IS95_CONST_IR_SIG_IS54B_PBX_L = 7;
- static public final int IS95_CONST_IR_SIG_IS54B_PBX_SS = 8;
- static public final int IS95_CONST_IR_SIG_IS54B_PBX_SSL = 9;
- static public final int IS95_CONST_IR_SIG_IS54B_PBX_SLS = 10;
- static public final int IS95_CONST_IR_SIG_IS54B_PBX_S_X4 = 11;
- static public final int IS95_CONST_IR_SIG_TONE_ABBR_ALRT = 0;
-
- // Hashmap to map signalInfo To AudioTone
- static private HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
-
- private static Integer signalParamHash(int signalType, int alertPitch, int signal) {
- if ((signalType < 0) || (signalType > 256) || (alertPitch > 256) ||
- (alertPitch < 0) || (signal > 256) || (signal < 0)) {
- return new Integer(CDMA_INVALID_TONE);
- }
- // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal,
- // the alert pitch field is ignored by the mobile station unless
- // SIGNAL_TYPE is '10',IS-54B Alerting.
- // Set alert pitch to TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN
- // so the alert pitch is not involved in hash calculation
- // when signal type is not IS-54B.
- if (signalType != IS95_CONST_IR_SIGNAL_IS54B) {
- alertPitch = TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN;
- }
- return new Integer(signalType * 256 * 256 + alertPitch * 256 + signal);
- }
-
- public static int getAudioToneFromSignalInfo(int signalType, int alertPitch, int signal) {
- Integer result = hm.get(signalParamHash(signalType, alertPitch, signal));
- if (result == null) {
- return CDMA_INVALID_TONE;
- }
- return result;
- }
-
- static {
-
- /* SIGNAL_TYPE_ISDN */
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_NORMAL), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_INTGRP),
- ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_SP_PRI), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_PAT_3), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT3);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_PING), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_PAT_5), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT5);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_PAT_6), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT6);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_PAT_7), ToneGenerator.TONE_CDMA_CALL_SIGNAL_ISDN_PAT7);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_ISDN, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_ISDN_OFF), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
-
- /* SIGNAL_TYPE_TONE */
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_DIAL), ToneGenerator.TONE_CDMA_DIAL_TONE_LITE);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_RING), ToneGenerator.TONE_CDMA_NETWORK_USA_RINGBACK);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_INT), ToneGenerator.TONE_SUP_INTERCEPT);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_ABB_INT), ToneGenerator.TONE_SUP_INTERCEPT_ABBREV);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_REORDER), ToneGenerator.TONE_CDMA_REORDER);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_ABB_RE), ToneGenerator.TONE_CDMA_ABBR_REORDER);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_BUSY), ToneGenerator.TONE_CDMA_NETWORK_BUSY);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_CONFIRM), ToneGenerator.TONE_SUP_CONFIRM);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_ANSWER), ToneGenerator.TONE_CDMA_ANSWER);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_CALL_W), ToneGenerator.TONE_CDMA_NETWORK_CALLWAITING);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_PIP), ToneGenerator.TONE_CDMA_PIP);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_TONE, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_TONE_NO_TONE), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
-
- /* SIGNAL_TYPE_IS54B */
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_HIGH_L);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_MED_L);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_L), ToneGenerator.TONE_CDMA_LOW_L);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_HIGH_SS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_MED_SS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_SS), ToneGenerator.TONE_CDMA_LOW_SS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_HIGH_SSL);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_MED_SSL);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_SSL), ToneGenerator.TONE_CDMA_LOW_SSL);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_HIGH_SS_2);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_MED_SS_2);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_SS_2), ToneGenerator.TONE_CDMA_LOW_SS_2);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_HIGH_SLS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_MED_SLS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_SLS), ToneGenerator.TONE_CDMA_LOW_SLS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_HIGH_S_X4);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_MED_S_X4);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_S_X4), ToneGenerator.TONE_CDMA_LOW_S_X4);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_HIGH_PBX_L);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_MED_PBX_L);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_PBX_L), ToneGenerator.TONE_CDMA_LOW_PBX_L);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_HIGH_PBX_SS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_MED_PBX_SS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_PBX_SS), ToneGenerator.TONE_CDMA_LOW_PBX_SS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_HIGH_PBX_SSL);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_MED_PBX_SSL);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_PBX_SSL), ToneGenerator.TONE_CDMA_LOW_PBX_SSL);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_HIGH_PBX_SLS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_MED_PBX_SLS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_PBX_SLS), ToneGenerator.TONE_CDMA_LOW_PBX_SLS);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_HIGH,
- IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_HIGH_PBX_S_X4);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_MED,
- IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_MED_PBX_S_X4);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, IS95_CONST_IR_ALERT_LOW,
- IS95_CONST_IR_SIG_IS54B_PBX_S_X4), ToneGenerator.TONE_CDMA_LOW_PBX_S_X4);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_IS54B, TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN,
- IS95_CONST_IR_SIG_IS54B_NO_TONE), ToneGenerator.TONE_CDMA_SIGNAL_OFF);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT,
- TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, IS95_CONST_IR_SIG_TONE_ABBR_ALRT),
- ToneGenerator.TONE_CDMA_ABBR_ALERT);
-
- hm.put(signalParamHash(IS95_CONST_IR_SIGNAL_USR_DEFD_ALERT,
- TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN, IS95_CONST_IR_SIG_TONE_NO_TONE),
- ToneGenerator.TONE_CDMA_ABBR_ALERT);
-
- }
-
- // suppress default constructor for noninstantiability
- private SignalToneUtil() {
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
deleted file mode 100644
index 9a0ebed..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ /dev/null
@@ -1,1004 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-import android.os.Parcel;
-import android.os.SystemProperties;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.util.Log;
-
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
-import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.util.BitwiseInputStream;
-import com.android.internal.util.HexDump;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.telephony.SmsMessage.MessageClass;
-
-/**
- * TODO(cleanup): these constants are disturbing... are they not just
- * different interpretations on one number? And if we did not have
- * terrible class name overlap, they would not need to be directly
- * imported like this. The class in this file could just as well be
- * named CdmaSmsMessage, could it not?
- */
-
-/**
- * TODO(cleanup): internally returning null in many places makes
- * debugging very hard (among many other reasons) and should be made
- * more meaningful (replaced with exceptions for example). Null
- * returns should only occur at the very outside of the module/class
- * scope.
- */
-
-/**
- * A Short Message Service message.
- *
- */
-public class SmsMessage extends SmsMessageBase {
- static final String LOG_TAG = "CDMA";
- static private final String LOGGABLE_TAG = "CDMA:SMS";
-
- private final static byte TELESERVICE_IDENTIFIER = 0x00;
- private final static byte SERVICE_CATEGORY = 0x01;
- private final static byte ORIGINATING_ADDRESS = 0x02;
- private final static byte ORIGINATING_SUB_ADDRESS = 0x03;
- private final static byte DESTINATION_ADDRESS = 0x04;
- private final static byte DESTINATION_SUB_ADDRESS = 0x05;
- private final static byte BEARER_REPLY_OPTION = 0x06;
- private final static byte CAUSE_CODES = 0x07;
- private final static byte BEARER_DATA = 0x08;
-
- /**
- * Status of a previously submitted SMS.
- * This field applies to SMS Delivery Acknowledge messages. 0 indicates success;
- * Here, the error class is defined by the bits from 9-8, the status code by the bits from 7-0.
- * See C.S0015-B, v2.0, 4.5.21 for a detailed description of possible values.
- */
- private int status;
-
- /** Specifies if a return of an acknowledgment is requested for send SMS */
- private static final int RETURN_NO_ACK = 0;
- private static final int RETURN_ACK = 1;
-
- private SmsEnvelope mEnvelope;
- private BearerData mBearerData;
-
- public static class SubmitPdu extends SubmitPduBase {
- }
-
- /**
- * Create an SmsMessage from a raw PDU.
- * Note: In CDMA the PDU is just a byte representation of the received Sms.
- */
- public static SmsMessage createFromPdu(byte[] pdu) {
- SmsMessage msg = new SmsMessage();
-
- try {
- msg.parsePdu(pdu);
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
- }
- }
-
- /**
- * Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp.
- * Note: Only primitive fields are set.
- */
- public static SmsMessage newFromParcel(Parcel p) {
- // Note: Parcel.readByte actually reads one Int and masks to byte
- SmsMessage msg = new SmsMessage();
- SmsEnvelope env = new SmsEnvelope();
- CdmaSmsAddress addr = new CdmaSmsAddress();
- CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress();
- byte[] data;
- byte count;
- int countInt;
- int addressDigitMode;
-
- //currently not supported by the modem-lib: env.mMessageType
- env.teleService = p.readInt(); //p_cur->uTeleserviceID
-
- if (0 != p.readByte()) { //p_cur->bIsServicePresent
- env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST;
- }
- else {
- if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) {
- // assume type ACK
- env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE;
- } else {
- env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
- }
- }
- env.serviceCategory = p.readInt(); //p_cur->uServicecategory
-
- // address
- addressDigitMode = p.readInt();
- addr.digitMode = (byte) (0xFF & addressDigitMode); //p_cur->sAddress.digit_mode
- addr.numberMode = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_mode
- addr.ton = p.readInt(); //p_cur->sAddress.number_type
- addr.numberPlan = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_plan
- count = p.readByte(); //p_cur->sAddress.number_of_digits
- addr.numberOfDigits = count;
- data = new byte[count];
- //p_cur->sAddress.digits[digitCount]
- for (int index=0; index < count; index++) {
- data[index] = p.readByte();
-
- // convert the value if it is 4-bit DTMF to 8 bit
- if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
- data[index] = msg.convertDtmfToAscii(data[index]);
- }
- }
-
- addr.origBytes = data;
-
- subaddr.type = p.readInt(); // p_cur->sSubAddress.subaddressType
- subaddr.odd = p.readByte(); // p_cur->sSubAddress.odd
- count = p.readByte(); // p_cur->sSubAddress.number_of_digits
-
- if (count < 0) {
- count = 0;
- }
-
- // p_cur->sSubAddress.digits[digitCount] :
-
- data = new byte[count];
-
- for (int index = 0; index < count; ++index) {
- data[index] = p.readByte();
- }
-
- subaddr.origBytes = data;
-
- /* currently not supported by the modem-lib:
- env.bearerReply
- env.replySeqNo
- env.errorClass
- env.causeCode
- */
-
- // bearer data
- countInt = p.readInt(); //p_cur->uBearerDataLen
- if (countInt < 0) {
- countInt = 0;
- }
-
- data = new byte[countInt];
- for (int index=0; index < countInt; index++) {
- data[index] = p.readByte();
- }
- // BD gets further decoded when accessed in SMSDispatcher
- env.bearerData = data;
-
- // link the the filled objects to the SMS
- env.origAddress = addr;
- env.origSubaddress = subaddr;
- msg.originatingAddress = addr;
- msg.mEnvelope = env;
-
- // create byte stream representation for transportation through the layers.
- msg.createPdu();
-
- return msg;
- }
-
- /**
- * Create an SmsMessage from an SMS EF record.
- *
- * @param index Index of SMS record. This should be index in ArrayList
- * returned by RuimSmsInterfaceManager.getAllMessagesFromIcc + 1.
- * @param data Record data.
- * @return An SmsMessage representing the record.
- *
- * @hide
- */
- public static SmsMessage createFromEfRecord(int index, byte[] data) {
- try {
- SmsMessage msg = new SmsMessage();
-
- msg.indexOnIcc = index;
-
- // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT,
- // or STORED_UNSENT
- // See 3GPP2 C.S0023 3.4.27
- if ((data[0] & 1) == 0) {
- Log.w(LOG_TAG, "SMS parsing failed: Trying to parse a free record");
- return null;
- } else {
- msg.statusOnIcc = data[0] & 0x07;
- }
-
- // Second byte is the MSG_LEN, length of the message
- // See 3GPP2 C.S0023 3.4.27
- int size = data[1];
-
- // Note: Data may include trailing FF's. That's OK; message
- // should still parse correctly.
- byte[] pdu = new byte[size];
- System.arraycopy(data, 2, pdu, 0, size);
- // the message has to be parsed before it can be displayed
- // see gsm.SmsMessage
- msg.parsePduFromEfRecord(pdu);
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
- }
-
- }
-
- /**
- * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
- */
- public static int getTPLayerLengthForPDU(String pdu) {
- Log.w(LOG_TAG, "getTPLayerLengthForPDU: is not supported in CDMA mode.");
- return 0;
- }
-
- /**
- * TODO(cleanup): why do getSubmitPdu methods take an scAddr input
- * and do nothing with it? GSM allows us to specify a SC (eg,
- * when responding to an SMS that explicitly requests the response
- * is sent to a specific SC), or pass null to use the default
- * value. Is there no similar notion in CDMA? Or do we just not
- * have it hooked up?
- */
-
- /**
- * Get an SMS-SUBMIT PDU for a destination address and a message
- *
- * @param scAddr Service Centre address. Null means use default.
- * @param destAddr Address of the recipient.
- * @param message String representation of the message payload.
- * @param statusReportRequested Indicates whether a report is requested for this message.
- * @param smsHeader Array containing the data for the User Data Header, preceded
- * by the Element Identifiers.
- * @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 scAddr, String destAddr, String message,
- boolean statusReportRequested, SmsHeader smsHeader) {
-
- /**
- * TODO(cleanup): Do we really want silent failure like this?
- * Would it not be much more reasonable to make sure we don't
- * call this function if we really want nothing done?
- */
- if (message == null || destAddr == null) {
- return null;
- }
-
- UserData uData = new UserData();
- uData.payloadStr = message;
- uData.userDataHeader = smsHeader;
- return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
- }
-
- /**
- * Get an SMS-SUBMIT PDU for a data message to a destination address and port.
- *
- * @param scAddr Service Centre address. null == use default
- * @param destAddr the address of the destination for the message
- * @param destPort the port to deliver the message to at the
- * destination
- * @param data the data 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 scAddr, String destAddr, int destPort,
- byte[] data, boolean statusReportRequested) {
-
- /**
- * TODO(cleanup): this is not a general-purpose SMS creation
- * method, but rather something specialized to messages
- * containing OCTET encoded (meaning non-human-readable) user
- * data. The name should reflect that, and not just overload.
- */
-
- SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
- portAddrs.destPort = destPort;
- portAddrs.origPort = 0;
- portAddrs.areEightBits = false;
-
- SmsHeader smsHeader = new SmsHeader();
- smsHeader.portAddrs = portAddrs;
-
- UserData uData = new UserData();
- uData.userDataHeader = smsHeader;
- uData.msgEncoding = UserData.ENCODING_OCTET;
- uData.msgEncodingSet = true;
- uData.payload = data;
-
- return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
- }
-
- /**
- * Get an SMS-SUBMIT PDU for a data message to a destination address & port
- *
- * @param destAddr the address of the destination for the message
- * @param userData the data for the message
- * @param statusReportRequested Indicates whether a report is requested for this 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 destAddr, UserData userData,
- boolean statusReportRequested) {
- return privateGetSubmitPdu(destAddr, statusReportRequested, userData);
- }
-
- /**
- * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
- */
- public int getProtocolIdentifier() {
- Log.w(LOG_TAG, "getProtocolIdentifier: is not supported in CDMA mode.");
- // (3GPP TS 23.040): "no interworking, but SME to SME protocol":
- return 0;
- }
-
- /**
- * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
- */
- public boolean isReplace() {
- Log.w(LOG_TAG, "isReplace: is not supported in CDMA mode.");
- return false;
- }
-
- /**
- * {@inheritDoc}
- * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
- */
- public boolean isCphsMwiMessage() {
- Log.w(LOG_TAG, "isCphsMwiMessage: is not supported in CDMA mode.");
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isMWIClearMessage() {
- return ((mBearerData != null) && (mBearerData.numberOfMessages == 0));
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isMWISetMessage() {
- return ((mBearerData != null) && (mBearerData.numberOfMessages > 0));
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isMwiDontStore() {
- return ((mBearerData != null) &&
- (mBearerData.numberOfMessages > 0) &&
- (mBearerData.userData == null));
- }
-
- /**
- * Returns the status for a previously submitted message.
- * For not interfering with status codes from GSM, this status code is
- * shifted to the bits 31-16.
- */
- public int getStatus() {
- return (status << 16);
- }
-
- /** Return true iff the bearer data message type is DELIVERY_ACK. */
- public boolean isStatusReportMessage() {
- return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK);
- }
-
- /**
- * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
- */
- public boolean isReplyPathPresent() {
- Log.w(LOG_TAG, "isReplyPathPresent: is not supported in CDMA mode.");
- return false;
- }
-
- /**
- * Calculate the number of septets needed to encode the message.
- *
- * @param messageBody the message to encode
- * @param use7bitOnly ignore (but still count) illegal characters if true
- * @return TextEncodingDetails
- */
- public static TextEncodingDetails calculateLength(CharSequence messageBody,
- boolean use7bitOnly) {
- return BearerData.calcTextEncodingDetails(messageBody, use7bitOnly);
- }
-
- /**
- * Returns the teleservice type of the message.
- * @return the teleservice:
- * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_NOT_SET},
- * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WMT},
- * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WEMT},
- * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_VMN},
- * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WAP}
- */
- /* package */ int getTeleService() {
- return mEnvelope.teleService;
- }
-
- /**
- * Returns the message type of the message.
- * @return the message type:
- * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_POINT_TO_POINT},
- * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_BROADCAST},
- * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE},
- */
- /* package */ int getMessageType() {
- // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs.
- // Use the service category parameter to detect CMAS and other cell broadcast messages.
- if (mEnvelope.serviceCategory != 0) {
- return SmsEnvelope.MESSAGE_TYPE_BROADCAST;
- } else {
- return SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
- }
- }
-
- /**
- * Decodes pdu to an empty SMS object.
- * In the CDMA case the pdu is just an internal byte stream representation
- * of the SMS Java-object.
- * @see #createPdu()
- */
- private void parsePdu(byte[] pdu) {
- ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
- DataInputStream dis = new DataInputStream(bais);
- byte length;
- int bearerDataLength;
- SmsEnvelope env = new SmsEnvelope();
- CdmaSmsAddress addr = new CdmaSmsAddress();
-
- try {
- env.messageType = dis.readInt();
- env.teleService = dis.readInt();
- env.serviceCategory = dis.readInt();
-
- addr.digitMode = dis.readByte();
- addr.numberMode = dis.readByte();
- addr.ton = dis.readByte();
- addr.numberPlan = dis.readByte();
-
- length = dis.readByte();
- addr.numberOfDigits = length;
- addr.origBytes = new byte[length];
- dis.read(addr.origBytes, 0, length); // digits
-
- env.bearerReply = dis.readInt();
- // CauseCode values:
- env.replySeqNo = dis.readByte();
- env.errorClass = dis.readByte();
- env.causeCode = dis.readByte();
-
- //encoded BearerData:
- bearerDataLength = dis.readInt();
- env.bearerData = new byte[bearerDataLength];
- dis.read(env.bearerData, 0, bearerDataLength);
- dis.close();
- } catch (Exception ex) {
- Log.e(LOG_TAG, "createFromPdu: conversion from byte array to object failed: " + ex);
- }
-
- // link the filled objects to this SMS
- originatingAddress = addr;
- env.origAddress = addr;
- mEnvelope = env;
- mPdu = pdu;
-
- parseSms();
- }
-
- /**
- * Decodes 3GPP2 sms stored in CSIM/RUIM cards As per 3GPP2 C.S0015-0
- */
- private void parsePduFromEfRecord(byte[] pdu) {
- ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
- DataInputStream dis = new DataInputStream(bais);
- SmsEnvelope env = new SmsEnvelope();
- CdmaSmsAddress addr = new CdmaSmsAddress();
- CdmaSmsSubaddress subAddr = new CdmaSmsSubaddress();
-
- try {
- env.messageType = dis.readByte();
-
- while (dis.available() > 0) {
- int parameterId = dis.readByte();
- int parameterLen = dis.readByte();
- byte[] parameterData = new byte[parameterLen];
-
- switch (parameterId) {
- case TELESERVICE_IDENTIFIER:
- /*
- * 16 bit parameter that identifies which upper layer
- * service access point is sending or should receive
- * this message
- */
- env.teleService = dis.readUnsignedShort();
- Log.i(LOG_TAG, "teleservice = " + env.teleService);
- break;
- case SERVICE_CATEGORY:
- /*
- * 16 bit parameter that identifies type of service as
- * in 3GPP2 C.S0015-0 Table 3.4.3.2-1
- */
- env.serviceCategory = dis.readUnsignedShort();
- break;
- case ORIGINATING_ADDRESS:
- case DESTINATION_ADDRESS:
- dis.read(parameterData, 0, parameterLen);
- BitwiseInputStream addrBis = new BitwiseInputStream(parameterData);
- addr.digitMode = addrBis.read(1);
- addr.numberMode = addrBis.read(1);
- int numberType = 0;
- if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
- numberType = addrBis.read(3);
- addr.ton = numberType;
-
- if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK)
- addr.numberPlan = addrBis.read(4);
- }
-
- addr.numberOfDigits = addrBis.read(8);
-
- byte[] data = new byte[addr.numberOfDigits];
- byte b = 0x00;
-
- if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
- /* As per 3GPP2 C.S0005-0 Table 2.7.1.3.2.4-4 */
- for (int index = 0; index < addr.numberOfDigits; index++) {
- b = (byte) (0xF & addrBis.read(4));
- // convert the value if it is 4-bit DTMF to 8
- // bit
- data[index] = convertDtmfToAscii(b);
- }
- } else if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
- if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) {
- for (int index = 0; index < addr.numberOfDigits; index++) {
- b = (byte) (0xFF & addrBis.read(8));
- data[index] = b;
- }
-
- } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) {
- if (numberType == 2)
- Log.e(LOG_TAG, "TODO: Originating Addr is email id");
- else
- Log.e(LOG_TAG,
- "TODO: Originating Addr is data network address");
- } else {
- Log.e(LOG_TAG, "Originating Addr is of incorrect type");
- }
- } else {
- Log.e(LOG_TAG, "Incorrect Digit mode");
- }
- addr.origBytes = data;
- Log.i(LOG_TAG, "Originating Addr=" + addr.toString());
- break;
- case ORIGINATING_SUB_ADDRESS:
- case DESTINATION_SUB_ADDRESS:
- dis.read(parameterData, 0, parameterLen);
- BitwiseInputStream subAddrBis = new BitwiseInputStream(parameterData);
- subAddr.type = subAddrBis.read(3);
- subAddr.odd = subAddrBis.readByteArray(1)[0];
- int subAddrLen = subAddrBis.read(8);
- byte[] subdata = new byte[subAddrLen];
- for (int index = 0; index < subAddrLen; index++) {
- b = (byte) (0xFF & subAddrBis.read(4));
- // convert the value if it is 4-bit DTMF to 8 bit
- subdata[index] = convertDtmfToAscii(b);
- }
- subAddr.origBytes = subdata;
- break;
- case BEARER_REPLY_OPTION:
- dis.read(parameterData, 0, parameterLen);
- BitwiseInputStream replyOptBis = new BitwiseInputStream(parameterData);
- env.bearerReply = replyOptBis.read(6);
- break;
- case CAUSE_CODES:
- dis.read(parameterData, 0, parameterLen);
- BitwiseInputStream ccBis = new BitwiseInputStream(parameterData);
- env.replySeqNo = ccBis.readByteArray(6)[0];
- env.errorClass = ccBis.readByteArray(2)[0];
- if (env.errorClass != 0x00)
- env.causeCode = ccBis.readByteArray(8)[0];
- break;
- case BEARER_DATA:
- dis.read(parameterData, 0, parameterLen);
- env.bearerData = parameterData;
- break;
- default:
- throw new Exception("unsupported parameterId (" + parameterId + ")");
- }
- }
- bais.close();
- dis.close();
- } catch (Exception ex) {
- Log.e(LOG_TAG, "parsePduFromEfRecord: conversion from pdu to SmsMessage failed" + ex);
- }
-
- // link the filled objects to this SMS
- originatingAddress = addr;
- env.origAddress = addr;
- env.origSubaddress = subAddr;
- mEnvelope = env;
- mPdu = pdu;
-
- parseSms();
- }
-
- /**
- * Parses a SMS message from its BearerData stream. (mobile-terminated only)
- */
- protected void parseSms() {
- // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6
- // It contains only an 8-bit number with the number of messages waiting
- if (mEnvelope.teleService == SmsEnvelope.TELESERVICE_MWI) {
- mBearerData = new BearerData();
- if (mEnvelope.bearerData != null) {
- mBearerData.numberOfMessages = 0x000000FF & mEnvelope.bearerData[0];
- }
- if (false) {
- Log.d(LOG_TAG, "parseSms: get MWI " +
- Integer.toString(mBearerData.numberOfMessages));
- }
- return;
- }
- mBearerData = BearerData.decode(mEnvelope.bearerData);
- if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
- Log.d(LOG_TAG, "MT raw BearerData = '" +
- HexDump.toHexString(mEnvelope.bearerData) + "'");
- Log.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData);
- }
- messageRef = mBearerData.messageId;
- if (mBearerData.userData != null) {
- userData = mBearerData.userData.payload;
- userDataHeader = mBearerData.userData.userDataHeader;
- messageBody = mBearerData.userData.payloadStr;
- }
-
- if (originatingAddress != null) {
- originatingAddress.address = new String(originatingAddress.origBytes);
- if (false) Log.v(LOG_TAG, "SMS originating address: "
- + originatingAddress.address);
- }
-
- if (mBearerData.msgCenterTimeStamp != null) {
- scTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true);
- }
-
- if (false) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
-
- // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1)
- if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) {
- // The BearerData MsgStatus subparameter should only be
- // included for DELIVERY_ACK messages. If it occurred for
- // other messages, it would be unclear what the status
- // being reported refers to. The MsgStatus subparameter
- // is primarily useful to indicate error conditions -- a
- // message without this subparameter is assumed to
- // indicate successful delivery (status == 0).
- if (! mBearerData.messageStatusSet) {
- Log.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" +
- (userData == null ? "also missing" : "does have") +
- " userData).");
- status = 0;
- } else {
- status = mBearerData.errorClass << 8;
- status |= mBearerData.messageStatus;
- }
- } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) {
- throw new RuntimeException("Unsupported message type: " + mBearerData.messageType);
- }
-
- if (messageBody != null) {
- if (false) Log.v(LOG_TAG, "SMS message body: '" + messageBody + "'");
- parseMessageBody();
- } else if ((userData != null) && (false)) {
- Log.v(LOG_TAG, "SMS payload: '" + IccUtils.bytesToHexString(userData) + "'");
- }
- }
-
- /**
- * Parses a broadcast SMS, possibly containing a CMAS alert.
- */
- SmsCbMessage parseBroadcastSms() {
- BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory);
- if (bData == null) {
- Log.w(LOG_TAG, "BearerData.decode() returned null");
- return null;
- }
-
- if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
- Log.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData));
- }
-
- String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
- SmsCbLocation location = new SmsCbLocation(plmn);
-
- return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2,
- SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location,
- mEnvelope.serviceCategory, bData.getLanguage(), bData.userData.payloadStr,
- bData.priority, null, bData.cmasWarningInfo);
- }
-
- /**
- * {@inheritDoc}
- */
- public MessageClass getMessageClass() {
- if (BearerData.DISPLAY_MODE_IMMEDIATE == mBearerData.displayMode ) {
- return MessageClass.CLASS_0;
- } else {
- return MessageClass.UNKNOWN;
- }
- }
-
- /**
- * Calculate the next message id, starting at 1 and iteratively
- * incrementing within the range 1..65535 remembering the state
- * via a persistent system property. (See C.S0015-B, v2.0,
- * 4.3.1.5) Since this routine is expected to be accessed via via
- * binder-call, and hence should be thread-safe, it has been
- * synchronized.
- */
- synchronized static int getNextMessageId() {
- // Testing and dialog with partners has indicated that
- // msgId==0 is (sometimes?) treated specially by lower levels.
- // Specifically, the ID is not preserved for delivery ACKs.
- // Hence, avoid 0 -- constraining the range to 1..65535.
- int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1);
- String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1);
- SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId);
- if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
- Log.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId);
- Log.d(LOG_TAG, "readback gets " +
- SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID));
- }
- return msgId;
- }
-
- /**
- * Creates BearerData and Envelope from parameters for a Submit SMS.
- * @return byte stream for SubmitPdu.
- */
- private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested,
- UserData userData) {
-
- /**
- * TODO(cleanup): give this function a more meaningful name.
- */
-
- /**
- * TODO(cleanup): Make returning null from the getSubmitPdu
- * variations meaningful -- clean up the error feedback
- * mechanism, and avoid null pointer exceptions.
- */
-
- /**
- * North America Plus Code :
- * Convert + code to 011 and dial out for international SMS
- */
- CdmaSmsAddress destAddr = CdmaSmsAddress.parse(
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode(destAddrStr));
- if (destAddr == null) return null;
-
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
-
- bearerData.messageId = getNextMessageId();
-
- bearerData.deliveryAckReq = statusReportRequested;
- bearerData.userAckReq = false;
- bearerData.readAckReq = false;
- bearerData.reportReq = false;
-
- bearerData.userData = userData;
-
- byte[] encodedBearerData = BearerData.encode(bearerData);
- if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
- Log.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData);
- Log.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'");
- }
- if (encodedBearerData == null) return null;
-
- int teleservice = bearerData.hasUserDataHeader ?
- SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT;
-
- SmsEnvelope envelope = new SmsEnvelope();
- envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
- envelope.teleService = teleservice;
- envelope.destAddress = destAddr;
- envelope.bearerReply = RETURN_ACK;
- envelope.bearerData = encodedBearerData;
-
- /**
- * TODO(cleanup): envelope looks to be a pointless class, get
- * rid of it. Also -- most of the envelope fields set here
- * are ignored, why?
- */
-
- try {
- /**
- * TODO(cleanup): reference a spec and get rid of the ugly comments
- */
- ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
- DataOutputStream dos = new DataOutputStream(baos);
- dos.writeInt(envelope.teleService);
- dos.writeInt(0); //servicePresent
- dos.writeInt(0); //serviceCategory
- dos.write(destAddr.digitMode);
- dos.write(destAddr.numberMode);
- dos.write(destAddr.ton); // number_type
- dos.write(destAddr.numberPlan);
- dos.write(destAddr.numberOfDigits);
- dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits
- // Subaddress is not supported.
- dos.write(0); //subaddressType
- dos.write(0); //subaddr_odd
- dos.write(0); //subaddr_nbr_of_digits
- dos.write(encodedBearerData.length);
- dos.write(encodedBearerData, 0, encodedBearerData.length);
- dos.close();
-
- SubmitPdu pdu = new SubmitPdu();
- pdu.encodedMessage = baos.toByteArray();
- pdu.encodedScAddress = null;
- return pdu;
- } catch(IOException ex) {
- Log.e(LOG_TAG, "creating SubmitPdu failed: " + ex);
- }
- return null;
- }
-
- /**
- * Creates byte array (pseudo pdu) from SMS object.
- * Note: Do not call this method more than once per object!
- */
- private void createPdu() {
- SmsEnvelope env = mEnvelope;
- CdmaSmsAddress addr = env.origAddress;
- ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
- DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
-
- try {
- dos.writeInt(env.messageType);
- dos.writeInt(env.teleService);
- dos.writeInt(env.serviceCategory);
-
- dos.writeByte(addr.digitMode);
- dos.writeByte(addr.numberMode);
- dos.writeByte(addr.ton);
- dos.writeByte(addr.numberPlan);
- dos.writeByte(addr.numberOfDigits);
- dos.write(addr.origBytes, 0, addr.origBytes.length); // digits
-
- dos.writeInt(env.bearerReply);
- // CauseCode values:
- dos.writeByte(env.replySeqNo);
- dos.writeByte(env.errorClass);
- dos.writeByte(env.causeCode);
- //encoded BearerData:
- dos.writeInt(env.bearerData.length);
- dos.write(env.bearerData, 0, env.bearerData.length);
- dos.close();
-
- /**
- * TODO(cleanup) -- The mPdu field is managed in
- * a fragile manner, and it would be much nicer if
- * accessing the serialized representation used a less
- * fragile mechanism. Maybe the getPdu method could
- * generate a representation if there was not yet one?
- */
-
- mPdu = baos.toByteArray();
- } catch (IOException ex) {
- Log.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex);
- }
- }
-
- /**
- * Converts a 4-Bit DTMF encoded symbol from the calling address number to ASCII character
- */
- private byte convertDtmfToAscii(byte dtmfDigit) {
- byte asciiDigit;
-
- switch (dtmfDigit) {
- case 0: asciiDigit = 68; break; // 'D'
- case 1: asciiDigit = 49; break; // '1'
- case 2: asciiDigit = 50; break; // '2'
- case 3: asciiDigit = 51; break; // '3'
- case 4: asciiDigit = 52; break; // '4'
- case 5: asciiDigit = 53; break; // '5'
- case 6: asciiDigit = 54; break; // '6'
- case 7: asciiDigit = 55; break; // '7'
- case 8: asciiDigit = 56; break; // '8'
- case 9: asciiDigit = 57; break; // '9'
- case 10: asciiDigit = 48; break; // '0'
- case 11: asciiDigit = 42; break; // '*'
- case 12: asciiDigit = 35; break; // '#'
- case 13: asciiDigit = 65; break; // 'A'
- case 14: asciiDigit = 66; break; // 'B'
- case 15: asciiDigit = 67; break; // 'C'
- default:
- asciiDigit = 32; // Invalid DTMF code
- break;
- }
-
- return asciiDigit;
- }
-
- /** This function shall be called to get the number of voicemails.
- * @hide
- */
- /*package*/ int getNumOfVoicemails() {
- return mBearerData.numberOfMessages;
- }
-
- /**
- * Returns a byte array that can be use to uniquely identify a received SMS message.
- * C.S0015-B 4.3.1.6 Unique Message Identification.
- *
- * @return byte array uniquely identifying the message.
- * @hide
- */
- /* package */ byte[] getIncomingSmsFingerprint() {
- ByteArrayOutputStream output = new ByteArrayOutputStream();
-
- output.write(mEnvelope.teleService);
- output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length);
- output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length);
- output.write(mEnvelope.origSubaddress.origBytes, 0,
- mEnvelope.origSubaddress.origBytes.length);
-
- return output.toByteArray();
- }
-
- /**
- * Returns the list of service category program data, if present.
- * @return a list of CdmaSmsCbProgramData objects, or null if not present
- */
- ArrayList<CdmaSmsCbProgramData> getSmsCbProgramData() {
- return mBearerData.serviceCategoryProgramData;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java b/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java
deleted file mode 100644
index 4907aa9..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.cdma;
-
-public class TtyIntent {
-
- private static final String TAG = "TtyIntent";
-
-
- /** Event for TTY mode change */
-
- /**
- * Broadcast intent action indicating that the TTY has either been
- * enabled or disabled. An intent extra provides this state as a boolean,
- * where {@code true} means enabled.
- * @see #TTY_ENABLED
- *
- * {@hide}
- */
- public static final String TTY_ENABLED_CHANGE_ACTION =
- "com.android.internal.telephony.cdma.intent.action.TTY_ENABLED_CHANGE";
-
- /**
- * The lookup key for a boolean that indicates whether TTY mode is enabled or
- * disabled. {@code true} means TTY mode is enabled. Retrieve it with
- * {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- *
- * {@hide}
- */
- public static final String TTY_ENABLED = "ttyEnabled";
-
- /**
- * Broadcast intent action indicating that the TTY preferred operating mode
- * has changed. An intent extra provides the new mode as an int.
- * @see #TTY_PREFFERED_MODE
- *
- * {@hide}
- */
- public static final String TTY_PREFERRED_MODE_CHANGE_ACTION =
- "com.android.internal.telephony.cdma.intent.action.TTY_PREFERRED_MODE_CHANGE";
-
- /**
- * The lookup key for an int that indicates preferred TTY mode.
- * Valid modes are:
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
- *
- * {@hide}
- */
- public static final String TTY_PREFFERED_MODE = "ttyPreferredMode";
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/package.html b/telephony/java/com/android/internal/telephony/cdma/package.html
deleted file mode 100644
index 4eb1f9c..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Provides classes to control or read data from CDMA phones.
-@hide
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
deleted file mode 100755
index 3d88f50..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ /dev/null
@@ -1,1968 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma.sms;
-
-import android.content.res.Resources;
-import android.telephony.SmsCbCmasInfo;
-import android.telephony.SmsMessage;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.telephony.cdma.CdmaSmsCbProgramResults;
-import android.text.format.Time;
-import android.util.Log;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.util.BitwiseInputStream;
-import com.android.internal.util.BitwiseOutputStream;
-
-import java.util.ArrayList;
-import java.util.TimeZone;
-
-import static android.telephony.SmsMessage.ENCODING_16BIT;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES;
-import static android.telephony.SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
-
-/**
- * An object to encode and decode CDMA SMS bearer data.
- */
-public final class BearerData {
- private final static String LOG_TAG = "SMS";
-
- /**
- * Bearer Data Subparameter Identifiers
- * (See 3GPP2 C.S0015-B, v2.0, table 4.5-1)
- * NOTE: Commented subparameter types are not implemented.
- */
- private final static byte SUBPARAM_MESSAGE_IDENTIFIER = 0x00;
- private final static byte SUBPARAM_USER_DATA = 0x01;
- private final static byte SUBPARAM_USER_RESPONSE_CODE = 0x02;
- private final static byte SUBPARAM_MESSAGE_CENTER_TIME_STAMP = 0x03;
- private final static byte SUBPARAM_VALIDITY_PERIOD_ABSOLUTE = 0x04;
- private final static byte SUBPARAM_VALIDITY_PERIOD_RELATIVE = 0x05;
- private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE = 0x06;
- private final static byte SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE = 0x07;
- private final static byte SUBPARAM_PRIORITY_INDICATOR = 0x08;
- private final static byte SUBPARAM_PRIVACY_INDICATOR = 0x09;
- private final static byte SUBPARAM_REPLY_OPTION = 0x0A;
- private final static byte SUBPARAM_NUMBER_OF_MESSAGES = 0x0B;
- private final static byte SUBPARAM_ALERT_ON_MESSAGE_DELIVERY = 0x0C;
- private final static byte SUBPARAM_LANGUAGE_INDICATOR = 0x0D;
- private final static byte SUBPARAM_CALLBACK_NUMBER = 0x0E;
- private final static byte SUBPARAM_MESSAGE_DISPLAY_MODE = 0x0F;
- //private final static byte SUBPARAM_MULTIPLE_ENCODING_USER_DATA = 0x10;
- private final static byte SUBPARAM_MESSAGE_DEPOSIT_INDEX = 0x11;
- private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12;
- private final static byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS = 0x13;
- private final static byte SUBPARAM_MESSAGE_STATUS = 0x14;
- //private final static byte SUBPARAM_TP_FAILURE_CAUSE = 0x15;
- //private final static byte SUBPARAM_ENHANCED_VMN = 0x16;
- //private final static byte SUBPARAM_ENHANCED_VMN_ACK = 0x17;
-
- /**
- * Supported message types for CDMA SMS messages
- * (See 3GPP2 C.S0015-B, v2.0, table 4.5.1-1)
- */
- public static final int MESSAGE_TYPE_DELIVER = 0x01;
- public static final int MESSAGE_TYPE_SUBMIT = 0x02;
- public static final int MESSAGE_TYPE_CANCELLATION = 0x03;
- public static final int MESSAGE_TYPE_DELIVERY_ACK = 0x04;
- public static final int MESSAGE_TYPE_USER_ACK = 0x05;
- public static final int MESSAGE_TYPE_READ_ACK = 0x06;
- public static final int MESSAGE_TYPE_DELIVER_REPORT = 0x07;
- public static final int MESSAGE_TYPE_SUBMIT_REPORT = 0x08;
-
- public int messageType;
-
- /**
- * 16-bit value indicating the message ID, which increments modulo 65536.
- * (Special rules apply for WAP-messages.)
- * (See 3GPP2 C.S0015-B, v2, 4.5.1)
- */
- public int messageId;
-
- /**
- * Supported priority modes for CDMA SMS messages
- * (See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1)
- */
- public static final int PRIORITY_NORMAL = 0x0;
- public static final int PRIORITY_INTERACTIVE = 0x1;
- public static final int PRIORITY_URGENT = 0x2;
- public static final int PRIORITY_EMERGENCY = 0x3;
-
- public boolean priorityIndicatorSet = false;
- public int priority = PRIORITY_NORMAL;
-
- /**
- * Supported privacy modes for CDMA SMS messages
- * (See 3GPP2 C.S0015-B, v2.0, table 4.5.10-1)
- */
- public static final int PRIVACY_NOT_RESTRICTED = 0x0;
- public static final int PRIVACY_RESTRICTED = 0x1;
- public static final int PRIVACY_CONFIDENTIAL = 0x2;
- public static final int PRIVACY_SECRET = 0x3;
-
- public boolean privacyIndicatorSet = false;
- public int privacy = PRIVACY_NOT_RESTRICTED;
-
- /**
- * Supported alert priority modes for CDMA SMS messages
- * (See 3GPP2 C.S0015-B, v2.0, table 4.5.13-1)
- */
- public static final int ALERT_DEFAULT = 0x0;
- public static final int ALERT_LOW_PRIO = 0x1;
- public static final int ALERT_MEDIUM_PRIO = 0x2;
- public static final int ALERT_HIGH_PRIO = 0x3;
-
- public boolean alertIndicatorSet = false;
- public int alert = ALERT_DEFAULT;
-
- /**
- * Supported display modes for CDMA SMS messages. Display mode is
- * a 2-bit value used to indicate to the mobile station when to
- * display the received message. (See 3GPP2 C.S0015-B, v2,
- * 4.5.16)
- */
- public static final int DISPLAY_MODE_IMMEDIATE = 0x0;
- public static final int DISPLAY_MODE_DEFAULT = 0x1;
- public static final int DISPLAY_MODE_USER = 0x2;
-
- public boolean displayModeSet = false;
- public int displayMode = DISPLAY_MODE_DEFAULT;
-
- /**
- * Language Indicator values. NOTE: the spec (3GPP2 C.S0015-B,
- * v2, 4.5.14) is ambiguous as to the meaning of this field, as it
- * refers to C.R1001-D but that reference has been crossed out.
- * It would seem reasonable to assume the values from C.R1001-F
- * (table 9.2-1) are to be used instead.
- */
- public static final int LANGUAGE_UNKNOWN = 0x00;
- public static final int LANGUAGE_ENGLISH = 0x01;
- public static final int LANGUAGE_FRENCH = 0x02;
- public static final int LANGUAGE_SPANISH = 0x03;
- public static final int LANGUAGE_JAPANESE = 0x04;
- public static final int LANGUAGE_KOREAN = 0x05;
- public static final int LANGUAGE_CHINESE = 0x06;
- public static final int LANGUAGE_HEBREW = 0x07;
-
- public boolean languageIndicatorSet = false;
- public int language = LANGUAGE_UNKNOWN;
-
- /**
- * SMS Message Status Codes. The first component of the Message
- * status indicates if an error has occurred and whether the error
- * is considered permanent or temporary. The second component of
- * the Message status indicates the cause of the error (if any).
- * (See 3GPP2 C.S0015-B, v2.0, 4.5.21)
- */
- /* no-error codes */
- public static final int ERROR_NONE = 0x00;
- public static final int STATUS_ACCEPTED = 0x00;
- public static final int STATUS_DEPOSITED_TO_INTERNET = 0x01;
- public static final int STATUS_DELIVERED = 0x02;
- public static final int STATUS_CANCELLED = 0x03;
- /* temporary-error and permanent-error codes */
- public static final int ERROR_TEMPORARY = 0x02;
- public static final int STATUS_NETWORK_CONGESTION = 0x04;
- public static final int STATUS_NETWORK_ERROR = 0x05;
- public static final int STATUS_UNKNOWN_ERROR = 0x1F;
- /* permanent-error codes */
- public static final int ERROR_PERMANENT = 0x03;
- public static final int STATUS_CANCEL_FAILED = 0x06;
- public static final int STATUS_BLOCKED_DESTINATION = 0x07;
- public static final int STATUS_TEXT_TOO_LONG = 0x08;
- public static final int STATUS_DUPLICATE_MESSAGE = 0x09;
- public static final int STATUS_INVALID_DESTINATION = 0x0A;
- public static final int STATUS_MESSAGE_EXPIRED = 0x0D;
- /* undefined-status codes */
- public static final int ERROR_UNDEFINED = 0xFF;
- public static final int STATUS_UNDEFINED = 0xFF;
-
- public boolean messageStatusSet = false;
- public int errorClass = ERROR_UNDEFINED;
- public int messageStatus = STATUS_UNDEFINED;
-
- /**
- * 1-bit value that indicates whether a User Data Header (UDH) is present.
- * (See 3GPP2 C.S0015-B, v2, 4.5.1)
- *
- * NOTE: during encoding, this value will be set based on the
- * presence of a UDH in the structured data, any existing setting
- * will be overwritten.
- */
- public boolean hasUserDataHeader;
-
- /**
- * provides the information for the user data
- * (e.g. padding bits, user data, user data header, etc)
- * (See 3GPP2 C.S.0015-B, v2, 4.5.2)
- */
- public UserData userData;
-
- /**
- * The User Response Code subparameter is used in the SMS User
- * Acknowledgment Message to respond to previously received short
- * messages. This message center-specific element carries the
- * identifier of a predefined response. (See 3GPP2 C.S.0015-B, v2,
- * 4.5.3)
- */
- public boolean userResponseCodeSet = false;
- public int userResponseCode;
-
- /**
- * 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4
- */
- public static class TimeStamp extends Time {
-
- public TimeStamp() {
- super(TimeZone.getDefault().getID()); // 3GPP2 timestamps use the local timezone
- }
-
- public static TimeStamp fromByteArray(byte[] data) {
- TimeStamp ts = new TimeStamp();
- // C.S0015-B v2.0, 4.5.4: range is 1996-2095
- int year = IccUtils.cdmaBcdByteToInt(data[0]);
- if (year > 99 || year < 0) return null;
- ts.year = year >= 96 ? year + 1900 : year + 2000;
- int month = IccUtils.cdmaBcdByteToInt(data[1]);
- if (month < 1 || month > 12) return null;
- ts.month = month - 1;
- int day = IccUtils.cdmaBcdByteToInt(data[2]);
- if (day < 1 || day > 31) return null;
- ts.monthDay = day;
- int hour = IccUtils.cdmaBcdByteToInt(data[3]);
- if (hour < 0 || hour > 23) return null;
- ts.hour = hour;
- int minute = IccUtils.cdmaBcdByteToInt(data[4]);
- if (minute < 0 || minute > 59) return null;
- ts.minute = minute;
- int second = IccUtils.cdmaBcdByteToInt(data[5]);
- if (second < 0 || second > 59) return null;
- ts.second = second;
- return ts;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("TimeStamp ");
- builder.append("{ year=" + year);
- builder.append(", month=" + month);
- builder.append(", day=" + monthDay);
- builder.append(", hour=" + hour);
- builder.append(", minute=" + minute);
- builder.append(", second=" + second);
- builder.append(" }");
- return builder.toString();
- }
- }
-
- public TimeStamp msgCenterTimeStamp;
- public TimeStamp validityPeriodAbsolute;
- public TimeStamp deferredDeliveryTimeAbsolute;
-
- /**
- * Relative time is specified as one byte, the value of which
- * falls into a series of ranges, as specified below. The idea is
- * that shorter time intervals allow greater precision -- the
- * value means minutes from zero until the MINS_LIMIT (inclusive),
- * upon which it means hours until the HOURS_LIMIT, and so
- * forth. (See 3GPP2 C.S0015-B, v2, 4.5.6-1)
- */
- public static final int RELATIVE_TIME_MINS_LIMIT = 143;
- public static final int RELATIVE_TIME_HOURS_LIMIT = 167;
- public static final int RELATIVE_TIME_DAYS_LIMIT = 196;
- public static final int RELATIVE_TIME_WEEKS_LIMIT = 244;
- public static final int RELATIVE_TIME_INDEFINITE = 245;
- public static final int RELATIVE_TIME_NOW = 246;
- public static final int RELATIVE_TIME_MOBILE_INACTIVE = 247;
- public static final int RELATIVE_TIME_RESERVED = 248;
-
- public boolean validityPeriodRelativeSet;
- public int validityPeriodRelative;
- public boolean deferredDeliveryTimeRelativeSet;
- public int deferredDeliveryTimeRelative;
-
- /**
- * The Reply Option subparameter contains 1-bit values which
- * indicate whether SMS acknowledgment is requested or not. (See
- * 3GPP2 C.S0015-B, v2, 4.5.11)
- */
- public boolean userAckReq;
- public boolean deliveryAckReq;
- public boolean readAckReq;
- public boolean reportReq;
-
- /**
- * The Number of Messages subparameter (8-bit value) is a decimal
- * number in the 0 to 99 range representing the number of messages
- * stored at the Voice Mail System. This element is used by the
- * Voice Mail Notification service. (See 3GPP2 C.S0015-B, v2,
- * 4.5.12)
- */
- public int numberOfMessages;
-
- /**
- * The Message Deposit Index subparameter is assigned by the
- * message center as a unique index to the contents of the User
- * Data subparameter in each message sent to a particular mobile
- * station. The mobile station, when replying to a previously
- * received short message which included a Message Deposit Index
- * subparameter, may include the Message Deposit Index of the
- * received message to indicate to the message center that the
- * original contents of the message are to be included in the
- * reply. (See 3GPP2 C.S0015-B, v2, 4.5.18)
- */
- public int depositIndex;
-
- /**
- * 4-bit or 8-bit value that indicates the number to be dialed in reply to a
- * received SMS message.
- * (See 3GPP2 C.S0015-B, v2, 4.5.15)
- */
- public CdmaSmsAddress callbackNumber;
-
- /**
- * CMAS warning notification information.
- * @see #decodeCmasUserData(BearerData, int)
- */
- public SmsCbCmasInfo cmasWarningInfo;
-
- /**
- * The Service Category Program Data subparameter is used to enable and disable
- * SMS broadcast service categories to display. If this subparameter is present,
- * this field will contain a list of one or more
- * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects containing the
- * operation(s) to perform.
- */
- public ArrayList<CdmaSmsCbProgramData> serviceCategoryProgramData;
-
- /**
- * The Service Category Program Results subparameter informs the message center
- * of the results of a Service Category Program Data request.
- */
- public ArrayList<CdmaSmsCbProgramResults> serviceCategoryProgramResults;
-
-
- private static class CodingException extends Exception {
- public CodingException(String s) {
- super(s);
- }
- }
-
- /**
- * Returns the language indicator as a two-character ISO 639 string.
- * @return a two character ISO 639 language code
- */
- public String getLanguage() {
- return getLanguageCodeForValue(language);
- }
-
- /**
- * Converts a CDMA language indicator value to an ISO 639 two character language code.
- * @param languageValue the CDMA language value to convert
- * @return the two character ISO 639 language code for the specified value, or null if unknown
- */
- private static String getLanguageCodeForValue(int languageValue) {
- switch (languageValue) {
- case LANGUAGE_ENGLISH:
- return "en";
-
- case LANGUAGE_FRENCH:
- return "fr";
-
- case LANGUAGE_SPANISH:
- return "es";
-
- case LANGUAGE_JAPANESE:
- return "ja";
-
- case LANGUAGE_KOREAN:
- return "ko";
-
- case LANGUAGE_CHINESE:
- return "zh";
-
- case LANGUAGE_HEBREW:
- return "he";
-
- default:
- return null;
- }
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("BearerData ");
- builder.append("{ messageType=" + messageType);
- builder.append(", messageId=" + (int)messageId);
- builder.append(", priority=" + (priorityIndicatorSet ? priority : "unset"));
- builder.append(", privacy=" + (privacyIndicatorSet ? privacy : "unset"));
- builder.append(", alert=" + (alertIndicatorSet ? alert : "unset"));
- builder.append(", displayMode=" + (displayModeSet ? displayMode : "unset"));
- builder.append(", language=" + (languageIndicatorSet ? language : "unset"));
- builder.append(", errorClass=" + (messageStatusSet ? errorClass : "unset"));
- builder.append(", msgStatus=" + (messageStatusSet ? messageStatus : "unset"));
- builder.append(", msgCenterTimeStamp=" +
- ((msgCenterTimeStamp != null) ? msgCenterTimeStamp : "unset"));
- builder.append(", validityPeriodAbsolute=" +
- ((validityPeriodAbsolute != null) ? validityPeriodAbsolute : "unset"));
- builder.append(", validityPeriodRelative=" +
- ((validityPeriodRelativeSet) ? validityPeriodRelative : "unset"));
- builder.append(", deferredDeliveryTimeAbsolute=" +
- ((deferredDeliveryTimeAbsolute != null) ? deferredDeliveryTimeAbsolute : "unset"));
- builder.append(", deferredDeliveryTimeRelative=" +
- ((deferredDeliveryTimeRelativeSet) ? deferredDeliveryTimeRelative : "unset"));
- builder.append(", userAckReq=" + userAckReq);
- builder.append(", deliveryAckReq=" + deliveryAckReq);
- builder.append(", readAckReq=" + readAckReq);
- builder.append(", reportReq=" + reportReq);
- builder.append(", numberOfMessages=" + numberOfMessages);
- builder.append(", callbackNumber=" + callbackNumber);
- builder.append(", depositIndex=" + depositIndex);
- builder.append(", hasUserDataHeader=" + hasUserDataHeader);
- builder.append(", userData=" + userData);
- builder.append(" }");
- return builder.toString();
- }
-
- private static void encodeMessageId(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 3);
- outStream.write(4, bData.messageType);
- outStream.write(8, bData.messageId >> 8);
- outStream.write(8, bData.messageId);
- outStream.write(1, bData.hasUserDataHeader ? 1 : 0);
- outStream.skip(3);
- }
-
- private static int countAsciiSeptets(CharSequence msg, boolean force) {
- int msgLen = msg.length();
- if (force) return msgLen;
- for (int i = 0; i < msgLen; i++) {
- if (UserData.charToAscii.get(msg.charAt(i), -1) == -1) {
- return -1;
- }
- }
- return msgLen;
- }
-
- /**
- * Calculate the message text encoding length, fragmentation, and other details.
- *
- * @param msg message text
- * @param force7BitEncoding ignore (but still count) illegal characters if true
- * @return septet count, or -1 on failure
- */
- public static TextEncodingDetails calcTextEncodingDetails(CharSequence msg,
- boolean force7BitEncoding) {
- TextEncodingDetails ted;
- int septets = countAsciiSeptets(msg, force7BitEncoding);
- if (septets != -1 && septets <= SmsMessage.MAX_USER_DATA_SEPTETS) {
- ted = new TextEncodingDetails();
- ted.msgCount = 1;
- ted.codeUnitCount = septets;
- ted.codeUnitsRemaining = SmsMessage.MAX_USER_DATA_SEPTETS - septets;
- ted.codeUnitSize = SmsMessage.ENCODING_7BIT;
- } else {
- ted = com.android.internal.telephony.gsm.SmsMessage.calculateLength(
- msg, force7BitEncoding);
- if (ted.msgCount == 1 && ted.codeUnitSize == SmsMessage.ENCODING_7BIT) {
- // We don't support single-segment EMS, so calculate for 16-bit
- // TODO: Consider supporting single-segment EMS
- ted.codeUnitCount = msg.length();
- int octets = ted.codeUnitCount * 2;
- if (octets > MAX_USER_DATA_BYTES) {
- ted.msgCount = (octets + (MAX_USER_DATA_BYTES_WITH_HEADER - 1)) /
- MAX_USER_DATA_BYTES_WITH_HEADER;
- ted.codeUnitsRemaining = ((ted.msgCount *
- MAX_USER_DATA_BYTES_WITH_HEADER) - octets) / 2;
- } else {
- ted.msgCount = 1;
- ted.codeUnitsRemaining = (MAX_USER_DATA_BYTES - octets)/2;
- }
- ted.codeUnitSize = ENCODING_16BIT;
- }
- }
- return ted;
- }
-
- private static byte[] encode7bitAscii(String msg, boolean force)
- throws CodingException
- {
- try {
- BitwiseOutputStream outStream = new BitwiseOutputStream(msg.length());
- int msgLen = msg.length();
- for (int i = 0; i < msgLen; i++) {
- int charCode = UserData.charToAscii.get(msg.charAt(i), -1);
- if (charCode == -1) {
- if (force) {
- outStream.write(7, UserData.UNENCODABLE_7_BIT_CHAR);
- } else {
- throw new CodingException("cannot ASCII encode (" + msg.charAt(i) + ")");
- }
- } else {
- outStream.write(7, charCode);
- }
- }
- return outStream.toByteArray();
- } catch (BitwiseOutputStream.AccessException ex) {
- throw new CodingException("7bit ASCII encode failed: " + ex);
- }
- }
-
- private static byte[] encodeUtf16(String msg)
- throws CodingException
- {
- try {
- return msg.getBytes("utf-16be");
- } catch (java.io.UnsupportedEncodingException ex) {
- throw new CodingException("UTF-16 encode failed: " + ex);
- }
- }
-
- private static class Gsm7bitCodingResult {
- int septets;
- byte[] data;
- }
-
- private static Gsm7bitCodingResult encode7bitGsm(String msg, int septetOffset, boolean force)
- throws CodingException
- {
- try {
- /*
- * TODO(cleanup): It would be nice if GsmAlphabet provided
- * an option to produce just the data without prepending
- * the septet count, as this function is really just a
- * wrapper to strip that off. Not to mention that the
- * septet count is generally known prior to invocation of
- * the encoder. Note that it cannot be derived from the
- * resulting array length, since that cannot distinguish
- * if the last contains either 1 or 8 valid bits.
- *
- * TODO(cleanup): The BitwiseXStreams could also be
- * extended with byte-wise reversed endianness read/write
- * routines to allow a corresponding implementation of
- * stringToGsm7BitPacked, and potentially directly support
- * access to the main bitwise stream from encode/decode.
- */
- byte[] fullData = GsmAlphabet.stringToGsm7BitPacked(msg, septetOffset, !force, 0, 0);
- Gsm7bitCodingResult result = new Gsm7bitCodingResult();
- result.data = new byte[fullData.length - 1];
- System.arraycopy(fullData, 1, result.data, 0, fullData.length - 1);
- result.septets = fullData[0] & 0x00FF;
- return result;
- } catch (com.android.internal.telephony.EncodeException ex) {
- throw new CodingException("7bit GSM encode failed: " + ex);
- }
- }
-
- private static void encode7bitEms(UserData uData, byte[] udhData, boolean force)
- throws CodingException
- {
- int udhBytes = udhData.length + 1; // Add length octet.
- int udhSeptets = ((udhBytes * 8) + 6) / 7;
- Gsm7bitCodingResult gcr = encode7bitGsm(uData.payloadStr, udhSeptets, force);
- uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
- uData.msgEncodingSet = true;
- uData.numFields = gcr.septets;
- uData.payload = gcr.data;
- uData.payload[0] = (byte)udhData.length;
- System.arraycopy(udhData, 0, uData.payload, 1, udhData.length);
- }
-
- private static void encode16bitEms(UserData uData, byte[] udhData)
- throws CodingException
- {
- byte[] payload = encodeUtf16(uData.payloadStr);
- int udhBytes = udhData.length + 1; // Add length octet.
- int udhCodeUnits = (udhBytes + 1) / 2;
- int payloadCodeUnits = payload.length / 2;
- uData.msgEncoding = UserData.ENCODING_UNICODE_16;
- uData.msgEncodingSet = true;
- uData.numFields = udhCodeUnits + payloadCodeUnits;
- uData.payload = new byte[uData.numFields * 2];
- uData.payload[0] = (byte)udhData.length;
- System.arraycopy(udhData, 0, uData.payload, 1, udhData.length);
- System.arraycopy(payload, 0, uData.payload, udhBytes, payload.length);
- }
-
- private static void encodeEmsUserDataPayload(UserData uData)
- throws CodingException
- {
- byte[] headerData = SmsHeader.toByteArray(uData.userDataHeader);
- if (uData.msgEncodingSet) {
- if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
- encode7bitEms(uData, headerData, true);
- } else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) {
- encode16bitEms(uData, headerData);
- } else {
- throw new CodingException("unsupported EMS user data encoding (" +
- uData.msgEncoding + ")");
- }
- } else {
- try {
- encode7bitEms(uData, headerData, false);
- } catch (CodingException ex) {
- encode16bitEms(uData, headerData);
- }
- }
- }
-
- private static void encodeUserDataPayload(UserData uData)
- throws CodingException
- {
- if ((uData.payloadStr == null) && (uData.msgEncoding != UserData.ENCODING_OCTET)) {
- Log.e(LOG_TAG, "user data with null payloadStr");
- uData.payloadStr = "";
- }
-
- if (uData.userDataHeader != null) {
- encodeEmsUserDataPayload(uData);
- return;
- }
-
- if (uData.msgEncodingSet) {
- if (uData.msgEncoding == UserData.ENCODING_OCTET) {
- if (uData.payload == null) {
- Log.e(LOG_TAG, "user data with octet encoding but null payload");
- uData.payload = new byte[0];
- uData.numFields = 0;
- } else {
- uData.numFields = uData.payload.length;
- }
- } else {
- if (uData.payloadStr == null) {
- Log.e(LOG_TAG, "non-octet user data with null payloadStr");
- uData.payloadStr = "";
- }
- if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
- Gsm7bitCodingResult gcr = encode7bitGsm(uData.payloadStr, 0, true);
- uData.payload = gcr.data;
- uData.numFields = gcr.septets;
- } else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) {
- uData.payload = encode7bitAscii(uData.payloadStr, true);
- uData.numFields = uData.payloadStr.length();
- } else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) {
- uData.payload = encodeUtf16(uData.payloadStr);
- uData.numFields = uData.payloadStr.length();
- } else {
- throw new CodingException("unsupported user data encoding (" +
- uData.msgEncoding + ")");
- }
- }
- } else {
- try {
- uData.payload = encode7bitAscii(uData.payloadStr, false);
- uData.msgEncoding = UserData.ENCODING_7BIT_ASCII;
- } catch (CodingException ex) {
- uData.payload = encodeUtf16(uData.payloadStr);
- uData.msgEncoding = UserData.ENCODING_UNICODE_16;
- }
- uData.numFields = uData.payloadStr.length();
- uData.msgEncodingSet = true;
- }
- }
-
- private static void encodeUserData(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException, CodingException
- {
- /*
- * TODO(cleanup): Do we really need to set userData.payload as
- * a side effect of encoding? If not, we could avoid data
- * copies by passing outStream directly.
- */
- encodeUserDataPayload(bData.userData);
- bData.hasUserDataHeader = bData.userData.userDataHeader != null;
-
- if (bData.userData.payload.length > SmsMessage.MAX_USER_DATA_BYTES) {
- throw new CodingException("encoded user data too large (" +
- bData.userData.payload.length +
- " > " + SmsMessage.MAX_USER_DATA_BYTES + " bytes)");
- }
-
- /*
- * TODO(cleanup): figure out what the right answer is WRT paddingBits field
- *
- * userData.paddingBits = (userData.payload.length * 8) - (userData.numFields * 7);
- * userData.paddingBits = 0; // XXX this seems better, but why?
- *
- */
- int dataBits = (bData.userData.payload.length * 8) - bData.userData.paddingBits;
- int paramBits = dataBits + 13;
- if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
- (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
- paramBits += 8;
- }
- int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0);
- int paddingBits = (paramBytes * 8) - paramBits;
- outStream.write(8, paramBytes);
- outStream.write(5, bData.userData.msgEncoding);
- if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
- (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
- outStream.write(8, bData.userData.msgType);
- }
- outStream.write(8, bData.userData.numFields);
- outStream.writeByteArray(dataBits, bData.userData.payload);
- if (paddingBits > 0) outStream.write(paddingBits, 0);
- }
-
- private static void encodeReplyOption(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(1, bData.userAckReq ? 1 : 0);
- outStream.write(1, bData.deliveryAckReq ? 1 : 0);
- outStream.write(1, bData.readAckReq ? 1 : 0);
- outStream.write(1, bData.reportReq ? 1 : 0);
- outStream.write(4, 0);
- }
-
- private static byte[] encodeDtmfSmsAddress(String address) {
- int digits = address.length();
- int dataBits = digits * 4;
- int dataBytes = (dataBits / 8);
- dataBytes += (dataBits % 8) > 0 ? 1 : 0;
- byte[] rawData = new byte[dataBytes];
- for (int i = 0; i < digits; i++) {
- char c = address.charAt(i);
- int val = 0;
- if ((c >= '1') && (c <= '9')) val = c - '0';
- else if (c == '0') val = 10;
- else if (c == '*') val = 11;
- else if (c == '#') val = 12;
- else return null;
- rawData[i / 2] |= val << (4 - ((i % 2) * 4));
- }
- return rawData;
- }
-
- /*
- * TODO(cleanup): CdmaSmsAddress encoding should make use of
- * CdmaSmsAddress.parse provided that DTMF encoding is unified,
- * and the difference in 4-bit vs. 8-bit is resolved.
- */
-
- private static void encodeCdmaSmsAddress(CdmaSmsAddress addr) throws CodingException {
- if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
- try {
- addr.origBytes = addr.address.getBytes("US-ASCII");
- } catch (java.io.UnsupportedEncodingException ex) {
- throw new CodingException("invalid SMS address, cannot convert to ASCII");
- }
- } else {
- addr.origBytes = encodeDtmfSmsAddress(addr.address);
- }
- }
-
- private static void encodeCallbackNumber(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException, CodingException
- {
- CdmaSmsAddress addr = bData.callbackNumber;
- encodeCdmaSmsAddress(addr);
- int paramBits = 9;
- int dataBits = 0;
- if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
- paramBits += 7;
- dataBits = addr.numberOfDigits * 8;
- } else {
- dataBits = addr.numberOfDigits * 4;
- }
- paramBits += dataBits;
- int paramBytes = (paramBits / 8) + ((paramBits % 8) > 0 ? 1 : 0);
- int paddingBits = (paramBytes * 8) - paramBits;
- outStream.write(8, paramBytes);
- outStream.write(1, addr.digitMode);
- if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
- outStream.write(3, addr.ton);
- outStream.write(4, addr.numberPlan);
- }
- outStream.write(8, addr.numberOfDigits);
- outStream.writeByteArray(dataBits, addr.origBytes);
- if (paddingBits > 0) outStream.write(paddingBits, 0);
- }
-
- private static void encodeMsgStatus(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(2, bData.errorClass);
- outStream.write(6, bData.messageStatus);
- }
-
- private static void encodeMsgCount(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(8, bData.numberOfMessages);
- }
-
- private static void encodeValidityPeriodRel(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(8, bData.validityPeriodRelative);
- }
-
- private static void encodePrivacyIndicator(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(2, bData.privacy);
- outStream.skip(6);
- }
-
- private static void encodeLanguageIndicator(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(8, bData.language);
- }
-
- private static void encodeDisplayMode(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(2, bData.displayMode);
- outStream.skip(6);
- }
-
- private static void encodePriorityIndicator(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(2, bData.priority);
- outStream.skip(6);
- }
-
- private static void encodeMsgDeliveryAlert(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- outStream.write(8, 1);
- outStream.write(2, bData.alert);
- outStream.skip(6);
- }
-
- private static void encodeScpResults(BearerData bData, BitwiseOutputStream outStream)
- throws BitwiseOutputStream.AccessException
- {
- ArrayList<CdmaSmsCbProgramResults> results = bData.serviceCategoryProgramResults;
- outStream.write(8, (results.size() * 4)); // 4 octets per program result
- for (CdmaSmsCbProgramResults result : results) {
- int category = result.getCategory();
- outStream.write(8, category >> 8);
- outStream.write(8, category);
- outStream.write(8, result.getLanguage());
- outStream.write(4, result.getCategoryResult());
- outStream.skip(4);
- }
- }
-
- /**
- * Create serialized representation for BearerData object.
- * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
- *
- * @param bData an instance of BearerData.
- *
- * @return byte array of raw encoded SMS bearer data.
- */
- public static byte[] encode(BearerData bData) {
- bData.hasUserDataHeader = ((bData.userData != null) &&
- (bData.userData.userDataHeader != null));
- try {
- BitwiseOutputStream outStream = new BitwiseOutputStream(200);
- outStream.write(8, SUBPARAM_MESSAGE_IDENTIFIER);
- encodeMessageId(bData, outStream);
- if (bData.userData != null) {
- outStream.write(8, SUBPARAM_USER_DATA);
- encodeUserData(bData, outStream);
- }
- if (bData.callbackNumber != null) {
- outStream.write(8, SUBPARAM_CALLBACK_NUMBER);
- encodeCallbackNumber(bData, outStream);
- }
- if (bData.userAckReq || bData.deliveryAckReq || bData.readAckReq || bData.reportReq) {
- outStream.write(8, SUBPARAM_REPLY_OPTION);
- encodeReplyOption(bData, outStream);
- }
- if (bData.numberOfMessages != 0) {
- outStream.write(8, SUBPARAM_NUMBER_OF_MESSAGES);
- encodeMsgCount(bData, outStream);
- }
- if (bData.validityPeriodRelativeSet) {
- outStream.write(8, SUBPARAM_VALIDITY_PERIOD_RELATIVE);
- encodeValidityPeriodRel(bData, outStream);
- }
- if (bData.privacyIndicatorSet) {
- outStream.write(8, SUBPARAM_PRIVACY_INDICATOR);
- encodePrivacyIndicator(bData, outStream);
- }
- if (bData.languageIndicatorSet) {
- outStream.write(8, SUBPARAM_LANGUAGE_INDICATOR);
- encodeLanguageIndicator(bData, outStream);
- }
- if (bData.displayModeSet) {
- outStream.write(8, SUBPARAM_MESSAGE_DISPLAY_MODE);
- encodeDisplayMode(bData, outStream);
- }
- if (bData.priorityIndicatorSet) {
- outStream.write(8, SUBPARAM_PRIORITY_INDICATOR);
- encodePriorityIndicator(bData, outStream);
- }
- if (bData.alertIndicatorSet) {
- outStream.write(8, SUBPARAM_ALERT_ON_MESSAGE_DELIVERY);
- encodeMsgDeliveryAlert(bData, outStream);
- }
- if (bData.messageStatusSet) {
- outStream.write(8, SUBPARAM_MESSAGE_STATUS);
- encodeMsgStatus(bData, outStream);
- }
- if (bData.serviceCategoryProgramResults != null) {
- outStream.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS);
- encodeScpResults(bData, outStream);
- }
- return outStream.toByteArray();
- } catch (BitwiseOutputStream.AccessException ex) {
- Log.e(LOG_TAG, "BearerData encode failed: " + ex);
- } catch (CodingException ex) {
- Log.e(LOG_TAG, "BearerData encode failed: " + ex);
- }
- return null;
- }
-
- private static boolean decodeMessageId(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 3 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.messageType = inStream.read(4);
- bData.messageId = inStream.read(8) << 8;
- bData.messageId |= inStream.read(8);
- bData.hasUserDataHeader = (inStream.read(1) == 1);
- inStream.skip(3);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "MESSAGE_IDENTIFIER decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- return decodeSuccess;
- }
-
- private static boolean decodeUserData(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException
- {
- int paramBits = inStream.read(8) * 8;
- bData.userData = new UserData();
- bData.userData.msgEncoding = inStream.read(5);
- bData.userData.msgEncodingSet = true;
- bData.userData.msgType = 0;
- int consumedBits = 5;
- if ((bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) ||
- (bData.userData.msgEncoding == UserData.ENCODING_GSM_DCS)) {
- bData.userData.msgType = inStream.read(8);
- consumedBits += 8;
- }
- bData.userData.numFields = inStream.read(8);
- consumedBits += 8;
- int dataBits = paramBits - consumedBits;
- bData.userData.payload = inStream.readByteArray(dataBits);
- return true;
- }
-
- private static String decodeUtf8(byte[] data, int offset, int numFields)
- throws CodingException
- {
- return decodeCharset(data, offset, numFields, 1, "UTF-8");
- }
-
- private static String decodeUtf16(byte[] data, int offset, int numFields)
- throws CodingException
- {
- // Subtract header and possible padding byte (at end) from num fields.
- int padding = offset % 2;
- numFields -= (offset + padding) / 2;
- return decodeCharset(data, offset, numFields, 2, "utf-16be");
- }
-
- private static String decodeCharset(byte[] data, int offset, int numFields, int width,
- String charset) throws CodingException
- {
- if (numFields < 0 || (numFields * width + offset) > data.length) {
- // Try to decode the max number of characters in payload
- int padding = offset % width;
- int maxNumFields = (data.length - offset - padding) / width;
- if (maxNumFields < 0) {
- throw new CodingException(charset + " decode failed: offset out of range");
- }
- Log.e(LOG_TAG, charset + " decode error: offset = " + offset + " numFields = "
- + numFields + " data.length = " + data.length + " maxNumFields = "
- + maxNumFields);
- numFields = maxNumFields;
- }
- try {
- return new String(data, offset, numFields * width, charset);
- } catch (java.io.UnsupportedEncodingException ex) {
- throw new CodingException(charset + " decode failed: " + ex);
- }
- }
-
- private static String decode7bitAscii(byte[] data, int offset, int numFields)
- throws CodingException
- {
- try {
- offset *= 8;
- StringBuffer strBuf = new StringBuffer(numFields);
- BitwiseInputStream inStream = new BitwiseInputStream(data);
- int wantedBits = (offset * 8) + (numFields * 7);
- if (inStream.available() < wantedBits) {
- throw new CodingException("insufficient data (wanted " + wantedBits +
- " bits, but only have " + inStream.available() + ")");
- }
- inStream.skip(offset);
- for (int i = 0; i < numFields; i++) {
- int charCode = inStream.read(7);
- if ((charCode >= UserData.ASCII_MAP_BASE_INDEX) &&
- (charCode <= UserData.ASCII_MAP_MAX_INDEX)) {
- strBuf.append(UserData.ASCII_MAP[charCode - UserData.ASCII_MAP_BASE_INDEX]);
- } else if (charCode == UserData.ASCII_NL_INDEX) {
- strBuf.append('\n');
- } else if (charCode == UserData.ASCII_CR_INDEX) {
- strBuf.append('\r');
- } else {
- /* For other charCodes, they are unprintable, and so simply use SPACE. */
- strBuf.append(' ');
- }
- }
- return strBuf.toString();
- } catch (BitwiseInputStream.AccessException ex) {
- throw new CodingException("7bit ASCII decode failed: " + ex);
- }
- }
-
- private static String decode7bitGsm(byte[] data, int offset, int numFields)
- throws CodingException
- {
- // Start reading from the next 7-bit aligned boundary after offset.
- int offsetBits = offset * 8;
- int offsetSeptets = (offsetBits + 6) / 7;
- numFields -= offsetSeptets;
- int paddingBits = (offsetSeptets * 7) - offsetBits;
- String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields, paddingBits,
- 0, 0);
- if (result == null) {
- throw new CodingException("7bit GSM decoding failed");
- }
- return result;
- }
-
- private static String decodeLatin(byte[] data, int offset, int numFields)
- throws CodingException
- {
- return decodeCharset(data, offset, numFields, 1, "ISO-8859-1");
- }
-
- private static void decodeUserDataPayload(UserData userData, boolean hasUserDataHeader)
- throws CodingException
- {
- int offset = 0;
- if (hasUserDataHeader) {
- int udhLen = userData.payload[0] & 0x00FF;
- offset += udhLen + 1;
- byte[] headerData = new byte[udhLen];
- System.arraycopy(userData.payload, 1, headerData, 0, udhLen);
- userData.userDataHeader = SmsHeader.fromByteArray(headerData);
- }
- switch (userData.msgEncoding) {
- case UserData.ENCODING_OCTET:
- /*
- * Octet decoding depends on the carrier service.
- */
- boolean decodingtypeUTF8 = Resources.getSystem()
- .getBoolean(com.android.internal.R.bool.config_sms_utf8_support);
-
- // Strip off any padding bytes, meaning any differences between the length of the
- // array and the target length specified by numFields. This is to avoid any
- // confusion by code elsewhere that only considers the payload array length.
- byte[] payload = new byte[userData.numFields];
- int copyLen = userData.numFields < userData.payload.length
- ? userData.numFields : userData.payload.length;
-
- System.arraycopy(userData.payload, 0, payload, 0, copyLen);
- userData.payload = payload;
-
- if (!decodingtypeUTF8) {
- // There are many devices in the market that send 8bit text sms (latin encoded) as
- // octet encoded.
- userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
- } else {
- userData.payloadStr = decodeUtf8(userData.payload, offset, userData.numFields);
- }
- break;
-
- case UserData.ENCODING_IA5:
- case UserData.ENCODING_7BIT_ASCII:
- userData.payloadStr = decode7bitAscii(userData.payload, offset, userData.numFields);
- break;
- case UserData.ENCODING_UNICODE_16:
- userData.payloadStr = decodeUtf16(userData.payload, offset, userData.numFields);
- break;
- case UserData.ENCODING_GSM_7BIT_ALPHABET:
- userData.payloadStr = decode7bitGsm(userData.payload, offset, userData.numFields);
- break;
- case UserData.ENCODING_LATIN:
- userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
- break;
- default:
- throw new CodingException("unsupported user data encoding ("
- + userData.msgEncoding + ")");
- }
- }
-
- /**
- * IS-91 Voice Mail message decoding
- * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
- * (For character encodings, see TIA/EIA/IS-91, Annex B)
- *
- * Protocol Summary: The user data payload may contain 3-14
- * characters. The first two characters are parsed as a number
- * and indicate the number of voicemails. The third character is
- * either a SPACE or '!' to indicate normal or urgent priority,
- * respectively. Any following characters are treated as normal
- * text user data payload.
- *
- * Note that the characters encoding is 6-bit packed.
- */
- private static void decodeIs91VoicemailStatus(BearerData bData)
- throws BitwiseInputStream.AccessException, CodingException
- {
- BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
- int dataLen = inStream.available() / 6; // 6-bit packed character encoding.
- int numFields = bData.userData.numFields;
- if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) {
- throw new CodingException("IS-91 voicemail status decoding failed");
- }
- try {
- StringBuffer strbuf = new StringBuffer(dataLen);
- while (inStream.available() >= 6) {
- strbuf.append(UserData.ASCII_MAP[inStream.read(6)]);
- }
- String data = strbuf.toString();
- bData.numberOfMessages = Integer.parseInt(data.substring(0, 2));
- char prioCode = data.charAt(2);
- if (prioCode == ' ') {
- bData.priority = PRIORITY_NORMAL;
- } else if (prioCode == '!') {
- bData.priority = PRIORITY_URGENT;
- } else {
- throw new CodingException("IS-91 voicemail status decoding failed: " +
- "illegal priority setting (" + prioCode + ")");
- }
- bData.priorityIndicatorSet = true;
- bData.userData.payloadStr = data.substring(3, numFields - 3);
- } catch (java.lang.NumberFormatException ex) {
- throw new CodingException("IS-91 voicemail status decoding failed: " + ex);
- } catch (java.lang.IndexOutOfBoundsException ex) {
- throw new CodingException("IS-91 voicemail status decoding failed: " + ex);
- }
- }
-
- /**
- * IS-91 Short Message decoding
- * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
- * (For character encodings, see TIA/EIA/IS-91, Annex B)
- *
- * Protocol Summary: The user data payload may contain 1-14
- * characters, which are treated as normal text user data payload.
- * Note that the characters encoding is 6-bit packed.
- */
- private static void decodeIs91ShortMessage(BearerData bData)
- throws BitwiseInputStream.AccessException, CodingException
- {
- BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
- int dataLen = inStream.available() / 6; // 6-bit packed character encoding.
- int numFields = bData.userData.numFields;
- // dataLen may be > 14 characters due to octet padding
- if ((numFields > 14) || (dataLen < numFields)) {
- throw new CodingException("IS-91 short message decoding failed");
- }
- StringBuffer strbuf = new StringBuffer(dataLen);
- for (int i = 0; i < numFields; i++) {
- strbuf.append(UserData.ASCII_MAP[inStream.read(6)]);
- }
- bData.userData.payloadStr = strbuf.toString();
- }
-
- /**
- * IS-91 CLI message (callback number) decoding
- * (See 3GPP2 C.S0015-A, Table 4.3.1.4.1-1)
- *
- * Protocol Summary: The data payload may contain 1-32 digits,
- * encoded using standard 4-bit DTMF, which are treated as a
- * callback number.
- */
- private static void decodeIs91Cli(BearerData bData) throws CodingException {
- BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
- int dataLen = inStream.available() / 4; // 4-bit packed DTMF digit encoding.
- int numFields = bData.userData.numFields;
- if ((dataLen > 14) || (dataLen < 3) || (dataLen < numFields)) {
- throw new CodingException("IS-91 voicemail status decoding failed");
- }
- CdmaSmsAddress addr = new CdmaSmsAddress();
- addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF;
- addr.origBytes = bData.userData.payload;
- addr.numberOfDigits = (byte)numFields;
- decodeSmsAddress(addr);
- bData.callbackNumber = addr;
- }
-
- private static void decodeIs91(BearerData bData)
- throws BitwiseInputStream.AccessException, CodingException
- {
- switch (bData.userData.msgType) {
- case UserData.IS91_MSG_TYPE_VOICEMAIL_STATUS:
- decodeIs91VoicemailStatus(bData);
- break;
- case UserData.IS91_MSG_TYPE_CLI:
- decodeIs91Cli(bData);
- break;
- case UserData.IS91_MSG_TYPE_SHORT_MESSAGE_FULL:
- case UserData.IS91_MSG_TYPE_SHORT_MESSAGE:
- decodeIs91ShortMessage(bData);
- break;
- default:
- throw new CodingException("unsupported IS-91 message type (" +
- bData.userData.msgType + ")");
- }
- }
-
- private static boolean decodeReplyOption(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.userAckReq = (inStream.read(1) == 1);
- bData.deliveryAckReq = (inStream.read(1) == 1);
- bData.readAckReq = (inStream.read(1) == 1);
- bData.reportReq = (inStream.read(1) == 1);
- inStream.skip(4);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "REPLY_OPTION decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- return decodeSuccess;
- }
-
- private static boolean decodeMsgCount(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.numberOfMessages = IccUtils.cdmaBcdByteToInt((byte)inStream.read(8));
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "NUMBER_OF_MESSAGES decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- return decodeSuccess;
- }
-
- private static boolean decodeDepositIndex(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 2 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.depositIndex = (inStream.read(8) << 8) | inStream.read(8);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "MESSAGE_DEPOSIT_INDEX decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- return decodeSuccess;
- }
-
- private static String decodeDtmfSmsAddress(byte[] rawData, int numFields)
- throws CodingException
- {
- /* DTMF 4-bit digit encoding, defined in at
- * 3GPP2 C.S005-D, v2.0, table 2.7.1.3.2.4-4 */
- StringBuffer strBuf = new StringBuffer(numFields);
- for (int i = 0; i < numFields; i++) {
- int val = 0x0F & (rawData[i / 2] >>> (4 - ((i % 2) * 4)));
- if ((val >= 1) && (val <= 9)) strBuf.append(Integer.toString(val, 10));
- else if (val == 10) strBuf.append('0');
- else if (val == 11) strBuf.append('*');
- else if (val == 12) strBuf.append('#');
- else throw new CodingException("invalid SMS address DTMF code (" + val + ")");
- }
- return strBuf.toString();
- }
-
- private static void decodeSmsAddress(CdmaSmsAddress addr) throws CodingException {
- if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
- try {
- /* As specified in 3GPP2 C.S0015-B, v2, 4.5.15 -- actually
- * just 7-bit ASCII encoding, with the MSB being zero. */
- addr.address = new String(addr.origBytes, 0, addr.origBytes.length, "US-ASCII");
- } catch (java.io.UnsupportedEncodingException ex) {
- throw new CodingException("invalid SMS address ASCII code");
- }
- } else {
- addr.address = decodeDtmfSmsAddress(addr.origBytes, addr.numberOfDigits);
- }
- }
-
- private static boolean decodeCallbackNumber(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- int paramBits = inStream.read(8) * 8;
- CdmaSmsAddress addr = new CdmaSmsAddress();
- addr.digitMode = inStream.read(1);
- byte fieldBits = 4;
- byte consumedBits = 1;
- if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
- addr.ton = inStream.read(3);
- addr.numberPlan = inStream.read(4);
- fieldBits = 8;
- consumedBits += 7;
- }
- addr.numberOfDigits = inStream.read(8);
- consumedBits += 8;
- int remainingBits = paramBits - consumedBits;
- int dataBits = addr.numberOfDigits * fieldBits;
- int paddingBits = remainingBits - dataBits;
- if (remainingBits < dataBits) {
- throw new CodingException("CALLBACK_NUMBER subparam encoding size error (" +
- "remainingBits + " + remainingBits + ", dataBits + " +
- dataBits + ", paddingBits + " + paddingBits + ")");
- }
- addr.origBytes = inStream.readByteArray(dataBits);
- inStream.skip(paddingBits);
- decodeSmsAddress(addr);
- bData.callbackNumber = addr;
- return true;
- }
-
- private static boolean decodeMsgStatus(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.errorClass = inStream.read(2);
- bData.messageStatus = inStream.read(6);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "MESSAGE_STATUS decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.messageStatusSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodeMsgCenterTimeStamp(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 6 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.msgCenterTimeStamp = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "MESSAGE_CENTER_TIME_STAMP decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- return decodeSuccess;
- }
-
- private static boolean decodeValidityAbs(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 6 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.validityPeriodAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "VALIDITY_PERIOD_ABSOLUTE decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- return decodeSuccess;
- }
-
- private static boolean decodeDeferredDeliveryAbs(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 6 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.deferredDeliveryTimeAbsolute = TimeStamp.fromByteArray(
- inStream.readByteArray(6 * 8));
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_ABSOLUTE decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- return decodeSuccess;
- }
-
- private static boolean decodeValidityRel(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.deferredDeliveryTimeRelative = inStream.read(8);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "VALIDITY_PERIOD_RELATIVE decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.deferredDeliveryTimeRelativeSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodeDeferredDeliveryRel(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.validityPeriodRelative = inStream.read(8);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_RELATIVE decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.validityPeriodRelativeSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodePrivacyIndicator(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.privacy = inStream.read(2);
- inStream.skip(6);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "PRIVACY_INDICATOR decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.privacyIndicatorSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodeLanguageIndicator(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.language = inStream.read(8);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "LANGUAGE_INDICATOR decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.languageIndicatorSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodeDisplayMode(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.displayMode = inStream.read(2);
- inStream.skip(6);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "DISPLAY_MODE decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.displayModeSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodePriorityIndicator(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.priority = inStream.read(2);
- inStream.skip(6);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "PRIORITY_INDICATOR decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.priorityIndicatorSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodeMsgDeliveryAlert(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.alert = inStream.read(2);
- inStream.skip(6);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "ALERT_ON_MESSAGE_DELIVERY decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.alertIndicatorSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodeUserResponseCode(BearerData bData, BitwiseInputStream inStream)
- throws BitwiseInputStream.AccessException, CodingException
- {
- final int EXPECTED_PARAM_SIZE = 1 * 8;
- boolean decodeSuccess = false;
- int paramBits = inStream.read(8) * 8;
- if (paramBits >= EXPECTED_PARAM_SIZE) {
- paramBits -= EXPECTED_PARAM_SIZE;
- decodeSuccess = true;
- bData.userResponseCode = inStream.read(8);
- }
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "USER_RESPONSE_CODE decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ")");
- }
- inStream.skip(paramBits);
- bData.userResponseCodeSet = decodeSuccess;
- return decodeSuccess;
- }
-
- private static boolean decodeServiceCategoryProgramData(BearerData bData,
- BitwiseInputStream inStream) throws BitwiseInputStream.AccessException, CodingException
- {
- if (inStream.available() < 13) {
- throw new CodingException("SERVICE_CATEGORY_PROGRAM_DATA decode failed: only "
- + inStream.available() + " bits available");
- }
-
- int paramBits = inStream.read(8) * 8;
- int msgEncoding = inStream.read(5);
- paramBits -= 5;
-
- if (inStream.available() < paramBits) {
- throw new CodingException("SERVICE_CATEGORY_PROGRAM_DATA decode failed: only "
- + inStream.available() + " bits available (" + paramBits + " bits expected)");
- }
-
- ArrayList<CdmaSmsCbProgramData> programDataList = new ArrayList<CdmaSmsCbProgramData>();
-
- final int CATEGORY_FIELD_MIN_SIZE = 6 * 8;
- boolean decodeSuccess = false;
- while (paramBits >= CATEGORY_FIELD_MIN_SIZE) {
- int operation = inStream.read(4);
- int category = (inStream.read(8) << 8) | inStream.read(8);
- int language = inStream.read(8);
- int maxMessages = inStream.read(8);
- int alertOption = inStream.read(4);
- int numFields = inStream.read(8);
- paramBits -= CATEGORY_FIELD_MIN_SIZE;
-
- int textBits = getBitsForNumFields(msgEncoding, numFields);
- if (paramBits < textBits) {
- throw new CodingException("category name is " + textBits + " bits in length,"
- + " but there are only " + paramBits + " bits available");
- }
-
- UserData userData = new UserData();
- userData.msgEncoding = msgEncoding;
- userData.msgEncodingSet = true;
- userData.numFields = numFields;
- userData.payload = inStream.readByteArray(textBits);
- paramBits -= textBits;
-
- decodeUserDataPayload(userData, false);
- String categoryName = userData.payloadStr;
- CdmaSmsCbProgramData programData = new CdmaSmsCbProgramData(operation, category,
- language, maxMessages, alertOption, categoryName);
- programDataList.add(programData);
-
- decodeSuccess = true;
- }
-
- if ((! decodeSuccess) || (paramBits > 0)) {
- Log.d(LOG_TAG, "SERVICE_CATEGORY_PROGRAM_DATA decode " +
- (decodeSuccess ? "succeeded" : "failed") +
- " (extra bits = " + paramBits + ')');
- }
-
- inStream.skip(paramBits);
- bData.serviceCategoryProgramData = programDataList;
- return decodeSuccess;
- }
-
- private static int serviceCategoryToCmasMessageClass(int serviceCategory) {
- switch (serviceCategory) {
- case SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT:
- return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT;
-
- case SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT:
- return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT;
-
- case SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT:
- return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT;
-
- case SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY:
- return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY;
-
- case SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE:
- return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST;
-
- default:
- return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
- }
- }
-
- /**
- * Calculates the number of bits to read for the specified number of encoded characters.
- * @param msgEncoding the message encoding to use
- * @param numFields the number of characters to read. For Shift-JIS and Korean encodings,
- * this is the number of bytes to read.
- * @return the number of bits to read from the stream
- * @throws CodingException if the specified encoding is not supported
- */
- private static int getBitsForNumFields(int msgEncoding, int numFields)
- throws CodingException {
- switch (msgEncoding) {
- case UserData.ENCODING_OCTET:
- case UserData.ENCODING_SHIFT_JIS:
- case UserData.ENCODING_KOREAN:
- case UserData.ENCODING_LATIN:
- case UserData.ENCODING_LATIN_HEBREW:
- return numFields * 8;
-
- case UserData.ENCODING_IA5:
- case UserData.ENCODING_7BIT_ASCII:
- case UserData.ENCODING_GSM_7BIT_ALPHABET:
- return numFields * 7;
-
- case UserData.ENCODING_UNICODE_16:
- return numFields * 16;
-
- default:
- throw new CodingException("unsupported message encoding (" + msgEncoding + ')');
- }
- }
-
- /**
- * CMAS message decoding.
- * (See TIA-1149-0-1, CMAS over CDMA)
- *
- * @param serviceCategory is the service category from the SMS envelope
- */
- private static void decodeCmasUserData(BearerData bData, int serviceCategory)
- throws BitwiseInputStream.AccessException, CodingException {
- BitwiseInputStream inStream = new BitwiseInputStream(bData.userData.payload);
- if (inStream.available() < 8) {
- throw new CodingException("emergency CB with no CMAE_protocol_version");
- }
- int protocolVersion = inStream.read(8);
- if (protocolVersion != 0) {
- throw new CodingException("unsupported CMAE_protocol_version " + protocolVersion);
- }
-
- int messageClass = serviceCategoryToCmasMessageClass(serviceCategory);
- int category = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN;
- int responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN;
- int severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
- int urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
- int certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
-
- while (inStream.available() >= 16) {
- int recordType = inStream.read(8);
- int recordLen = inStream.read(8);
- switch (recordType) {
- case 0: // Type 0 elements (Alert text)
- UserData alertUserData = new UserData();
- alertUserData.msgEncoding = inStream.read(5);
- alertUserData.msgEncodingSet = true;
- alertUserData.msgType = 0;
-
- int numFields; // number of chars to decode
- switch (alertUserData.msgEncoding) {
- case UserData.ENCODING_OCTET:
- case UserData.ENCODING_LATIN:
- numFields = recordLen - 1; // subtract 1 byte for encoding
- break;
-
- case UserData.ENCODING_IA5:
- case UserData.ENCODING_7BIT_ASCII:
- case UserData.ENCODING_GSM_7BIT_ALPHABET:
- numFields = ((recordLen * 8) - 5) / 7; // subtract 5 bits for encoding
- break;
-
- case UserData.ENCODING_UNICODE_16:
- numFields = (recordLen - 1) / 2;
- break;
-
- default:
- numFields = 0; // unsupported encoding
- }
-
- alertUserData.numFields = numFields;
- alertUserData.payload = inStream.readByteArray(recordLen * 8 - 5);
- decodeUserDataPayload(alertUserData, false);
- bData.userData = alertUserData;
- break;
-
- case 1: // Type 1 elements
- category = inStream.read(8);
- responseType = inStream.read(8);
- severity = inStream.read(4);
- urgency = inStream.read(4);
- certainty = inStream.read(4);
- inStream.skip(recordLen * 8 - 28);
- break;
-
- default:
- Log.w(LOG_TAG, "skipping unsupported CMAS record type " + recordType);
- inStream.skip(recordLen * 8);
- break;
- }
- }
-
- bData.cmasWarningInfo = new SmsCbCmasInfo(messageClass, category, responseType, severity,
- urgency, certainty);
- }
-
- /**
- * Create BearerData object from serialized representation.
- * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
- *
- * @param smsData byte array of raw encoded SMS bearer data.
- * @return an instance of BearerData.
- */
- public static BearerData decode(byte[] smsData) {
- return decode(smsData, 0);
- }
-
- private static boolean isCmasAlertCategory(int category) {
- return category >= SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT
- && category <= SmsEnvelope.SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE;
- }
-
- /**
- * Create BearerData object from serialized representation.
- * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
- *
- * @param smsData byte array of raw encoded SMS bearer data.
- * @param serviceCategory the envelope service category (for CMAS alert handling)
- * @return an instance of BearerData.
- */
- public static BearerData decode(byte[] smsData, int serviceCategory) {
- try {
- BitwiseInputStream inStream = new BitwiseInputStream(smsData);
- BearerData bData = new BearerData();
- int foundSubparamMask = 0;
- while (inStream.available() > 0) {
- int subparamId = inStream.read(8);
- int subparamIdBit = 1 << subparamId;
- if ((foundSubparamMask & subparamIdBit) != 0) {
- throw new CodingException("illegal duplicate subparameter (" +
- subparamId + ")");
- }
- boolean decodeSuccess;
- switch (subparamId) {
- case SUBPARAM_MESSAGE_IDENTIFIER:
- decodeSuccess = decodeMessageId(bData, inStream);
- break;
- case SUBPARAM_USER_DATA:
- decodeSuccess = decodeUserData(bData, inStream);
- break;
- case SUBPARAM_USER_RESPONSE_CODE:
- decodeSuccess = decodeUserResponseCode(bData, inStream);
- break;
- case SUBPARAM_REPLY_OPTION:
- decodeSuccess = decodeReplyOption(bData, inStream);
- break;
- case SUBPARAM_NUMBER_OF_MESSAGES:
- decodeSuccess = decodeMsgCount(bData, inStream);
- break;
- case SUBPARAM_CALLBACK_NUMBER:
- decodeSuccess = decodeCallbackNumber(bData, inStream);
- break;
- case SUBPARAM_MESSAGE_STATUS:
- decodeSuccess = decodeMsgStatus(bData, inStream);
- break;
- case SUBPARAM_MESSAGE_CENTER_TIME_STAMP:
- decodeSuccess = decodeMsgCenterTimeStamp(bData, inStream);
- break;
- case SUBPARAM_VALIDITY_PERIOD_ABSOLUTE:
- decodeSuccess = decodeValidityAbs(bData, inStream);
- break;
- case SUBPARAM_VALIDITY_PERIOD_RELATIVE:
- decodeSuccess = decodeValidityRel(bData, inStream);
- break;
- case SUBPARAM_DEFERRED_DELIVERY_TIME_ABSOLUTE:
- decodeSuccess = decodeDeferredDeliveryAbs(bData, inStream);
- break;
- case SUBPARAM_DEFERRED_DELIVERY_TIME_RELATIVE:
- decodeSuccess = decodeDeferredDeliveryRel(bData, inStream);
- break;
- case SUBPARAM_PRIVACY_INDICATOR:
- decodeSuccess = decodePrivacyIndicator(bData, inStream);
- break;
- case SUBPARAM_LANGUAGE_INDICATOR:
- decodeSuccess = decodeLanguageIndicator(bData, inStream);
- break;
- case SUBPARAM_MESSAGE_DISPLAY_MODE:
- decodeSuccess = decodeDisplayMode(bData, inStream);
- break;
- case SUBPARAM_PRIORITY_INDICATOR:
- decodeSuccess = decodePriorityIndicator(bData, inStream);
- break;
- case SUBPARAM_ALERT_ON_MESSAGE_DELIVERY:
- decodeSuccess = decodeMsgDeliveryAlert(bData, inStream);
- break;
- case SUBPARAM_MESSAGE_DEPOSIT_INDEX:
- decodeSuccess = decodeDepositIndex(bData, inStream);
- break;
- case SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA:
- decodeSuccess = decodeServiceCategoryProgramData(bData, inStream);
- break;
- default:
- throw new CodingException("unsupported bearer data subparameter ("
- + subparamId + ")");
- }
- if (decodeSuccess) foundSubparamMask |= subparamIdBit;
- }
- if ((foundSubparamMask & (1 << SUBPARAM_MESSAGE_IDENTIFIER)) == 0) {
- throw new CodingException("missing MESSAGE_IDENTIFIER subparam");
- }
- if (bData.userData != null) {
- if (isCmasAlertCategory(serviceCategory)) {
- decodeCmasUserData(bData, serviceCategory);
- } else if (bData.userData.msgEncoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) {
- if ((foundSubparamMask ^
- (1 << SUBPARAM_MESSAGE_IDENTIFIER) ^
- (1 << SUBPARAM_USER_DATA))
- != 0) {
- Log.e(LOG_TAG, "IS-91 must occur without extra subparams (" +
- foundSubparamMask + ")");
- }
- decodeIs91(bData);
- } else {
- decodeUserDataPayload(bData.userData, bData.hasUserDataHeader);
- }
- }
- return bData;
- } catch (BitwiseInputStream.AccessException ex) {
- Log.e(LOG_TAG, "BearerData decode failed: " + ex);
- } catch (CodingException ex) {
- Log.e(LOG_TAG, "BearerData decode failed: " + ex);
- }
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
deleted file mode 100644
index 5f2e561..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsAddress.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma.sms;
-
-import android.util.SparseBooleanArray;
-
-import com.android.internal.telephony.SmsAddress;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.util.HexDump;
-
-public class CdmaSmsAddress extends SmsAddress {
-
- /**
- * Digit Mode Indicator is a 1-bit value that indicates whether
- * the address digits are 4-bit DTMF codes or 8-bit codes. (See
- * 3GPP2 C.S0015-B, v2, 3.4.3.3)
- */
- static public final int DIGIT_MODE_4BIT_DTMF = 0x00;
- static public final int DIGIT_MODE_8BIT_CHAR = 0x01;
-
- public int digitMode;
-
- /**
- * Number Mode Indicator is 1-bit value that indicates whether the
- * address type is a data network address or not. (See 3GPP2
- * C.S0015-B, v2, 3.4.3.3)
- */
- static public final int NUMBER_MODE_NOT_DATA_NETWORK = 0x00;
- static public final int NUMBER_MODE_DATA_NETWORK = 0x01;
-
- public int numberMode;
-
- /**
- * Number Types for data networks.
- * (See 3GPP2 C.S005-D, table2.7.1.3.2.4-2 for complete table)
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3 for data network subset)
- * NOTE: value is stored in the parent class ton field.
- */
- static public final int TON_UNKNOWN = 0x00;
- static public final int TON_INTERNATIONAL_OR_IP = 0x01;
- static public final int TON_NATIONAL_OR_EMAIL = 0x02;
- static public final int TON_NETWORK = 0x03;
- static public final int TON_SUBSCRIBER = 0x04;
- static public final int TON_ALPHANUMERIC = 0x05;
- static public final int TON_ABBREVIATED = 0x06;
- static public final int TON_RESERVED = 0x07;
-
- /**
- * Maximum lengths for fields as defined in ril_cdma_sms.h.
- */
- static public final int SMS_ADDRESS_MAX = 36;
- static public final int SMS_SUBADDRESS_MAX = 36;
-
- /**
- * This field shall be set to the number of address digits
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
- */
- public int numberOfDigits;
-
- /**
- * Numbering Plan identification is a 0 or 4-bit value that
- * indicates which numbering plan identification is set. (See
- * 3GPP2, C.S0015-B, v2, 3.4.3.3 and C.S005-D, table2.7.1.3.2.4-3)
- */
- static public final int NUMBERING_PLAN_UNKNOWN = 0x0;
- static public final int NUMBERING_PLAN_ISDN_TELEPHONY = 0x1;
- //static protected final int NUMBERING_PLAN_DATA = 0x3;
- //static protected final int NUMBERING_PLAN_TELEX = 0x4;
- //static protected final int NUMBERING_PLAN_PRIVATE = 0x9;
-
- public int numberPlan;
-
- /**
- * NOTE: the parsed string address and the raw byte array values
- * are stored in the parent class address and origBytes fields,
- * respectively.
- */
-
- public CdmaSmsAddress(){
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("CdmaSmsAddress ");
- builder.append("{ digitMode=" + digitMode);
- builder.append(", numberMode=" + numberMode);
- builder.append(", numberPlan=" + numberPlan);
- builder.append(", numberOfDigits=" + numberOfDigits);
- builder.append(", ton=" + ton);
- builder.append(", address=\"" + address + "\"");
- builder.append(", origBytes=" + HexDump.toHexString(origBytes));
- builder.append(" }");
- return builder.toString();
- }
-
- /*
- * TODO(cleanup): Refactor the parsing for addresses to better
- * share code and logic with GSM. Also, gather all DTMF/BCD
- * processing code in one place.
- */
-
- private static byte[] parseToDtmf(String address) {
- int digits = address.length();
- byte[] result = new byte[digits];
- for (int i = 0; i < digits; i++) {
- char c = address.charAt(i);
- int val = 0;
- if ((c >= '1') && (c <= '9')) val = c - '0';
- else if (c == '0') val = 10;
- else if (c == '*') val = 11;
- else if (c == '#') val = 12;
- else return null;
- result[i] = (byte)val;
- }
- return result;
- }
-
- private static final char[] numericCharsDialable = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '#'
- };
-
- private static final char[] numericCharsSugar = {
- '(', ')', ' ', '-', '+', '.', '/', '\\'
- };
-
- private static final SparseBooleanArray numericCharDialableMap = new SparseBooleanArray (
- numericCharsDialable.length + numericCharsSugar.length);
- static {
- for (int i = 0; i < numericCharsDialable.length; i++) {
- numericCharDialableMap.put(numericCharsDialable[i], true);
- }
- for (int i = 0; i < numericCharsSugar.length; i++) {
- numericCharDialableMap.put(numericCharsSugar[i], false);
- }
- }
-
- /**
- * Given a numeric address string, return the string without
- * syntactic sugar, meaning parens, spaces, hyphens/minuses, or
- * plus signs. If the input string contains non-numeric
- * non-punctuation characters, return null.
- */
- private static String filterNumericSugar(String address) {
- StringBuilder builder = new StringBuilder();
- int len = address.length();
- for (int i = 0; i < len; i++) {
- char c = address.charAt(i);
- int mapIndex = numericCharDialableMap.indexOfKey(c);
- if (mapIndex < 0) return null;
- if (! numericCharDialableMap.valueAt(mapIndex)) continue;
- builder.append(c);
- }
- return builder.toString();
- }
-
- /**
- * Given a string, return the string without whitespace,
- * including CR/LF.
- */
- private static String filterWhitespace(String address) {
- StringBuilder builder = new StringBuilder();
- int len = address.length();
- for (int i = 0; i < len; i++) {
- char c = address.charAt(i);
- if ((c == ' ') || (c == '\r') || (c == '\n') || (c == '\t')) continue;
- builder.append(c);
- }
- return builder.toString();
- }
-
- /**
- * Given a string, create a corresponding CdmaSmsAddress object.
- *
- * The result will be null if the input string is not
- * representable using printable ASCII.
- *
- * For numeric addresses, the string is cleaned up by removing
- * common punctuation. For alpha addresses, the string is cleaned
- * up by removing whitespace.
- */
- public static CdmaSmsAddress parse(String address) {
- CdmaSmsAddress addr = new CdmaSmsAddress();
- addr.address = address;
- addr.ton = CdmaSmsAddress.TON_UNKNOWN;
- byte[] origBytes = null;
- String filteredAddr = filterNumericSugar(address);
- if (filteredAddr != null) {
- origBytes = parseToDtmf(filteredAddr);
- }
- if (origBytes != null) {
- addr.digitMode = DIGIT_MODE_4BIT_DTMF;
- addr.numberMode = NUMBER_MODE_NOT_DATA_NETWORK;
- if (address.indexOf('+') != -1) {
- addr.ton = TON_INTERNATIONAL_OR_IP;
- }
- } else {
- filteredAddr = filterWhitespace(address);
- origBytes = UserData.stringToAscii(filteredAddr);
- if (origBytes == null) {
- return null;
- }
- addr.digitMode = DIGIT_MODE_8BIT_CHAR;
- addr.numberMode = NUMBER_MODE_DATA_NETWORK;
- if (address.indexOf('@') != -1) {
- addr.ton = TON_NATIONAL_OR_EMAIL;
- }
- }
- addr.origBytes = origBytes;
- addr.numberOfDigits = origBytes.length;
- return addr;
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java
deleted file mode 100644
index f9cebf5..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project. All rights reserved.
- * Copyright (C) 2010 Code Aurora Forum. All rights reserved.
- *
- * 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.cdma.sms;
-
-public class CdmaSmsSubaddress {
- public int type;
-
- public byte odd;
-
- public byte[] origBytes;
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
deleted file mode 100644
index f73df56..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma.sms;
-
-
-import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
-
-public final class SmsEnvelope {
- /**
- * Message Types
- * (See 3GPP2 C.S0015-B 3.4.1)
- */
- static public final int MESSAGE_TYPE_POINT_TO_POINT = 0x00;
- static public final int MESSAGE_TYPE_BROADCAST = 0x01;
- static public final int MESSAGE_TYPE_ACKNOWLEDGE = 0x02;
-
- /**
- * Supported Teleservices
- * (See 3GPP2 N.S0005 and TIA-41)
- */
- static public final int TELESERVICE_NOT_SET = 0x0000;
- static public final int TELESERVICE_WMT = 0x1002;
- static public final int TELESERVICE_VMN = 0x1003;
- static public final int TELESERVICE_WAP = 0x1004;
- static public final int TELESERVICE_WEMT = 0x1005;
- static public final int TELESERVICE_SCPT = 0x1006;
-
- /**
- * The following are defined as extensions to the standard teleservices
- */
- // Voice mail notification through Message Waiting Indication in CDMA mode or Analog mode.
- // Defined in 3GPP2 C.S-0005, 3.7.5.6, an Info Record containing an 8-bit number with the
- // number of messages waiting, it's used by some CDMA carriers for a voice mail count.
- static public final int TELESERVICE_MWI = 0x40000;
-
- // Service Categories for Cell Broadcast, see 3GPP2 C.R1001 table 9.3.1-1
- // static final int SERVICE_CATEGORY_EMERGENCY = 0x0001;
- //...
-
- // CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1
- public static final int SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 0x1000;
- public static final int SERVICE_CATEGORY_CMAS_EXTREME_THREAT = 0x1001;
- public static final int SERVICE_CATEGORY_CMAS_SEVERE_THREAT = 0x1002;
- public static final int SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003;
- public static final int SERVICE_CATEGORY_CMAS_TEST_MESSAGE = 0x1004;
- public static final int SERVICE_CATEGORY_CMAS_LAST_RESERVED_VALUE = 0x10ff;
-
- /**
- * Provides the type of a SMS message like point to point, broadcast or acknowledge
- */
- public int messageType;
-
- /**
- * The 16-bit Teleservice parameter identifies which upper layer service access point is sending
- * or receiving the message.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.1)
- */
- public int teleService = TELESERVICE_NOT_SET;
-
- /**
- * The 16-bit service category parameter identifies the type of service provided
- * by the SMS message.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.2)
- */
- public int serviceCategory;
-
- /**
- * The origination address identifies the originator of the SMS message.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
- */
- public CdmaSmsAddress origAddress;
-
- /**
- * The destination address identifies the target of the SMS message.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
- */
- public CdmaSmsAddress destAddress;
-
- /**
- * The origination subaddress identifies the originator of the SMS message.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
- */
- public CdmaSmsSubaddress origSubaddress;
-
- /**
- * The 6-bit bearer reply parameter is used to request the return of a
- * SMS Acknowledge Message.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.5)
- */
- public int bearerReply;
-
- /**
- * Cause Code values:
- * The cause code parameters are an indication whether an SMS error has occurred and if so,
- * whether the condition is considered temporary or permanent.
- * ReplySeqNo 6-bit value,
- * ErrorClass 2-bit value,
- * CauseCode 0-bit or 8-bit value
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.6)
- */
- public byte replySeqNo;
- public byte errorClass;
- public byte causeCode;
-
- /**
- * encoded bearer data
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.7)
- */
- public byte[] bearerData;
-
- public SmsEnvelope() {
- // nothing to see here
- }
-
-}
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
deleted file mode 100644
index 599c2b3..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma.sms;
-
-import android.util.SparseIntArray;
-
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.util.HexDump;
-
-public class UserData {
-
- /**
- * User data encoding types.
- * (See 3GPP2 C.R1001-F, v1.0, table 9.1-1)
- */
- public static final int ENCODING_OCTET = 0x00;
- public static final int ENCODING_IS91_EXTENDED_PROTOCOL = 0x01;
- public static final int ENCODING_7BIT_ASCII = 0x02;
- public static final int ENCODING_IA5 = 0x03;
- public static final int ENCODING_UNICODE_16 = 0x04;
- public static final int ENCODING_SHIFT_JIS = 0x05;
- public static final int ENCODING_KOREAN = 0x06;
- public static final int ENCODING_LATIN_HEBREW = 0x07;
- public static final int ENCODING_LATIN = 0x08;
- public static final int ENCODING_GSM_7BIT_ALPHABET = 0x09;
- public static final int ENCODING_GSM_DCS = 0x0A;
-
- /**
- * IS-91 message types.
- * (See TIA/EIS/IS-91-A-ENGL 1999, table 3.7.1.1-3)
- */
- public static final int IS91_MSG_TYPE_VOICEMAIL_STATUS = 0x82;
- public static final int IS91_MSG_TYPE_SHORT_MESSAGE_FULL = 0x83;
- public static final int IS91_MSG_TYPE_CLI = 0x84;
- public static final int IS91_MSG_TYPE_SHORT_MESSAGE = 0x85;
-
- /**
- * US ASCII character mapping table.
- *
- * This table contains only the printable ASCII characters, with a
- * 0x20 offset, meaning that the ASCII SPACE character is at index
- * 0, with the resulting code of 0x20.
- *
- * Note this mapping is also equivalent to that used by both the
- * IA5 and the IS-91 encodings. For the former this is defined
- * using CCITT Rec. T.50 Tables 1 and 3. For the latter IS 637 B,
- * Table 4.3.1.4.1-1 -- and note the encoding uses only 6 bits,
- * and hence only maps entries up to the '_' character.
- *
- */
- public static final char[] ASCII_MAP = {
- ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
- '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
- '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'};
-
- /**
- * Character to use when forced to encode otherwise unencodable
- * characters, meaning those not in the respective ASCII or GSM
- * 7-bit encoding tables. Current choice is SPACE, which is 0x20
- * in both the GSM-7bit and ASCII-7bit encodings.
- */
- static final byte UNENCODABLE_7_BIT_CHAR = 0x20;
-
- /**
- * Only elements between these indices in the ASCII table are printable.
- */
- public static final int PRINTABLE_ASCII_MIN_INDEX = 0x20;
- public static final int ASCII_NL_INDEX = 0x0A;
- public static final int ASCII_CR_INDEX = 0x0D;
- public static final SparseIntArray charToAscii = new SparseIntArray();
- static {
- for (int i = 0; i < ASCII_MAP.length; i++) {
- charToAscii.put(ASCII_MAP[i], PRINTABLE_ASCII_MIN_INDEX + i);
- }
- charToAscii.put('\n', ASCII_NL_INDEX);
- charToAscii.put('\r', ASCII_CR_INDEX);
- }
-
- /*
- * TODO(cleanup): Move this very generic functionality somewhere
- * more general.
- */
- /**
- * Given a string generate a corresponding ASCII-encoded byte
- * array, but limited to printable characters. If the input
- * contains unprintable characters, return null.
- */
- public static byte[] stringToAscii(String str) {
- int len = str.length();
- byte[] result = new byte[len];
- for (int i = 0; i < len; i++) {
- int charCode = charToAscii.get(str.charAt(i), -1);
- if (charCode == -1) return null;
- result[i] = (byte)charCode;
- }
- return result;
- }
-
- /**
- * Mapping for ASCII values less than 32 are flow control signals
- * and not used here.
- */
- public static final int ASCII_MAP_BASE_INDEX = 0x20;
- public static final int ASCII_MAP_MAX_INDEX = ASCII_MAP_BASE_INDEX + ASCII_MAP.length - 1;
-
- /**
- * Contains the data header of the user data
- */
- public SmsHeader userDataHeader;
-
- /**
- * Contains the data encoding type for the SMS message
- */
- public int msgEncoding;
- public boolean msgEncodingSet = false;
-
- public int msgType;
-
- /**
- * Number of invalid bits in the last byte of data.
- */
- public int paddingBits;
-
- public int numFields;
-
- /**
- * Contains the user data of a SMS message
- * (See 3GPP2 C.S0015-B, v2, 4.5.2)
- */
- public byte[] payload;
- public String payloadStr;
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("UserData ");
- builder.append("{ msgEncoding=" + (msgEncodingSet ? msgEncoding : "unset"));
- builder.append(", msgType=" + msgType);
- builder.append(", paddingBits=" + paddingBits);
- builder.append(", numFields=" + numFields);
- builder.append(", userDataHeader=" + userDataHeader);
- builder.append(", payload='" + HexDump.toHexString(payload) + "'");
- builder.append(", payloadStr='" + payloadStr + "'");
- builder.append(" }");
- return builder.toString();
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/package.html b/telephony/java/com/android/internal/telephony/cdma/sms/package.html
deleted file mode 100644
index b2bc736..0000000
--- a/telephony/java/com/android/internal/telephony/cdma/sms/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Provides CDMA-specific features for text/data/PDU SMS messages
-@hide
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java
deleted file mode 100644
index af2ad48..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.gsm;
-
-/**
- * Call fail causes from TS 24.008 .
- * These are mostly the cause codes we need to distinguish for the UI.
- * See 22.001 Annex F.4 for mapping of cause codes to local tones.
- *
- * {@hide}
- *
- */
-public interface CallFailCause {
- // Unassigned/Unobtainable number
- static final int UNOBTAINABLE_NUMBER = 1;
-
- static final int NORMAL_CLEARING = 16;
- // Busy Tone
- static final int USER_BUSY = 17;
-
- // No Tone
- static final int NUMBER_CHANGED = 22;
- static final int STATUS_ENQUIRY = 30;
- static final int NORMAL_UNSPECIFIED = 31;
-
- // Congestion Tone
- static final int NO_CIRCUIT_AVAIL = 34;
- static final int TEMPORARY_FAILURE = 41;
- static final int SWITCHING_CONGESTION = 42;
- static final int CHANNEL_NOT_AVAIL = 44;
- static final int QOS_NOT_AVAIL = 49;
- static final int BEARER_NOT_AVAIL = 58;
-
- // others
- static final int ACM_LIMIT_EXCEEDED = 68;
- static final int CALL_BARRED = 240;
- static final int FDN_BLOCKED = 241;
- static final int ERROR_UNSPECIFIED = 0xffff;
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
deleted file mode 100644
index 6e9cd51..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ /dev/null
@@ -1,1507 +0,0 @@
-/*
- * 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.gsm;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Telephony;
-import android.telephony.CellLocation;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import com.android.internal.telephony.CallTracker;
-import android.text.TextUtils;
-import android.util.Log;
-
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE;
-import static com.android.internal.telephony.CommandsInterface.CF_ACTION_REGISTRATION;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_ALL_CONDITIONAL;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_NO_REPLY;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_NOT_REACHABLE;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_BUSY;
-import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
-import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
-
-import com.android.internal.telephony.cat.CatService;
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallForwardInfo;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.IccVmNotSupportedException;
-import com.android.internal.telephony.ServiceStateTracker;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@hide}
- */
-public class GSMPhone extends PhoneBase {
- // NOTE that LOG_TAG here is "GSM", which means that log messages
- // from this file will go into the radio log rather than the main
- // log. (Use "adb logcat -b radio" to see them.)
- static final String LOG_TAG = "GSM";
- private static final boolean LOCAL_DEBUG = true;
- private static final boolean VDBG = false; /* STOP SHIP if true */
-
- // Key used to read/write current ciphering state
- public static final String CIPHERING_KEY = "ciphering_key";
- // Key used to read/write voice mail number
- public static final String VM_NUMBER = "vm_number_key";
- // Key used to read/write the SIM IMSI used for storing the voice mail
- public static final String VM_SIM_IMSI = "vm_sim_imsi_key";
-
- // Instance Variables
- GsmCallTracker mCT;
- GsmServiceStateTracker mSST;
- ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>();
- SimPhoneBookInterfaceManager mSimPhoneBookIntManager;
- SimSmsInterfaceManager mSimSmsIntManager;
- PhoneSubInfo mSubInfo;
-
-
- Registrant mPostDialHandler;
-
- /** List of Registrants to receive Supplementary Service Notifications. */
- RegistrantList mSsnRegistrants = new RegistrantList();
-
- Thread debugPortThread;
- ServerSocket debugSocket;
-
- private String mImei;
- private String mImeiSv;
- private String mVmNumber;
-
-
- // Constructors
-
- public
- GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier) {
- this(context,ci,notifier, false);
- }
-
- public
- GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {
- super(notifier, context, ci, unitTestMode);
-
- if (ci instanceof SimulatedRadioControl) {
- mSimulatedRadioControl = (SimulatedRadioControl) ci;
- }
-
- mCM.setPhoneType(Phone.PHONE_TYPE_GSM);
- mIccCard.set(UiccController.getInstance(this).getIccCard());
- mIccRecords = mIccCard.get().getIccRecords();
- mCT = new GsmCallTracker(this);
- mSST = new GsmServiceStateTracker (this);
- mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
- mDataConnectionTracker = new GsmDataConnectionTracker (this);
- if (!unitTestMode) {
- mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this);
- mSimSmsIntManager = new SimSmsInterfaceManager(this, mSMS);
- mSubInfo = new PhoneSubInfo(this);
- }
-
- mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
- registerForSimRecordEvents();
- mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mCM.registerForOn(this, EVENT_RADIO_ON, null);
- mCM.setOnUSSD(this, EVENT_USSD, null);
- mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
- mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
-
- if (false) {
- try {
- //debugSocket = new LocalServerSocket("com.android.internal.telephony.debug");
- debugSocket = new ServerSocket();
- debugSocket.setReuseAddress(true);
- debugSocket.bind (new InetSocketAddress("127.0.0.1", 6666));
-
- debugPortThread
- = new Thread(
- new Runnable() {
- public void run() {
- for(;;) {
- try {
- Socket sock;
- sock = debugSocket.accept();
- Log.i(LOG_TAG, "New connection; resetting radio");
- mCM.resetRadio(null);
- sock.close();
- } catch (IOException ex) {
- Log.w(LOG_TAG,
- "Exception accepting socket", ex);
- }
- }
- }
- },
- "GSMPhone debug");
-
- debugPortThread.start();
-
- } catch (IOException ex) {
- Log.w(LOG_TAG, "Failure to open com.android.internal.telephony.debug socket", ex);
- }
- }
-
- //Change the system property
- SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
- new Integer(Phone.PHONE_TYPE_GSM).toString());
- }
-
- @Override
- public void dispose() {
- synchronized(PhoneProxy.lockForRadioTechnologyChange) {
- super.dispose();
-
- //Unregister from all former registered events
- mCM.unregisterForAvailable(this); //EVENT_RADIO_AVAILABLE
- unregisterForSimRecordEvents();
- mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
- mCM.unregisterForOn(this); //EVENT_RADIO_ON
- mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK
- mCM.unSetOnUSSD(this);
- mCM.unSetOnSuppServiceNotification(this);
-
- mPendingMMIs.clear();
-
- //Force all referenced classes to unregister their former registered events
- mCT.dispose();
- mDataConnectionTracker.dispose();
- mSST.dispose();
- mSimPhoneBookIntManager.dispose();
- mSimSmsIntManager.dispose();
- mSubInfo.dispose();
- }
- }
-
- @Override
- public void removeReferences() {
- Log.d(LOG_TAG, "removeReferences");
- mSimulatedRadioControl = null;
- mSimPhoneBookIntManager = null;
- mSimSmsIntManager = null;
- mSubInfo = null;
- mCT = null;
- mSST = null;
- super.removeReferences();
- }
-
- protected void finalize() {
- if(LOCAL_DEBUG) Log.d(LOG_TAG, "GSMPhone finalized");
- }
-
-
- public ServiceState
- getServiceState() {
- return mSST.ss;
- }
-
- public CellLocation getCellLocation() {
- return mSST.cellLoc;
- }
-
- public Phone.State getState() {
- return mCT.state;
- }
-
- public String getPhoneName() {
- return "GSM";
- }
-
- public int getPhoneType() {
- return Phone.PHONE_TYPE_GSM;
- }
-
- public SignalStrength getSignalStrength() {
- return mSST.mSignalStrength;
- }
-
- public CallTracker getCallTracker() {
- return mCT;
- }
-
- public ServiceStateTracker getServiceStateTracker() {
- return mSST;
- }
-
- public List<? extends MmiCode>
- getPendingMmiCodes() {
- return mPendingMMIs;
- }
-
- public DataState getDataConnectionState(String apnType) {
- DataState ret = DataState.DISCONNECTED;
-
- if (mSST == null) {
- // Radio Technology Change is ongoning, dispose() and removeReferences() have
- // already been called
-
- ret = DataState.DISCONNECTED;
- } else if (mSST.getCurrentGprsState()
- != ServiceState.STATE_IN_SERVICE) {
- // If we're out of service, open TCP sockets may still work
- // but no data will flow
- ret = DataState.DISCONNECTED;
- } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false ||
- mDataConnectionTracker.isApnTypeActive(apnType) == false) {
- //TODO: isApnTypeActive() is just checking whether ApnContext holds
- // Dataconnection or not. Checking each ApnState below should
- // provide the same state. Calling isApnTypeActive() can be removed.
- ret = DataState.DISCONNECTED;
- } else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */
- switch (mDataConnectionTracker.getState(apnType)) {
- case FAILED:
- case IDLE:
- ret = DataState.DISCONNECTED;
- break;
-
- case CONNECTED:
- case DISCONNECTING:
- if ( mCT.state != Phone.State.IDLE
- && !mSST.isConcurrentVoiceAndDataAllowed()) {
- ret = DataState.SUSPENDED;
- } else {
- ret = DataState.CONNECTED;
- }
- break;
-
- case INITING:
- case CONNECTING:
- case SCANNING:
- ret = DataState.CONNECTING;
- break;
- }
- }
-
- return ret;
- }
-
- public DataActivityState getDataActivityState() {
- DataActivityState ret = DataActivityState.NONE;
-
- if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) {
- switch (mDataConnectionTracker.getActivity()) {
- case DATAIN:
- ret = DataActivityState.DATAIN;
- break;
-
- case DATAOUT:
- ret = DataActivityState.DATAOUT;
- break;
-
- case DATAINANDOUT:
- ret = DataActivityState.DATAINANDOUT;
- break;
- }
- }
-
- return ret;
- }
-
- /**
- * Notify any interested party of a Phone state change {@link Phone.State}
- */
- /*package*/ void notifyPhoneStateChanged() {
- mNotifier.notifyPhoneState(this);
- }
-
- /**
- * Notify registrants of a change in the call state. This notifies changes in {@link Call.State}
- * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged.
- */
- /*package*/ void notifyPreciseCallStateChanged() {
- /* we'd love it if this was package-scoped*/
- super.notifyPreciseCallStateChangedP();
- }
-
- /*package*/ void
- notifyNewRingingConnection(Connection c) {
- /* we'd love it if this was package-scoped*/
- super.notifyNewRingingConnectionP(c);
- }
-
- /*package*/ void
- notifyDisconnect(Connection cn) {
- mDisconnectRegistrants.notifyResult(cn);
- }
-
- void notifyUnknownConnection() {
- mUnknownConnectionRegistrants.notifyResult(this);
- }
-
- void notifySuppServiceFailed(SuppService code) {
- mSuppServiceFailedRegistrants.notifyResult(code);
- }
-
- /*package*/ void
- notifyServiceStateChanged(ServiceState ss) {
- super.notifyServiceStateChangedP(ss);
- }
-
- /*package*/
- void notifyLocationChanged() {
- mNotifier.notifyCellLocation(this);
- }
-
- /*package*/ void
- notifySignalStrength() {
- mNotifier.notifySignalStrength(this);
- }
-
- public void
- notifyCallForwardingIndicator() {
- mNotifier.notifyCallForwardingChanged(this);
- }
-
- // override for allowing access from other classes of this package
- /**
- * {@inheritDoc}
- */
- public final void
- setSystemProperty(String property, String value) {
- super.setSystemProperty(property, value);
- }
-
- public void registerForSuppServiceNotification(
- Handler h, int what, Object obj) {
- mSsnRegistrants.addUnique(h, what, obj);
- if (mSsnRegistrants.size() == 1) mCM.setSuppServiceNotifications(true, null);
- }
-
- public void unregisterForSuppServiceNotification(Handler h) {
- mSsnRegistrants.remove(h);
- if (mSsnRegistrants.size() == 0) mCM.setSuppServiceNotifications(false, null);
- }
-
- public void
- acceptCall() throws CallStateException {
- mCT.acceptCall();
- }
-
- public void
- rejectCall() throws CallStateException {
- mCT.rejectCall();
- }
-
- public void
- switchHoldingAndActive() throws CallStateException {
- mCT.switchWaitingOrHoldingAndActive();
- }
-
- public boolean canConference() {
- return mCT.canConference();
- }
-
- public boolean canDial() {
- return mCT.canDial();
- }
-
- public void conference() throws CallStateException {
- mCT.conference();
- }
-
- public void clearDisconnected() {
- mCT.clearDisconnected();
- }
-
- public boolean canTransfer() {
- return mCT.canTransfer();
- }
-
- public void explicitCallTransfer() throws CallStateException {
- mCT.explicitCallTransfer();
- }
-
- public GsmCall
- getForegroundCall() {
- return mCT.foregroundCall;
- }
-
- public GsmCall
- getBackgroundCall() {
- return mCT.backgroundCall;
- }
-
- public GsmCall
- getRingingCall() {
- return mCT.ringingCall;
- }
-
- private boolean handleCallDeflectionIncallSupplementaryService(
- String dialString) throws CallStateException {
- if (dialString.length() > 1) {
- return false;
- }
-
- if (getRingingCall().getState() != GsmCall.State.IDLE) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 0: rejectCall");
- try {
- mCT.rejectCall();
- } catch (CallStateException e) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "reject failed", e);
- notifySuppServiceFailed(Phone.SuppService.REJECT);
- }
- } else if (getBackgroundCall().getState() != GsmCall.State.IDLE) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "MmiCode 0: hangupWaitingOrBackground");
- mCT.hangupWaitingOrBackground();
- }
-
- return true;
- }
-
- private boolean handleCallWaitingIncallSupplementaryService(
- String dialString) throws CallStateException {
- int len = dialString.length();
-
- if (len > 2) {
- return false;
- }
-
- GsmCall call = (GsmCall) getForegroundCall();
-
- try {
- if (len > 1) {
- char ch = dialString.charAt(1);
- int callIndex = ch - '0';
-
- if (callIndex >= 1 && callIndex <= GsmCallTracker.MAX_CONNECTIONS) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "MmiCode 1: hangupConnectionByIndex " +
- callIndex);
- mCT.hangupConnectionByIndex(call, callIndex);
- }
- } else {
- if (call.getState() != GsmCall.State.IDLE) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "MmiCode 1: hangup foreground");
- //mCT.hangupForegroundResumeBackground();
- mCT.hangup(call);
- } else {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "MmiCode 1: switchWaitingOrHoldingAndActive");
- mCT.switchWaitingOrHoldingAndActive();
- }
- }
- } catch (CallStateException e) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "hangup failed", e);
- notifySuppServiceFailed(Phone.SuppService.HANGUP);
- }
-
- return true;
- }
-
- private boolean handleCallHoldIncallSupplementaryService(String dialString)
- throws CallStateException {
- int len = dialString.length();
-
- if (len > 2) {
- return false;
- }
-
- GsmCall call = (GsmCall) getForegroundCall();
-
- if (len > 1) {
- try {
- char ch = dialString.charAt(1);
- int callIndex = ch - '0';
- GsmConnection conn = mCT.getConnectionByIndex(call, callIndex);
-
- // gsm index starts at 1, up to 5 connections in a call,
- if (conn != null && callIndex >= 1 && callIndex <= GsmCallTracker.MAX_CONNECTIONS) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 2: separate call "+
- callIndex);
- mCT.separate(conn);
- } else {
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "separate: invalid call index "+
- callIndex);
- notifySuppServiceFailed(Phone.SuppService.SEPARATE);
- }
- } catch (CallStateException e) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "separate failed", e);
- notifySuppServiceFailed(Phone.SuppService.SEPARATE);
- }
- } else {
- try {
- if (getRingingCall().getState() != GsmCall.State.IDLE) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "MmiCode 2: accept ringing call");
- mCT.acceptCall();
- } else {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "MmiCode 2: switchWaitingOrHoldingAndActive");
- mCT.switchWaitingOrHoldingAndActive();
- }
- } catch (CallStateException e) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "switch failed", e);
- notifySuppServiceFailed(Phone.SuppService.SWITCH);
- }
- }
-
- return true;
- }
-
- private boolean handleMultipartyIncallSupplementaryService(
- String dialString) throws CallStateException {
- if (dialString.length() > 1) {
- return false;
- }
-
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 3: merge calls");
- try {
- conference();
- } catch (CallStateException e) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "conference failed", e);
- notifySuppServiceFailed(Phone.SuppService.CONFERENCE);
- }
- return true;
- }
-
- private boolean handleEctIncallSupplementaryService(String dialString)
- throws CallStateException {
-
- int len = dialString.length();
-
- if (len != 1) {
- return false;
- }
-
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 4: explicit call transfer");
- try {
- explicitCallTransfer();
- } catch (CallStateException e) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "transfer failed", e);
- notifySuppServiceFailed(Phone.SuppService.TRANSFER);
- }
- return true;
- }
-
- private boolean handleCcbsIncallSupplementaryService(String dialString)
- throws CallStateException {
- if (dialString.length() > 1) {
- return false;
- }
-
- Log.i(LOG_TAG, "MmiCode 5: CCBS not supported!");
- // Treat it as an "unknown" service.
- notifySuppServiceFailed(Phone.SuppService.UNKNOWN);
- return true;
- }
-
- public boolean handleInCallMmiCommands(String dialString)
- throws CallStateException {
- if (!isInCall()) {
- return false;
- }
-
- if (TextUtils.isEmpty(dialString)) {
- return false;
- }
-
- boolean result = false;
- char ch = dialString.charAt(0);
- switch (ch) {
- case '0':
- result = handleCallDeflectionIncallSupplementaryService(
- dialString);
- break;
- case '1':
- result = handleCallWaitingIncallSupplementaryService(
- dialString);
- break;
- case '2':
- result = handleCallHoldIncallSupplementaryService(dialString);
- break;
- case '3':
- result = handleMultipartyIncallSupplementaryService(dialString);
- break;
- case '4':
- result = handleEctIncallSupplementaryService(dialString);
- break;
- case '5':
- result = handleCcbsIncallSupplementaryService(dialString);
- break;
- default:
- break;
- }
-
- return result;
- }
-
- boolean isInCall() {
- GsmCall.State foregroundCallState = getForegroundCall().getState();
- GsmCall.State backgroundCallState = getBackgroundCall().getState();
- GsmCall.State ringingCallState = getRingingCall().getState();
-
- return (foregroundCallState.isAlive() ||
- backgroundCallState.isAlive() ||
- ringingCallState.isAlive());
- }
-
- public Connection
- dial(String dialString) throws CallStateException {
- return dial(dialString, null);
- }
-
- public Connection
- dial (String dialString, UUSInfo uusInfo) throws CallStateException {
- // Need to make sure dialString gets parsed properly
- String newDialString = PhoneNumberUtils.stripSeparators(dialString);
-
- // handle in-call MMI first if applicable
- if (handleInCallMmiCommands(newDialString)) {
- return null;
- }
-
- // Only look at the Network portion for mmi
- String networkPortion = PhoneNumberUtils.extractNetworkPortionAlt(newDialString);
- GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this);
- if (LOCAL_DEBUG) Log.d(LOG_TAG,
- "dialing w/ mmi '" + mmi + "'...");
-
- if (mmi == null) {
- return mCT.dial(newDialString, uusInfo);
- } else if (mmi.isTemporaryModeCLIR()) {
- return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode(), uusInfo);
- } else {
- mPendingMMIs.add(mmi);
- mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
- mmi.processCode();
-
- // FIXME should this return null or something else?
- return null;
- }
- }
-
- public boolean handlePinMmi(String dialString) {
- GsmMmiCode mmi = GsmMmiCode.newFromDialString(dialString, this);
-
- if (mmi != null && mmi.isPinCommand()) {
- mPendingMMIs.add(mmi);
- mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
- mmi.processCode();
- return true;
- }
-
- return false;
- }
-
- public void sendUssdResponse(String ussdMessge) {
- GsmMmiCode mmi = GsmMmiCode.newFromUssdUserInput(ussdMessge, this);
- mPendingMMIs.add(mmi);
- mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
- mmi.sendUssd(ussdMessge);
- }
-
- public void
- sendDtmf(char c) {
- if (!PhoneNumberUtils.is12Key(c)) {
- Log.e(LOG_TAG,
- "sendDtmf called with invalid character '" + c + "'");
- } else {
- if (mCT.state == Phone.State.OFFHOOK) {
- mCM.sendDtmf(c, null);
- }
- }
- }
-
- public void
- startDtmf(char c) {
- if (!PhoneNumberUtils.is12Key(c)) {
- Log.e(LOG_TAG,
- "startDtmf called with invalid character '" + c + "'");
- } else {
- mCM.startDtmf(c, null);
- }
- }
-
- public void
- stopDtmf() {
- mCM.stopDtmf(null);
- }
-
- public void
- sendBurstDtmf(String dtmfString) {
- Log.e(LOG_TAG, "[GSMPhone] sendBurstDtmf() is a CDMA method");
- }
-
- public void
- setRadioPower(boolean power) {
- mSST.setRadioPower(power);
- }
-
- private void storeVoiceMailNumber(String number) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- SharedPreferences.Editor editor = sp.edit();
- editor.putString(VM_NUMBER, number);
- editor.apply();
- setVmSimImsi(getSubscriberId());
- }
-
- public String getVoiceMailNumber() {
- // Read from the SIM. If its null, try reading from the shared preference area.
- String number = mIccRecords.getVoiceMailNumber();
- if (TextUtils.isEmpty(number)) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- number = sp.getString(VM_NUMBER, null);
- }
- return number;
- }
-
- private String getVmSimImsi() {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- return sp.getString(VM_SIM_IMSI, null);
- }
-
- private void setVmSimImsi(String imsi) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- SharedPreferences.Editor editor = sp.edit();
- editor.putString(VM_SIM_IMSI, imsi);
- editor.apply();
- }
-
- public String getVoiceMailAlphaTag() {
- String ret;
-
- ret = mIccRecords.getVoiceMailAlphaTag();
-
- if (ret == null || ret.length() == 0) {
- return mContext.getText(
- com.android.internal.R.string.defaultVoiceMailAlphaTag).toString();
- }
-
- return ret;
- }
-
- public String getDeviceId() {
- return mImei;
- }
-
- public String getDeviceSvn() {
- return mImeiSv;
- }
-
- public String getImei() {
- return mImei;
- }
-
- public String getEsn() {
- Log.e(LOG_TAG, "[GSMPhone] getEsn() is a CDMA method");
- return "0";
- }
-
- public String getMeid() {
- Log.e(LOG_TAG, "[GSMPhone] getMeid() is a CDMA method");
- return "0";
- }
-
- public String getSubscriberId() {
- return mIccRecords.getIMSI();
- }
-
- public String getLine1Number() {
- return mIccRecords.getMsisdnNumber();
- }
-
- @Override
- public String getMsisdn() {
- return mIccRecords.getMsisdnNumber();
- }
-
- public String getLine1AlphaTag() {
- return mIccRecords.getMsisdnAlphaTag();
- }
-
- public void setLine1Number(String alphaTag, String number, Message onComplete) {
- mIccRecords.setMsisdnNumber(alphaTag, number, onComplete);
- }
-
- public void setVoiceMailNumber(String alphaTag,
- String voiceMailNumber,
- Message onComplete) {
-
- Message resp;
- mVmNumber = voiceMailNumber;
- resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
- mIccRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
- }
-
- private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) {
- switch (commandInterfaceCFReason) {
- case CF_REASON_UNCONDITIONAL:
- case CF_REASON_BUSY:
- case CF_REASON_NO_REPLY:
- case CF_REASON_NOT_REACHABLE:
- case CF_REASON_ALL:
- case CF_REASON_ALL_CONDITIONAL:
- return true;
- default:
- return false;
- }
- }
-
- private boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) {
- switch (commandInterfaceCFAction) {
- case CF_ACTION_DISABLE:
- case CF_ACTION_ENABLE:
- case CF_ACTION_REGISTRATION:
- case CF_ACTION_ERASURE:
- return true;
- default:
- return false;
- }
- }
-
- protected boolean isCfEnable(int action) {
- return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION);
- }
-
- public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
- if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "requesting call forwarding query.");
- Message resp;
- if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
- resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete);
- } else {
- resp = onComplete;
- }
- mCM.queryCallForwardStatus(commandInterfaceCFReason,0,null,resp);
- }
- }
-
- public void setCallForwardingOption(int commandInterfaceCFAction,
- int commandInterfaceCFReason,
- String dialingNumber,
- int timerSeconds,
- Message onComplete) {
- if ( (isValidCommandInterfaceCFAction(commandInterfaceCFAction)) &&
- (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) {
-
- Message resp;
- if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) {
- resp = obtainMessage(EVENT_SET_CALL_FORWARD_DONE,
- isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, onComplete);
- } else {
- resp = onComplete;
- }
- mCM.setCallForward(commandInterfaceCFAction,
- commandInterfaceCFReason,
- CommandsInterface.SERVICE_CLASS_VOICE,
- dialingNumber,
- timerSeconds,
- resp);
- }
- }
-
- public void getOutgoingCallerIdDisplay(Message onComplete) {
- mCM.getCLIR(onComplete);
- }
-
- public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
- Message onComplete) {
- mCM.setCLIR(commandInterfaceCLIRMode,
- obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete));
- }
-
- public void getCallWaiting(Message onComplete) {
- //As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service
- //class parameter in call waiting interrogation to network
- mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_NONE, onComplete);
- }
-
- public void setCallWaiting(boolean enable, Message onComplete) {
- mCM.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
- }
-
- public void
- getAvailableNetworks(Message response) {
- mCM.getAvailableNetworks(response);
- }
-
- /**
- * Small container class used to hold information relevant to
- * the carrier selection process. operatorNumeric can be ""
- * if we are looking for automatic selection. operatorAlphaLong is the
- * corresponding operator name.
- */
- private static class NetworkSelectMessage {
- public Message message;
- public String operatorNumeric;
- public String operatorAlphaLong;
- }
-
- public void
- setNetworkSelectionModeAutomatic(Message response) {
- // wrap the response message in our own message along with
- // an empty string (to indicate automatic selection) for the
- // operator's id.
- NetworkSelectMessage nsm = new NetworkSelectMessage();
- nsm.message = response;
- nsm.operatorNumeric = "";
- nsm.operatorAlphaLong = "";
-
- // get the message
- Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
- if (LOCAL_DEBUG)
- Log.d(LOG_TAG, "wrapping and sending message to connect automatically");
-
- mCM.setNetworkSelectionModeAutomatic(msg);
- }
-
- public void
- selectNetworkManually(OperatorInfo network,
- Message response) {
- // wrap the response message in our own message along with
- // the operator's id.
- NetworkSelectMessage nsm = new NetworkSelectMessage();
- nsm.message = response;
- nsm.operatorNumeric = network.getOperatorNumeric();
- nsm.operatorAlphaLong = network.getOperatorAlphaLong();
-
- // get the message
- Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
-
- mCM.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
- }
-
- public void
- getNeighboringCids(Message response) {
- mCM.getNeighboringCids(response);
- }
-
- public void setOnPostDialCharacter(Handler h, int what, Object obj) {
- mPostDialHandler = new Registrant(h, what, obj);
- }
-
- public void setMute(boolean muted) {
- mCT.setMute(muted);
- }
-
- public boolean getMute() {
- return mCT.getMute();
- }
-
- public void getDataCallList(Message response) {
- mCM.getDataCallList(response);
- }
-
- public void updateServiceLocation() {
- mSST.enableSingleLocationUpdate();
- }
-
- public void enableLocationUpdates() {
- mSST.enableLocationUpdates();
- }
-
- public void disableLocationUpdates() {
- mSST.disableLocationUpdates();
- }
-
- public boolean getDataRoamingEnabled() {
- return mDataConnectionTracker.getDataOnRoamingEnabled();
- }
-
- public void setDataRoamingEnabled(boolean enable) {
- mDataConnectionTracker.setDataOnRoamingEnabled(enable);
- }
-
- /**
- * Removes the given MMI from the pending list and notifies
- * registrants that it is complete.
- * @param mmi MMI that is done
- */
- /*package*/ void
- onMMIDone(GsmMmiCode mmi) {
- /* Only notify complete if it's on the pending list.
- * Otherwise, it's already been handled (eg, previously canceled).
- * The exception is cancellation of an incoming USSD-REQUEST, which is
- * not on the list.
- */
- if (mPendingMMIs.remove(mmi) || mmi.isUssdRequest()) {
- mMmiCompleteRegistrants.notifyRegistrants(
- new AsyncResult(null, mmi, null));
- }
- }
-
-
- private void
- onNetworkInitiatedUssd(GsmMmiCode mmi) {
- mMmiCompleteRegistrants.notifyRegistrants(
- new AsyncResult(null, mmi, null));
- }
-
-
- /** ussdMode is one of CommandsInterface.USSD_MODE_* */
- private void
- onIncomingUSSD (int ussdMode, String ussdMessage) {
- boolean isUssdError;
- boolean isUssdRequest;
-
- isUssdRequest
- = (ussdMode == CommandsInterface.USSD_MODE_REQUEST);
-
- isUssdError
- = (ussdMode != CommandsInterface.USSD_MODE_NOTIFY
- && ussdMode != CommandsInterface.USSD_MODE_REQUEST);
-
- // See comments in GsmMmiCode.java
- // USSD requests aren't finished until one
- // of these two events happen
- GsmMmiCode found = null;
- for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
- if(mPendingMMIs.get(i).isPendingUSSD()) {
- found = mPendingMMIs.get(i);
- break;
- }
- }
-
- if (found != null) {
- // Complete pending USSD
-
- if (isUssdError) {
- found.onUssdFinishedError();
- } else {
- found.onUssdFinished(ussdMessage, isUssdRequest);
- }
- } else { // pending USSD not found
- // The network may initiate its own USSD request
-
- // ignore everything that isnt a Notify or a Request
- // also, discard if there is no message to present
- if (!isUssdError && ussdMessage != null) {
- GsmMmiCode mmi;
- mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage,
- isUssdRequest,
- GSMPhone.this);
- onNetworkInitiatedUssd(mmi);
- }
- }
- }
-
- /**
- * Make sure the network knows our preferred setting.
- */
- protected void syncClirSetting() {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- int clirSetting = sp.getInt(CLIR_KEY, -1);
- if (clirSetting >= 0) {
- mCM.setCLIR(clirSetting, null);
- }
- }
-
- @Override
- public void handleMessage (Message msg) {
- AsyncResult ar;
- Message onComplete;
-
- switch (msg.what) {
- case EVENT_RADIO_AVAILABLE: {
- mCM.getBasebandVersion(
- obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE));
-
- mCM.getIMEI(obtainMessage(EVENT_GET_IMEI_DONE));
- mCM.getIMEISV(obtainMessage(EVENT_GET_IMEISV_DONE));
- }
- break;
-
- case EVENT_RADIO_ON:
- break;
-
- case EVENT_REGISTERED_TO_NETWORK:
- syncClirSetting();
- break;
-
- case EVENT_SIM_RECORDS_LOADED:
- updateCurrentCarrierInProvider();
-
- // Check if this is a different SIM than the previous one. If so unset the
- // voice mail number.
- String imsi = getVmSimImsi();
- String imsiFromSIM = getSubscriberId();
- if (imsi != null && imsiFromSIM != null && !imsiFromSIM.equals(imsi)) {
- storeVoiceMailNumber(null);
- setVmSimImsi(null);
- }
-
- break;
-
- case EVENT_GET_BASEBAND_VERSION_DONE:
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- break;
- }
-
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
- setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result);
- break;
-
- case EVENT_GET_IMEI_DONE:
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- break;
- }
-
- mImei = (String)ar.result;
- break;
-
- case EVENT_GET_IMEISV_DONE:
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- break;
- }
-
- mImeiSv = (String)ar.result;
- break;
-
- case EVENT_USSD:
- ar = (AsyncResult)msg.obj;
-
- String[] ussdResult = (String[]) ar.result;
-
- if (ussdResult.length > 1) {
- try {
- onIncomingUSSD(Integer.parseInt(ussdResult[0]), ussdResult[1]);
- } catch (NumberFormatException e) {
- Log.w(LOG_TAG, "error parsing USSD");
- }
- }
- break;
-
- case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
- // Some MMI requests (eg USSD) are not completed
- // within the course of a CommandsInterface request
- // If the radio shuts off or resets while one of these
- // is pending, we need to clean up.
-
- for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) {
- if (mPendingMMIs.get(i).isPendingUSSD()) {
- mPendingMMIs.get(i).onUssdFinishedError();
- }
- }
- break;
-
- case EVENT_SSN:
- ar = (AsyncResult)msg.obj;
- SuppServiceNotification not = (SuppServiceNotification) ar.result;
- mSsnRegistrants.notifyRegistrants(ar);
- break;
-
- case EVENT_SET_CALL_FORWARD_DONE:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- mIccRecords.setVoiceCallForwardingFlag(1, msg.arg1 == 1);
- }
- onComplete = (Message) ar.userObj;
- if (onComplete != null) {
- AsyncResult.forMessage(onComplete, ar.result, ar.exception);
- onComplete.sendToTarget();
- }
- break;
-
- case EVENT_SET_VM_NUMBER_DONE:
- ar = (AsyncResult)msg.obj;
- if (IccVmNotSupportedException.class.isInstance(ar.exception)) {
- storeVoiceMailNumber(mVmNumber);
- ar.exception = null;
- }
- onComplete = (Message) ar.userObj;
- if (onComplete != null) {
- AsyncResult.forMessage(onComplete, ar.result, ar.exception);
- onComplete.sendToTarget();
- }
- break;
-
-
- case EVENT_GET_CALL_FORWARD_DONE:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- handleCfuQueryResult((CallForwardInfo[])ar.result);
- }
- onComplete = (Message) ar.userObj;
- if (onComplete != null) {
- AsyncResult.forMessage(onComplete, ar.result, ar.exception);
- onComplete.sendToTarget();
- }
- break;
-
- case EVENT_NEW_ICC_SMS:
- ar = (AsyncResult)msg.obj;
- mSMS.dispatchMessage((SmsMessage)ar.result);
- break;
-
- case EVENT_SET_NETWORK_AUTOMATIC:
- ar = (AsyncResult)msg.obj;
- setNetworkSelectionModeAutomatic((Message)ar.result);
- break;
-
- case EVENT_ICC_RECORD_EVENTS:
- ar = (AsyncResult)msg.obj;
- processIccRecordEvents((Integer)ar.result);
- break;
-
- // handle the select network completion callbacks.
- case EVENT_SET_NETWORK_MANUAL_COMPLETE:
- case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
- handleSetSelectNetwork((AsyncResult) msg.obj);
- break;
-
- case EVENT_SET_CLIR_COMPLETE:
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- saveClirSetting(msg.arg1);
- }
- onComplete = (Message) ar.userObj;
- if (onComplete != null) {
- AsyncResult.forMessage(onComplete, ar.result, ar.exception);
- onComplete.sendToTarget();
- }
- break;
-
- default:
- super.handleMessage(msg);
- }
- }
-
- private void processIccRecordEvents(int eventCode) {
- switch (eventCode) {
- case SIMRecords.EVENT_CFI:
- notifyCallForwardingIndicator();
- break;
- case SIMRecords.EVENT_MWI:
- notifyMessageWaitingIndicator();
- break;
- }
- }
-
- /**
- * Sets the "current" field in the telephony provider according to the SIM's operator
- *
- * @return true for success; false otherwise.
- */
- boolean updateCurrentCarrierInProvider() {
- if (mIccRecords != null) {
- try {
- Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
- ContentValues map = new ContentValues();
- map.put(Telephony.Carriers.NUMERIC, mIccRecords.getOperatorNumeric());
- mContext.getContentResolver().insert(uri, map);
- return true;
- } catch (SQLException e) {
- Log.e(LOG_TAG, "Can't store current operator", e);
- }
- }
- return false;
- }
-
- /**
- * Used to track the settings upon completion of the network change.
- */
- private void handleSetSelectNetwork(AsyncResult ar) {
- // look for our wrapper within the asyncresult, skip the rest if it
- // is null.
- if (!(ar.userObj instanceof NetworkSelectMessage)) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "unexpected result from user object.");
- return;
- }
-
- NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
-
- // found the object, now we send off the message we had originally
- // attached to the request.
- if (nsm.message != null) {
- if (LOCAL_DEBUG) Log.d(LOG_TAG, "sending original message to recipient");
- AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
- nsm.message.sendToTarget();
- }
-
- // open the shared preferences editor, and write the value.
- // nsm.operatorNumeric is "" if we're in automatic.selection.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- SharedPreferences.Editor editor = sp.edit();
- editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric);
- editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong);
-
- // commit and log the result.
- if (! editor.commit()) {
- Log.e(LOG_TAG, "failed to commit network selection preference");
- }
-
- }
-
- /**
- * Saves CLIR setting so that we can re-apply it as necessary
- * (in case the RIL resets it across reboots).
- */
- public void saveClirSetting(int commandInterfaceCLIRMode) {
- // open the shared preferences editor, and write the value.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- SharedPreferences.Editor editor = sp.edit();
- editor.putInt(CLIR_KEY, commandInterfaceCLIRMode);
-
- // commit and log the result.
- if (! editor.commit()) {
- Log.e(LOG_TAG, "failed to commit CLIR preference");
- }
- }
-
- private void handleCfuQueryResult(CallForwardInfo[] infos) {
- if (infos == null || infos.length == 0) {
- // Assume the default is not active
- // Set unconditional CFF in SIM to false
- mIccRecords.setVoiceCallForwardingFlag(1, false);
- } else {
- for (int i = 0, s = infos.length; i < s; i++) {
- if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) {
- mIccRecords.setVoiceCallForwardingFlag(1, (infos[i].status == 1));
- // should only have the one
- break;
- }
- }
- }
- }
-
- /**
- * Retrieves the PhoneSubInfo of the GSMPhone
- */
- public PhoneSubInfo getPhoneSubInfo(){
- return mSubInfo;
- }
-
- /**
- * Retrieves the IccSmsInterfaceManager of the GSMPhone
- */
- public IccSmsInterfaceManager getIccSmsInterfaceManager(){
- return mSimSmsIntManager;
- }
-
- /**
- * Retrieves the IccPhoneBookInterfaceManager of the GSMPhone
- */
- public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
- return mSimPhoneBookIntManager;
- }
-
- /**
- * Activate or deactivate cell broadcast SMS.
- *
- * @param activate 0 = activate, 1 = deactivate
- * @param response Callback message is empty on completion
- */
- public void activateCellBroadcastSms(int activate, Message response) {
- Log.e(LOG_TAG, "[GSMPhone] activateCellBroadcastSms() is obsolete; use SmsManager");
- response.sendToTarget();
- }
-
- /**
- * Query the current configuration of cdma cell broadcast SMS.
- *
- * @param response Callback message is empty on completion
- */
- public void getCellBroadcastSmsConfig(Message response) {
- Log.e(LOG_TAG, "[GSMPhone] getCellBroadcastSmsConfig() is obsolete; use SmsManager");
- response.sendToTarget();
- }
-
- /**
- * Configure cdma cell broadcast SMS.
- *
- * @param response Callback message is empty on completion
- */
- public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response) {
- Log.e(LOG_TAG, "[GSMPhone] setCellBroadcastSmsConfig() is obsolete; use SmsManager");
- response.sendToTarget();
- }
-
- public boolean isCspPlmnEnabled() {
- return mIccRecords.isCspPlmnEnabled();
- }
-
- private void registerForSimRecordEvents() {
- mIccRecords.registerForNetworkSelectionModeAutomatic(
- this, EVENT_SET_NETWORK_AUTOMATIC, null);
- mIccRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null);
- mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
- mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
- }
-
- private void unregisterForSimRecordEvents() {
- mIccRecords.unregisterForNetworkSelectionModeAutomatic(this);
- mIccRecords.unregisterForNewSms(this);
- mIccRecords.unregisterForRecordsEvents(this);
- mIccRecords.unregisterForRecordsLoaded(this);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("GSMPhone extends:");
- super.dump(fd, pw, args);
- pw.println(" mCT=" + mCT);
- pw.println(" mSST=" + mSST);
- pw.println(" mPendingMMIs=" + mPendingMMIs);
- pw.println(" mSimPhoneBookIntManager=" + mSimPhoneBookIntManager);
- pw.println(" mSimSmsIntManager=" + mSimSmsIntManager);
- pw.println(" mSubInfo=" + mSubInfo);
- if (VDBG) pw.println(" mImei=" + mImei);
- if (VDBG) pw.println(" mImeiSv=" + mImeiSv);
- pw.println(" mVmNumber=" + mVmNumber);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCall.java b/telephony/java/com/android/internal/telephony/gsm/GsmCall.java
deleted file mode 100644
index 58124a2..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCall.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * 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.gsm;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DriverCall;
-import com.android.internal.telephony.Phone;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@hide}
- */
-class GsmCall extends Call {
- /*************************** Instance Variables **************************/
-
- /*package*/ ArrayList<Connection> connections = new ArrayList<Connection>();
- /*package*/ GsmCallTracker owner;
-
-
- /***************************** Class Methods *****************************/
-
- static State
- stateFromDCState (DriverCall.State dcState) {
- switch (dcState) {
- case ACTIVE: return State.ACTIVE;
- case HOLDING: return State.HOLDING;
- case DIALING: return State.DIALING;
- case ALERTING: return State.ALERTING;
- case INCOMING: return State.INCOMING;
- case WAITING: return State.WAITING;
- default: throw new RuntimeException ("illegal call state:" + dcState);
- }
- }
-
-
- /****************************** Constructors *****************************/
- /*package*/
- GsmCall (GsmCallTracker owner) {
- this.owner = owner;
- }
-
- public void dispose() {
- }
-
- /************************** Overridden from Call *************************/
-
- public List<Connection>
- getConnections() {
- // FIXME should return Collections.unmodifiableList();
- return connections;
- }
-
- public Phone
- getPhone() {
- return owner.phone;
- }
-
- public boolean
- isMultiparty() {
- return connections.size() > 1;
- }
-
- /** Please note: if this is the foreground call and a
- * background call exists, the background call will be resumed
- * because an AT+CHLD=1 will be sent
- */
- public void
- hangup() throws CallStateException {
- owner.hangup(this);
- }
-
- public String
- toString() {
- return state.toString();
- }
-
- //***** Called from GsmConnection
-
- /*package*/ void
- attach(Connection conn, DriverCall dc) {
- connections.add(conn);
-
- state = stateFromDCState (dc.state);
- }
-
- /*package*/ void
- attachFake(Connection conn, State state) {
- connections.add(conn);
-
- this.state = state;
- }
-
- /**
- * Called by GsmConnection when it has disconnected
- */
- void
- connectionDisconnected(GsmConnection conn) {
- if (state != State.DISCONNECTED) {
- /* If only disconnected connections remain, we are disconnected*/
-
- boolean hasOnlyDisconnectedConnections = true;
-
- for (int i = 0, s = connections.size() ; i < s; i ++) {
- if (connections.get(i).getState()
- != State.DISCONNECTED
- ) {
- hasOnlyDisconnectedConnections = false;
- break;
- }
- }
-
- if (hasOnlyDisconnectedConnections) {
- state = State.DISCONNECTED;
- }
- }
- }
-
-
- /*package*/ void
- detach(GsmConnection conn) {
- connections.remove(conn);
-
- if (connections.size() == 0) {
- state = State.IDLE;
- }
- }
-
- /*package*/ boolean
- update (GsmConnection conn, DriverCall dc) {
- State newState;
- boolean changed = false;
-
- newState = stateFromDCState(dc.state);
-
- if (newState != state) {
- state = newState;
- changed = true;
- }
-
- return changed;
- }
-
- /**
- * @return true if there's no space in this call for additional
- * connections to be added via "conference"
- */
- /*package*/ boolean
- isFull() {
- return connections.size() == GsmCallTracker.MAX_CONNECTIONS_PER_CALL;
- }
-
- //***** Called from GsmCallTracker
-
-
- /**
- * Called when this Call is being hung up locally (eg, user pressed "end")
- * Note that at this point, the hangup request has been dispatched to the radio
- * but no response has yet been received so update() has not yet been called
- */
- void
- onHangupLocal() {
- for (int i = 0, s = connections.size()
- ; i < s; i++
- ) {
- GsmConnection cn = (GsmConnection)connections.get(i);
-
- cn.onHangupLocal();
- }
- state = State.DISCONNECTING;
- }
-
- /**
- * Called when it's time to clean up disconnected Connection objects
- */
- void
- clearDisconnected() {
- for (int i = connections.size() - 1 ; i >= 0 ; i--) {
- GsmConnection cn = (GsmConnection)connections.get(i);
-
- if (cn.getState() == State.DISCONNECTED) {
- connections.remove(i);
- }
- }
-
- if (connections.size() == 0) {
- state = State.IDLE;
- }
- }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
deleted file mode 100644
index e86d853..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
- * 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.gsm;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.gsm.GsmCellLocation;
-import android.util.EventLog;
-import android.util.Log;
-
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.CallTracker;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DriverCall;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.GsmCall;
-import com.android.internal.telephony.gsm.GsmConnection;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public final class GsmCallTracker extends CallTracker {
- static final String LOG_TAG = "GSM";
- private static final boolean REPEAT_POLLING = false;
-
- private static final boolean DBG_POLL = false;
-
- //***** Constants
-
- static final int MAX_CONNECTIONS = 7; // only 7 connections allowed in GSM
- static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call
-
- //***** Instance Variables
- GsmConnection connections[] = new GsmConnection[MAX_CONNECTIONS];
- RegistrantList voiceCallEndedRegistrants = new RegistrantList();
- RegistrantList voiceCallStartedRegistrants = new RegistrantList();
-
-
- // connections dropped during last poll
- ArrayList<GsmConnection> droppedDuringPoll
- = new ArrayList<GsmConnection>(MAX_CONNECTIONS);
-
- GsmCall ringingCall = new GsmCall(this);
- // A call that is ringing or (call) waiting
- GsmCall foregroundCall = new GsmCall(this);
- GsmCall backgroundCall = new GsmCall(this);
-
- GsmConnection pendingMO;
- boolean hangupPendingMO;
-
- GSMPhone phone;
-
- boolean desiredMute = false; // false = mute off
-
- Phone.State state = Phone.State.IDLE;
-
-
-
- //***** Events
-
-
- //***** Constructors
-
- GsmCallTracker (GSMPhone phone) {
- this.phone = phone;
- cm = phone.mCM;
-
- cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
-
- cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
- cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
- }
-
- public void dispose() {
- //Unregister for all events
- cm.unregisterForCallStateChanged(this);
- cm.unregisterForOn(this);
- cm.unregisterForNotAvailable(this);
-
- for(GsmConnection c : connections) {
- try {
- if(c != null) hangup(c);
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "unexpected error on hangup during dispose");
- }
- }
-
- try {
- if(pendingMO != null) hangup(pendingMO);
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "unexpected error on hangup during dispose");
- }
-
- clearDisconnected();
- }
-
- protected void finalize() {
- Log.d(LOG_TAG, "GsmCallTracker finalized");
- }
-
- //***** Instance Methods
-
- //***** Public Methods
- public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- voiceCallStartedRegistrants.add(r);
- }
-
- public void unregisterForVoiceCallStarted(Handler h) {
- voiceCallStartedRegistrants.remove(h);
- }
-
- public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- voiceCallEndedRegistrants.add(r);
- }
-
- public void unregisterForVoiceCallEnded(Handler h) {
- voiceCallEndedRegistrants.remove(h);
- }
-
- private void
- fakeHoldForegroundBeforeDial() {
- List<Connection> connCopy;
-
- // We need to make a copy here, since fakeHoldBeforeDial()
- // modifies the lists, and we don't want to reverse the order
- connCopy = (List<Connection>) foregroundCall.connections.clone();
-
- for (int i = 0, s = connCopy.size() ; i < s ; i++) {
- GsmConnection conn = (GsmConnection)connCopy.get(i);
-
- conn.fakeHoldBeforeDial();
- }
- }
-
- /**
- * clirMode is one of the CLIR_ constants
- */
- synchronized Connection
- dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException {
- // note that this triggers call state changed notif
- clearDisconnected();
-
- if (!canDial()) {
- throw new CallStateException("cannot dial in current state");
- }
-
- // The new call must be assigned to the foreground call.
- // That call must be idle, so place anything that's
- // there on hold
- if (foregroundCall.getState() == GsmCall.State.ACTIVE) {
- // this will probably be done by the radio anyway
- // but the dial might fail before this happens
- // and we need to make sure the foreground call is clear
- // for the newly dialed connection
- switchWaitingOrHoldingAndActive();
-
- // Fake local state so that
- // a) foregroundCall is empty for the newly dialed connection
- // b) hasNonHangupStateChanged remains false in the
- // next poll, so that we don't clear a failed dialing call
- fakeHoldForegroundBeforeDial();
- }
-
- if (foregroundCall.getState() != GsmCall.State.IDLE) {
- //we should have failed in !canDial() above before we get here
- throw new CallStateException("cannot dial in current state");
- }
-
- pendingMO = new GsmConnection(phone.getContext(), checkForTestEmergencyNumber(dialString),
- this, foregroundCall);
- hangupPendingMO = false;
-
- if (pendingMO.address == null || pendingMO.address.length() == 0
- || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0
- ) {
- // Phone number is invalid
- pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
-
- // handlePollCalls() will notice this call not present
- // and will mark it as dropped.
- pollCallsWhenSafe();
- } else {
- // Always unmute when initiating a new call
- setMute(false);
-
- cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage());
- }
-
- updatePhoneState();
- phone.notifyPreciseCallStateChanged();
-
- return pendingMO;
- }
-
- Connection
- dial(String dialString) throws CallStateException {
- return dial(dialString, CommandsInterface.CLIR_DEFAULT, null);
- }
-
- Connection
- dial(String dialString, UUSInfo uusInfo) throws CallStateException {
- return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo);
- }
-
- Connection
- dial(String dialString, int clirMode) throws CallStateException {
- return dial(dialString, clirMode, null);
- }
-
- void
- acceptCall () throws CallStateException {
- // FIXME if SWITCH fails, should retry with ANSWER
- // in case the active/holding call disappeared and this
- // is no longer call waiting
-
- if (ringingCall.getState() == GsmCall.State.INCOMING) {
- Log.i("phone", "acceptCall: incoming...");
- // Always unmute when answering a new call
- setMute(false);
- cm.acceptCall(obtainCompleteMessage());
- } else if (ringingCall.getState() == GsmCall.State.WAITING) {
- setMute(false);
- switchWaitingOrHoldingAndActive();
- } else {
- throw new CallStateException("phone not ringing");
- }
- }
-
- void
- rejectCall () throws CallStateException {
- // AT+CHLD=0 means "release held or UDUB"
- // so if the phone isn't ringing, this could hang up held
- if (ringingCall.getState().isRinging()) {
- cm.rejectCall(obtainCompleteMessage());
- } else {
- throw new CallStateException("phone not ringing");
- }
- }
-
- void
- switchWaitingOrHoldingAndActive() throws CallStateException {
- // Should we bother with this check?
- if (ringingCall.getState() == GsmCall.State.INCOMING) {
- throw new CallStateException("cannot be in the incoming state");
- } else {
- cm.switchWaitingOrHoldingAndActive(
- obtainCompleteMessage(EVENT_SWITCH_RESULT));
- }
- }
-
- void
- conference() throws CallStateException {
- cm.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT));
- }
-
- void
- explicitCallTransfer() throws CallStateException {
- cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT));
- }
-
- void
- clearDisconnected() {
- internalClearDisconnected();
-
- updatePhoneState();
- phone.notifyPreciseCallStateChanged();
- }
-
- boolean
- canConference() {
- return foregroundCall.getState() == GsmCall.State.ACTIVE
- && backgroundCall.getState() == GsmCall.State.HOLDING
- && !backgroundCall.isFull()
- && !foregroundCall.isFull();
- }
-
- boolean
- canDial() {
- boolean ret;
- int serviceState = phone.getServiceState().getState();
- String disableCall = SystemProperties.get(
- TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
-
- ret = (serviceState != ServiceState.STATE_POWER_OFF)
- && pendingMO == null
- && !ringingCall.isRinging()
- && !disableCall.equals("true")
- && (!foregroundCall.getState().isAlive()
- || !backgroundCall.getState().isAlive());
-
- return ret;
- }
-
- boolean
- canTransfer() {
- return foregroundCall.getState() == GsmCall.State.ACTIVE
- && backgroundCall.getState() == GsmCall.State.HOLDING;
- }
-
- //***** Private Instance Methods
-
- private void
- internalClearDisconnected() {
- ringingCall.clearDisconnected();
- foregroundCall.clearDisconnected();
- backgroundCall.clearDisconnected();
- }
-
- /**
- * Obtain a message to use for signalling "invoke getCurrentCalls() when
- * this operation and all other pending operations are complete
- */
- private Message
- obtainCompleteMessage() {
- return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);
- }
-
- /**
- * Obtain a message to use for signalling "invoke getCurrentCalls() when
- * this operation and all other pending operations are complete
- */
- private Message
- obtainCompleteMessage(int what) {
- pendingOperations++;
- lastRelevantPoll = null;
- needsPoll = true;
-
- if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" +
- pendingOperations + ", needsPoll=" + needsPoll);
-
- return obtainMessage(what);
- }
-
- private void
- operationComplete() {
- pendingOperations--;
-
- if (DBG_POLL) log("operationComplete: pendingOperations=" +
- pendingOperations + ", needsPoll=" + needsPoll);
-
- if (pendingOperations == 0 && needsPoll) {
- lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
- cm.getCurrentCalls(lastRelevantPoll);
- } else if (pendingOperations < 0) {
- // this should never happen
- Log.e(LOG_TAG,"GsmCallTracker.pendingOperations < 0");
- pendingOperations = 0;
- }
- }
-
- private void
- updatePhoneState() {
- Phone.State oldState = state;
-
- if (ringingCall.isRinging()) {
- state = Phone.State.RINGING;
- } else if (pendingMO != null ||
- !(foregroundCall.isIdle() && backgroundCall.isIdle())) {
- state = Phone.State.OFFHOOK;
- } else {
- state = Phone.State.IDLE;
- }
-
- if (state == Phone.State.IDLE && oldState != state) {
- voiceCallEndedRegistrants.notifyRegistrants(
- new AsyncResult(null, null, null));
- } else if (oldState == Phone.State.IDLE && oldState != state) {
- voiceCallStartedRegistrants.notifyRegistrants (
- new AsyncResult(null, null, null));
- }
-
- if (state != oldState) {
- phone.notifyPhoneStateChanged();
- }
- }
-
- protected synchronized void
- handlePollCalls(AsyncResult ar) {
- List polledCalls;
-
- if (ar.exception == null) {
- polledCalls = (List)ar.result;
- } else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
- // just a dummy empty ArrayList to cause the loop
- // to hang up all the calls
- polledCalls = new ArrayList();
- } else {
- // Radio probably wasn't ready--try again in a bit
- // But don't keep polling if the channel is closed
- pollCallsAfterDelay();
- return;
- }
-
- Connection newRinging = null; //or waiting
- boolean hasNonHangupStateChanged = false; // Any change besides
- // a dropped connection
- boolean needsPollDelay = false;
- boolean unknownConnectionAppeared = false;
-
- for (int i = 0, curDC = 0, dcSize = polledCalls.size()
- ; i < connections.length; i++) {
- GsmConnection conn = connections[i];
- DriverCall dc = null;
-
- // polledCall list is sparse
- if (curDC < dcSize) {
- dc = (DriverCall) polledCalls.get(curDC);
-
- if (dc.index == i+1) {
- curDC++;
- } else {
- dc = null;
- }
- }
-
- if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
- conn+", dc=" + dc);
-
- if (conn == null && dc != null) {
- // Connection appeared in CLCC response that we don't know about
- if (pendingMO != null && pendingMO.compareTo(dc)) {
-
- if (DBG_POLL) log("poll: pendingMO=" + pendingMO);
-
- // It's our pending mobile originating call
- connections[i] = pendingMO;
- pendingMO.index = i;
- pendingMO.update(dc);
- pendingMO = null;
-
- // Someone has already asked to hangup this call
- if (hangupPendingMO) {
- hangupPendingMO = false;
- try {
- if (Phone.DEBUG_PHONE) log(
- "poll: hangupPendingMO, hangup conn " + i);
- hangup(connections[i]);
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "unexpected error on hangup");
- }
-
- // Do not continue processing this poll
- // Wait for hangup and repoll
- return;
- }
- } else {
- connections[i] = new GsmConnection(phone.getContext(), dc, this, i);
-
- // it's a ringing call
- if (connections[i].getCall() == ringingCall) {
- newRinging = connections[i];
- } else {
- // Something strange happened: a call appeared
- // which is neither a ringing call or one we created.
- // Either we've crashed and re-attached to an existing
- // call, or something else (eg, SIM) initiated the call.
-
- Log.i(LOG_TAG,"Phantom call appeared " + dc);
-
- // If it's a connected call, set the connect time so that
- // it's non-zero. It may not be accurate, but at least
- // it won't appear as a Missed Call.
- if (dc.state != DriverCall.State.ALERTING
- && dc.state != DriverCall.State.DIALING) {
- connections[i].connectTime = System.currentTimeMillis();
- }
-
- unknownConnectionAppeared = true;
- }
- }
- hasNonHangupStateChanged = true;
- } else if (conn != null && dc == null) {
- // Connection missing in CLCC response that we were
- // tracking.
- droppedDuringPoll.add(conn);
- // Dropped connections are removed from the CallTracker
- // list but kept in the GsmCall list
- connections[i] = null;
- } else if (conn != null && dc != null && !conn.compareTo(dc)) {
- // Connection in CLCC response does not match what
- // we were tracking. Assume dropped call and new call
-
- droppedDuringPoll.add(conn);
- connections[i] = new GsmConnection (phone.getContext(), dc, this, i);
-
- if (connections[i].getCall() == ringingCall) {
- newRinging = connections[i];
- } // else something strange happened
- hasNonHangupStateChanged = true;
- } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */
- boolean changed;
- changed = conn.update(dc);
- hasNonHangupStateChanged = hasNonHangupStateChanged || changed;
- }
-
- if (REPEAT_POLLING) {
- if (dc != null) {
- // FIXME with RIL, we should not need this anymore
- if ((dc.state == DriverCall.State.DIALING
- /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
- || (dc.state == DriverCall.State.ALERTING
- /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
- || (dc.state == DriverCall.State.INCOMING
- /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
- || (dc.state == DriverCall.State.WAITING
- /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)
- ) {
- // Sometimes there's no unsolicited notification
- // for state transitions
- needsPollDelay = true;
- }
- }
- }
- }
-
- // This is the first poll after an ATD.
- // We expect the pending call to appear in the list
- // If it does not, we land here
- if (pendingMO != null) {
- Log.d(LOG_TAG,"Pending MO dropped before poll fg state:"
- + foregroundCall.getState());
-
- droppedDuringPoll.add(pendingMO);
- pendingMO = null;
- hangupPendingMO = false;
- }
-
- if (newRinging != null) {
- phone.notifyNewRingingConnection(newRinging);
- }
-
- // clear the "local hangup" and "missed/rejected call"
- // cases from the "dropped during poll" list
- // These cases need no "last call fail" reason
- for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) {
- GsmConnection conn = droppedDuringPoll.get(i);
-
- if (conn.isIncoming() && conn.getConnectTime() == 0) {
- // Missed or rejected call
- Connection.DisconnectCause cause;
- if (conn.cause == Connection.DisconnectCause.LOCAL) {
- cause = Connection.DisconnectCause.INCOMING_REJECTED;
- } else {
- cause = Connection.DisconnectCause.INCOMING_MISSED;
- }
-
- if (Phone.DEBUG_PHONE) {
- log("missed/rejected call, conn.cause=" + conn.cause);
- log("setting cause to " + cause);
- }
- droppedDuringPoll.remove(i);
- conn.onDisconnect(cause);
- } else if (conn.cause == Connection.DisconnectCause.LOCAL) {
- // Local hangup
- droppedDuringPoll.remove(i);
- conn.onDisconnect(Connection.DisconnectCause.LOCAL);
- } else if (conn.cause ==
- Connection.DisconnectCause.INVALID_NUMBER) {
- droppedDuringPoll.remove(i);
- conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER);
- }
- }
-
- // Any non-local disconnects: determine cause
- if (droppedDuringPoll.size() > 0) {
- cm.getLastCallFailCause(
- obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
- }
-
- if (needsPollDelay) {
- pollCallsAfterDelay();
- }
-
- // Cases when we can no longer keep disconnected Connection's
- // with their previous calls
- // 1) the phone has started to ring
- // 2) A Call/Connection object has changed state...
- // we may have switched or held or answered (but not hung up)
- if (newRinging != null || hasNonHangupStateChanged) {
- internalClearDisconnected();
- }
-
- updatePhoneState();
-
- if (unknownConnectionAppeared) {
- phone.notifyUnknownConnection();
- }
-
- if (hasNonHangupStateChanged || newRinging != null) {
- phone.notifyPreciseCallStateChanged();
- }
-
- //dumpState();
- }
-
- private void
- handleRadioNotAvailable() {
- // handlePollCalls will clear out its
- // call list when it gets the CommandException
- // error result from this
- pollCallsWhenSafe();
- }
-
- private void
- dumpState() {
- List l;
-
- Log.i(LOG_TAG,"Phone State:" + state);
-
- Log.i(LOG_TAG,"Ringing call: " + ringingCall.toString());
-
- l = ringingCall.getConnections();
- for (int i = 0, s = l.size(); i < s; i++) {
- Log.i(LOG_TAG,l.get(i).toString());
- }
-
- Log.i(LOG_TAG,"Foreground call: " + foregroundCall.toString());
-
- l = foregroundCall.getConnections();
- for (int i = 0, s = l.size(); i < s; i++) {
- Log.i(LOG_TAG,l.get(i).toString());
- }
-
- Log.i(LOG_TAG,"Background call: " + backgroundCall.toString());
-
- l = backgroundCall.getConnections();
- for (int i = 0, s = l.size(); i < s; i++) {
- Log.i(LOG_TAG,l.get(i).toString());
- }
-
- }
-
- //***** Called from GsmConnection
-
- /*package*/ void
- hangup (GsmConnection conn) throws CallStateException {
- if (conn.owner != this) {
- throw new CallStateException ("GsmConnection " + conn
- + "does not belong to GsmCallTracker " + this);
- }
-
- if (conn == pendingMO) {
- // We're hanging up an outgoing call that doesn't have it's
- // GSM index assigned yet
-
- if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
- hangupPendingMO = true;
- } else {
- try {
- cm.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage());
- } catch (CallStateException ex) {
- // Ignore "connection not found"
- // Call may have hung up already
- Log.w(LOG_TAG,"GsmCallTracker WARN: hangup() on absent connection "
- + conn);
- }
- }
-
- conn.onHangupLocal();
- }
-
- /*package*/ void
- separate (GsmConnection conn) throws CallStateException {
- if (conn.owner != this) {
- throw new CallStateException ("GsmConnection " + conn
- + "does not belong to GsmCallTracker " + this);
- }
- try {
- cm.separateConnection (conn.getGSMIndex(),
- obtainCompleteMessage(EVENT_SEPARATE_RESULT));
- } catch (CallStateException ex) {
- // Ignore "connection not found"
- // Call may have hung up already
- Log.w(LOG_TAG,"GsmCallTracker WARN: separate() on absent connection "
- + conn);
- }
- }
-
- //***** Called from GSMPhone
-
- /*package*/ void
- setMute(boolean mute) {
- desiredMute = mute;
- cm.setMute(desiredMute, null);
- }
-
- /*package*/ boolean
- getMute() {
- return desiredMute;
- }
-
-
- //***** Called from GsmCall
-
- /* package */ void
- hangup (GsmCall call) throws CallStateException {
- if (call.getConnections().size() == 0) {
- throw new CallStateException("no connections in call");
- }
-
- if (call == ringingCall) {
- if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
- cm.hangupWaitingOrBackground(obtainCompleteMessage());
- } else if (call == foregroundCall) {
- if (call.isDialingOrAlerting()) {
- if (Phone.DEBUG_PHONE) {
- log("(foregnd) hangup dialing or alerting...");
- }
- hangup((GsmConnection)(call.getConnections().get(0)));
- } else {
- hangupForegroundResumeBackground();
- }
- } else if (call == backgroundCall) {
- if (ringingCall.isRinging()) {
- if (Phone.DEBUG_PHONE) {
- log("hangup all conns in background call");
- }
- hangupAllConnections(call);
- } else {
- hangupWaitingOrBackground();
- }
- } else {
- throw new RuntimeException ("GsmCall " + call +
- "does not belong to GsmCallTracker " + this);
- }
-
- call.onHangupLocal();
- phone.notifyPreciseCallStateChanged();
- }
-
- /* package */
- void hangupWaitingOrBackground() {
- if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
- cm.hangupWaitingOrBackground(obtainCompleteMessage());
- }
-
- /* package */
- void hangupForegroundResumeBackground() {
- if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground");
- cm.hangupForegroundResumeBackground(obtainCompleteMessage());
- }
-
- void hangupConnectionByIndex(GsmCall call, int index)
- throws CallStateException {
- int count = call.connections.size();
- for (int i = 0; i < count; i++) {
- GsmConnection cn = (GsmConnection)call.connections.get(i);
- if (cn.getGSMIndex() == index) {
- cm.hangupConnection(index, obtainCompleteMessage());
- return;
- }
- }
-
- throw new CallStateException("no gsm index found");
- }
-
- void hangupAllConnections(GsmCall call) throws CallStateException{
- try {
- int count = call.connections.size();
- for (int i = 0; i < count; i++) {
- GsmConnection cn = (GsmConnection)call.connections.get(i);
- cm.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage());
- }
- } catch (CallStateException ex) {
- Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex);
- }
- }
-
- /* package */
- GsmConnection getConnectionByIndex(GsmCall call, int index)
- throws CallStateException {
- int count = call.connections.size();
- for (int i = 0; i < count; i++) {
- GsmConnection cn = (GsmConnection)call.connections.get(i);
- if (cn.getGSMIndex() == index) {
- return cn;
- }
- }
-
- return null;
- }
-
- private Phone.SuppService getFailedService(int what) {
- switch (what) {
- case EVENT_SWITCH_RESULT:
- return Phone.SuppService.SWITCH;
- case EVENT_CONFERENCE_RESULT:
- return Phone.SuppService.CONFERENCE;
- case EVENT_SEPARATE_RESULT:
- return Phone.SuppService.SEPARATE;
- case EVENT_ECT_RESULT:
- return Phone.SuppService.TRANSFER;
- }
- return Phone.SuppService.UNKNOWN;
- }
-
- //****** Overridden from Handler
-
- public void
- handleMessage (Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_POLL_CALLS_RESULT:
- ar = (AsyncResult)msg.obj;
-
- if (msg == lastRelevantPoll) {
- if (DBG_POLL) log(
- "handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
- needsPoll = false;
- lastRelevantPoll = null;
- handlePollCalls((AsyncResult)msg.obj);
- }
- break;
-
- case EVENT_OPERATION_COMPLETE:
- ar = (AsyncResult)msg.obj;
- operationComplete();
- break;
-
- case EVENT_SWITCH_RESULT:
- case EVENT_CONFERENCE_RESULT:
- case EVENT_SEPARATE_RESULT:
- case EVENT_ECT_RESULT:
- ar = (AsyncResult)msg.obj;
- if (ar.exception != null) {
- phone.notifySuppServiceFailed(getFailedService(msg.what));
- }
- operationComplete();
- break;
-
- case EVENT_GET_LAST_CALL_FAIL_CAUSE:
- int causeCode;
- ar = (AsyncResult)msg.obj;
-
- operationComplete();
-
- if (ar.exception != null) {
- // An exception occurred...just treat the disconnect
- // cause as "normal"
- causeCode = CallFailCause.NORMAL_CLEARING;
- Log.i(LOG_TAG,
- "Exception during getLastCallFailCause, assuming normal disconnect");
- } else {
- causeCode = ((int[])ar.result)[0];
- }
- // Log the causeCode if its not normal
- if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL ||
- causeCode == CallFailCause.TEMPORARY_FAILURE ||
- causeCode == CallFailCause.SWITCHING_CONGESTION ||
- causeCode == CallFailCause.CHANNEL_NOT_AVAIL ||
- causeCode == CallFailCause.QOS_NOT_AVAIL ||
- causeCode == CallFailCause.BEARER_NOT_AVAIL ||
- causeCode == CallFailCause.ERROR_UNSPECIFIED) {
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
- EventLog.writeEvent(EventLogTags.CALL_DROP,
- causeCode, loc != null ? loc.getCid() : -1,
- TelephonyManager.getDefault().getNetworkType());
- }
-
- for (int i = 0, s = droppedDuringPoll.size()
- ; i < s ; i++
- ) {
- GsmConnection conn = droppedDuringPoll.get(i);
-
- conn.onRemoteDisconnect(causeCode);
- }
-
- updatePhoneState();
-
- phone.notifyPreciseCallStateChanged();
- droppedDuringPoll.clear();
- break;
-
- case EVENT_REPOLL_AFTER_DELAY:
- case EVENT_CALL_STATE_CHANGE:
- pollCallsWhenSafe();
- break;
-
- case EVENT_RADIO_AVAILABLE:
- handleRadioAvailable();
- break;
-
- case EVENT_RADIO_NOT_AVAILABLE:
- handleRadioNotAvailable();
- break;
- }
- }
-
- protected void log(String msg) {
- Log.d(LOG_TAG, "[GsmCallTracker] " + msg);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("GsmCallTracker extends:");
- super.dump(fd, pw, args);
- pw.println("connections: length=" + connections.length);
- for(int i=0; i < connections.length; i++) {
- pw.printf(" connections[%d]=%s\n", i, connections[i]);
- }
- pw.println(" voiceCallEndedRegistrants=" + voiceCallEndedRegistrants);
- pw.println(" voiceCallStartedRegistrants=" + voiceCallStartedRegistrants);
- pw.println(" droppedDuringPoll: size=" + droppedDuringPoll.size());
- for(int i = 0; i < droppedDuringPoll.size(); i++) {
- pw.printf( " droppedDuringPoll[%d]=%s\n", i, droppedDuringPoll.get(i));
- }
- pw.println(" ringingCall=" + ringingCall);
- pw.println(" foregroundCall=" + foregroundCall);
- pw.println(" backgroundCall=" + backgroundCall);
- pw.println(" pendingMO=" + pendingMO);
- pw.println(" hangupPendingMO=" + hangupPendingMO);
- pw.println(" phone=" + phone);
- pw.println(" desiredMute=" + desiredMute);
- pw.println(" state=" + state);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
deleted file mode 100644
index f7c6025..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * 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.gsm;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.SystemClock;
-import android.util.Log;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-
-import com.android.internal.telephony.*;
-
-/**
- * {@hide}
- */
-public class GsmConnection extends Connection {
- static final String LOG_TAG = "GSM";
-
- //***** Instance Variables
-
- GsmCallTracker owner;
- GsmCall parent;
-
- String address; // MAY BE NULL!!!
- String dialString; // outgoing calls only
- String postDialString; // outgoing calls only
- boolean isIncoming;
- boolean disconnected;
-
- int index; // index in GsmCallTracker.connections[], -1 if unassigned
- // The GSM index is 1 + this
-
- /*
- * These time/timespan values are based on System.currentTimeMillis(),
- * i.e., "wall clock" time.
- */
- long createTime;
- long connectTime;
- long disconnectTime;
-
- /*
- * These time/timespan values are based on SystemClock.elapsedRealTime(),
- * i.e., time since boot. They are appropriate for comparison and
- * calculating deltas.
- */
- long connectTimeReal;
- long duration;
- long holdingStartTime; // The time when the Connection last transitioned
- // into HOLDING
-
- int nextPostDialChar; // index into postDialString
-
- DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
- PostDialState postDialState = PostDialState.NOT_STARTED;
- int numberPresentation = Connection.PRESENTATION_ALLOWED;
- UUSInfo uusInfo;
-
- Handler h;
-
- private PowerManager.WakeLock mPartialWakeLock;
-
- //***** Event Constants
- static final int EVENT_DTMF_DONE = 1;
- static final int EVENT_PAUSE_DONE = 2;
- static final int EVENT_NEXT_POST_DIAL = 3;
- static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
-
- //***** Constants
- static final int PAUSE_DELAY_FIRST_MILLIS = 100;
- static final int PAUSE_DELAY_MILLIS = 3 * 1000;
- static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
-
- //***** Inner Classes
-
- class MyHandler extends Handler {
- MyHandler(Looper l) {super(l);}
-
- public void
- handleMessage(Message msg) {
-
- switch (msg.what) {
- case EVENT_NEXT_POST_DIAL:
- case EVENT_DTMF_DONE:
- case EVENT_PAUSE_DONE:
- processNextPostDialChar();
- break;
- case EVENT_WAKE_LOCK_TIMEOUT:
- releaseWakeLock();
- break;
- }
- }
- }
-
- //***** Constructors
-
- /** This is probably an MT call that we first saw in a CLCC response */
- /*package*/
- GsmConnection (Context context, DriverCall dc, GsmCallTracker ct, int index) {
- createWakeLock(context);
- acquireWakeLock();
-
- owner = ct;
- h = new MyHandler(owner.getLooper());
-
- address = dc.number;
-
- isIncoming = dc.isMT;
- createTime = System.currentTimeMillis();
- numberPresentation = dc.numberPresentation;
- uusInfo = dc.uusInfo;
-
- this.index = index;
-
- parent = parentFromDCState (dc.state);
- parent.attach(this, dc);
- }
-
- /** This is an MO call, created when dialing */
- /*package*/
- GsmConnection (Context context, String dialString, GsmCallTracker ct, GsmCall parent) {
- createWakeLock(context);
- acquireWakeLock();
-
- owner = ct;
- h = new MyHandler(owner.getLooper());
-
- this.dialString = dialString;
-
- this.address = PhoneNumberUtils.extractNetworkPortionAlt(dialString);
- this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
-
- index = -1;
-
- isIncoming = false;
- createTime = System.currentTimeMillis();
-
- this.parent = parent;
- parent.attachFake(this, GsmCall.State.DIALING);
- }
-
- public void dispose() {
- }
-
- static boolean
- equalsHandlesNulls (Object a, Object b) {
- return (a == null) ? (b == null) : a.equals (b);
- }
-
- /*package*/ boolean
- compareTo(DriverCall c) {
- // On mobile originated (MO) calls, the phone number may have changed
- // due to a SIM Toolkit call control modification.
- //
- // We assume we know when MO calls are created (since we created them)
- // and therefore don't need to compare the phone number anyway.
- if (! (isIncoming || c.isMT)) return true;
-
- // ... but we can compare phone numbers on MT calls, and we have
- // no control over when they begin, so we might as well
-
- String cAddress = PhoneNumberUtils.stringFromStringAndTOA(c.number, c.TOA);
- return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
- }
-
- public String getAddress() {
- return address;
- }
-
- public GsmCall getCall() {
- return parent;
- }
-
- public long getCreateTime() {
- return createTime;
- }
-
- public long getConnectTime() {
- return connectTime;
- }
-
- public long getDisconnectTime() {
- return disconnectTime;
- }
-
- public long getDurationMillis() {
- if (connectTimeReal == 0) {
- return 0;
- } else if (duration == 0) {
- return SystemClock.elapsedRealtime() - connectTimeReal;
- } else {
- return duration;
- }
- }
-
- public long getHoldDurationMillis() {
- if (getState() != GsmCall.State.HOLDING) {
- // If not holding, return 0
- return 0;
- } else {
- return SystemClock.elapsedRealtime() - holdingStartTime;
- }
- }
-
- public DisconnectCause getDisconnectCause() {
- return cause;
- }
-
- public boolean isIncoming() {
- return isIncoming;
- }
-
- public GsmCall.State getState() {
- if (disconnected) {
- return GsmCall.State.DISCONNECTED;
- } else {
- return super.getState();
- }
- }
-
- public void hangup() throws CallStateException {
- if (!disconnected) {
- owner.hangup(this);
- } else {
- throw new CallStateException ("disconnected");
- }
- }
-
- public void separate() throws CallStateException {
- if (!disconnected) {
- owner.separate(this);
- } else {
- throw new CallStateException ("disconnected");
- }
- }
-
- public PostDialState getPostDialState() {
- return postDialState;
- }
-
- public void proceedAfterWaitChar() {
- if (postDialState != PostDialState.WAIT) {
- Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected "
- + "getPostDialState() to be WAIT but was " + postDialState);
- return;
- }
-
- setPostDialState(PostDialState.STARTED);
-
- processNextPostDialChar();
- }
-
- public void proceedAfterWildChar(String str) {
- if (postDialState != PostDialState.WILD) {
- Log.w(LOG_TAG, "GsmConnection.proceedAfterWaitChar(): Expected "
- + "getPostDialState() to be WILD but was " + postDialState);
- return;
- }
-
- setPostDialState(PostDialState.STARTED);
-
- if (false) {
- boolean playedTone = false;
- int len = (str != null ? str.length() : 0);
-
- for (int i=0; i<len; i++) {
- char c = str.charAt(i);
- Message msg = null;
-
- if (i == len-1) {
- msg = h.obtainMessage(EVENT_DTMF_DONE);
- }
-
- if (PhoneNumberUtils.is12Key(c)) {
- owner.cm.sendDtmf(c, msg);
- playedTone = true;
- }
- }
-
- if (!playedTone) {
- processNextPostDialChar();
- }
- } else {
- // make a new postDialString, with the wild char replacement string
- // at the beginning, followed by the remaining postDialString.
-
- StringBuilder buf = new StringBuilder(str);
- buf.append(postDialString.substring(nextPostDialChar));
- postDialString = buf.toString();
- nextPostDialChar = 0;
- if (Phone.DEBUG_PHONE) {
- log("proceedAfterWildChar: new postDialString is " +
- postDialString);
- }
-
- processNextPostDialChar();
- }
- }
-
- public void cancelPostDial() {
- setPostDialState(PostDialState.CANCELLED);
- }
-
- /**
- * Called when this Connection is being hung up locally (eg, user pressed "end")
- * Note that at this point, the hangup request has been dispatched to the radio
- * but no response has yet been received so update() has not yet been called
- */
- void
- onHangupLocal() {
- cause = DisconnectCause.LOCAL;
- }
-
- DisconnectCause
- disconnectCauseFromCode(int causeCode) {
- /**
- * See 22.001 Annex F.4 for mapping of cause codes
- * to local tones
- */
-
- switch (causeCode) {
- case CallFailCause.USER_BUSY:
- return DisconnectCause.BUSY;
-
- case CallFailCause.NO_CIRCUIT_AVAIL:
- case CallFailCause.TEMPORARY_FAILURE:
- case CallFailCause.SWITCHING_CONGESTION:
- case CallFailCause.CHANNEL_NOT_AVAIL:
- case CallFailCause.QOS_NOT_AVAIL:
- case CallFailCause.BEARER_NOT_AVAIL:
- return DisconnectCause.CONGESTION;
-
- case CallFailCause.ACM_LIMIT_EXCEEDED:
- return DisconnectCause.LIMIT_EXCEEDED;
-
- case CallFailCause.CALL_BARRED:
- return DisconnectCause.CALL_BARRED;
-
- case CallFailCause.FDN_BLOCKED:
- return DisconnectCause.FDN_BLOCKED;
-
- case CallFailCause.UNOBTAINABLE_NUMBER:
- return DisconnectCause.UNOBTAINABLE_NUMBER;
-
- case CallFailCause.ERROR_UNSPECIFIED:
- case CallFailCause.NORMAL_CLEARING:
- default:
- GSMPhone phone = owner.phone;
- int serviceState = phone.getServiceState().getState();
- if (serviceState == ServiceState.STATE_POWER_OFF) {
- return DisconnectCause.POWER_OFF;
- } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
- || serviceState == ServiceState.STATE_EMERGENCY_ONLY ) {
- return DisconnectCause.OUT_OF_SERVICE;
- } else if (phone.getIccCard().getState() != IccCard.State.READY) {
- return DisconnectCause.ICC_ERROR;
- } else if (causeCode == CallFailCause.ERROR_UNSPECIFIED) {
- if (phone.mSST.mRestrictedState.isCsRestricted()) {
- return DisconnectCause.CS_RESTRICTED;
- } else if (phone.mSST.mRestrictedState.isCsEmergencyRestricted()) {
- return DisconnectCause.CS_RESTRICTED_EMERGENCY;
- } else if (phone.mSST.mRestrictedState.isCsNormalRestricted()) {
- return DisconnectCause.CS_RESTRICTED_NORMAL;
- } else {
- return DisconnectCause.ERROR_UNSPECIFIED;
- }
- } else if (causeCode == CallFailCause.NORMAL_CLEARING) {
- return DisconnectCause.NORMAL;
- } else {
- // If nothing else matches, report unknown call drop reason
- // to app, not NORMAL call end.
- return DisconnectCause.ERROR_UNSPECIFIED;
- }
- }
- }
-
- /*package*/ void
- onRemoteDisconnect(int causeCode) {
- onDisconnect(disconnectCauseFromCode(causeCode));
- }
-
- /** Called when the radio indicates the connection has been disconnected */
- /*package*/ void
- onDisconnect(DisconnectCause cause) {
- this.cause = cause;
-
- if (!disconnected) {
- index = -1;
-
- disconnectTime = System.currentTimeMillis();
- duration = SystemClock.elapsedRealtime() - connectTimeReal;
- disconnected = true;
-
- if (false) Log.d(LOG_TAG,
- "[GSMConn] onDisconnect: cause=" + cause);
-
- owner.phone.notifyDisconnect(this);
-
- if (parent != null) {
- parent.connectionDisconnected(this);
- }
- }
- releaseWakeLock();
- }
-
- // Returns true if state has changed, false if nothing changed
- /*package*/ boolean
- update (DriverCall dc) {
- GsmCall newParent;
- boolean changed = false;
- boolean wasConnectingInOrOut = isConnectingInOrOut();
- boolean wasHolding = (getState() == GsmCall.State.HOLDING);
-
- newParent = parentFromDCState(dc.state);
-
- if (!equalsHandlesNulls(address, dc.number)) {
- if (Phone.DEBUG_PHONE) log("update: phone # changed!");
- address = dc.number;
- changed = true;
- }
-
- if (newParent != parent) {
- if (parent != null) {
- parent.detach(this);
- }
- newParent.attach(this, dc);
- parent = newParent;
- changed = true;
- } else {
- boolean parentStateChange;
- parentStateChange = parent.update (this, dc);
- changed = changed || parentStateChange;
- }
-
- /** Some state-transition events */
-
- if (Phone.DEBUG_PHONE) log(
- "update: parent=" + parent +
- ", hasNewParent=" + (newParent != parent) +
- ", wasConnectingInOrOut=" + wasConnectingInOrOut +
- ", wasHolding=" + wasHolding +
- ", isConnectingInOrOut=" + isConnectingInOrOut() +
- ", changed=" + changed);
-
-
- if (wasConnectingInOrOut && !isConnectingInOrOut()) {
- onConnectedInOrOut();
- }
-
- if (changed && !wasHolding && (getState() == GsmCall.State.HOLDING)) {
- // We've transitioned into HOLDING
- onStartedHolding();
- }
-
- return changed;
- }
-
- /**
- * Called when this Connection is in the foregroundCall
- * when a dial is initiated.
- * We know we're ACTIVE, and we know we're going to end up
- * HOLDING in the backgroundCall
- */
- void
- fakeHoldBeforeDial() {
- if (parent != null) {
- parent.detach(this);
- }
-
- parent = owner.backgroundCall;
- parent.attachFake(this, GsmCall.State.HOLDING);
-
- onStartedHolding();
- }
-
- /*package*/ int
- getGSMIndex() throws CallStateException {
- if (index >= 0) {
- return index + 1;
- } else {
- throw new CallStateException ("GSM index not yet assigned");
- }
- }
-
- /**
- * An incoming or outgoing call has connected
- */
- void
- onConnectedInOrOut() {
- connectTime = System.currentTimeMillis();
- connectTimeReal = SystemClock.elapsedRealtime();
- duration = 0;
-
- // bug #678474: incoming call interpreted as missed call, even though
- // it sounds like the user has picked up the call.
- if (Phone.DEBUG_PHONE) {
- log("onConnectedInOrOut: connectTime=" + connectTime);
- }
-
- if (!isIncoming) {
- // outgoing calls only
- processNextPostDialChar();
- }
- releaseWakeLock();
- }
-
- private void
- onStartedHolding() {
- holdingStartTime = SystemClock.elapsedRealtime();
- }
- /**
- * Performs the appropriate action for a post-dial char, but does not
- * notify application. returns false if the character is invalid and
- * should be ignored
- */
- private boolean
- processPostDialChar(char c) {
- if (PhoneNumberUtils.is12Key(c)) {
- owner.cm.sendDtmf(c, h.obtainMessage(EVENT_DTMF_DONE));
- } else if (c == PhoneNumberUtils.PAUSE) {
- // From TS 22.101:
-
- // "The first occurrence of the "DTMF Control Digits Separator"
- // shall be used by the ME to distinguish between the addressing
- // digits (i.e. the phone number) and the DTMF digits...."
-
- if (nextPostDialChar == 1) {
- // The first occurrence.
- // We don't need to pause here, but wait for just a bit anyway
- h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
- PAUSE_DELAY_FIRST_MILLIS);
- } else {
- // It continues...
- // "Upon subsequent occurrences of the separator, the UE shall
- // pause again for 3 seconds (\u00B1 20 %) before sending any
- // further DTMF digits."
- h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE),
- PAUSE_DELAY_MILLIS);
- }
- } else if (c == PhoneNumberUtils.WAIT) {
- setPostDialState(PostDialState.WAIT);
- } else if (c == PhoneNumberUtils.WILD) {
- setPostDialState(PostDialState.WILD);
- } else {
- return false;
- }
-
- return true;
- }
-
- public String
- getRemainingPostDialString() {
- if (postDialState == PostDialState.CANCELLED
- || postDialState == PostDialState.COMPLETE
- || postDialString == null
- || postDialString.length() <= nextPostDialChar
- ) {
- return "";
- }
-
- return postDialString.substring(nextPostDialChar);
- }
-
- @Override
- protected void finalize()
- {
- /**
- * It is understood that This finializer is not guaranteed
- * to be called and the release lock call is here just in
- * case there is some path that doesn't call onDisconnect
- * and or onConnectedInOrOut.
- */
- if (mPartialWakeLock.isHeld()) {
- Log.e(LOG_TAG, "[GSMConn] UNEXPECTED; mPartialWakeLock is held when finalizing.");
- }
- releaseWakeLock();
- }
-
- private void
- processNextPostDialChar() {
- char c = 0;
- Registrant postDialHandler;
-
- if (postDialState == PostDialState.CANCELLED) {
- //Log.v("GSM", "##### processNextPostDialChar: postDialState == CANCELLED, bail");
- return;
- }
-
- if (postDialString == null ||
- postDialString.length() <= nextPostDialChar) {
- setPostDialState(PostDialState.COMPLETE);
-
- // notifyMessage.arg1 is 0 on complete
- c = 0;
- } else {
- boolean isValid;
-
- setPostDialState(PostDialState.STARTED);
-
- c = postDialString.charAt(nextPostDialChar++);
-
- isValid = processPostDialChar(c);
-
- if (!isValid) {
- // Will call processNextPostDialChar
- h.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget();
- // Don't notify application
- Log.e("GSM", "processNextPostDialChar: c=" + c + " isn't valid!");
- return;
- }
- }
-
- postDialHandler = owner.phone.mPostDialHandler;
-
- Message notifyMessage;
-
- if (postDialHandler != null
- && (notifyMessage = postDialHandler.messageForRegistrant()) != null) {
- // The AsyncResult.result is the Connection object
- PostDialState state = postDialState;
- AsyncResult ar = AsyncResult.forMessage(notifyMessage);
- ar.result = this;
- ar.userObj = state;
-
- // arg1 is the character that was/is being processed
- notifyMessage.arg1 = c;
-
- //Log.v("GSM", "##### processNextPostDialChar: send msg to postDialHandler, arg1=" + c);
- notifyMessage.sendToTarget();
- }
- }
-
-
- /** "connecting" means "has never been ACTIVE" for both incoming
- * and outgoing calls
- */
- private boolean
- isConnectingInOrOut() {
- return parent == null || parent == owner.ringingCall
- || parent.state == GsmCall.State.DIALING
- || parent.state == GsmCall.State.ALERTING;
- }
-
- private GsmCall
- parentFromDCState (DriverCall.State state) {
- switch (state) {
- case ACTIVE:
- case DIALING:
- case ALERTING:
- return owner.foregroundCall;
- //break;
-
- case HOLDING:
- return owner.backgroundCall;
- //break;
-
- case INCOMING:
- case WAITING:
- return owner.ringingCall;
- //break;
-
- default:
- throw new RuntimeException("illegal call state: " + state);
- }
- }
-
- /**
- * Set post dial state and acquire wake lock while switching to "started"
- * state, the wake lock will be released if state switches out of "started"
- * state or after WAKE_LOCK_TIMEOUT_MILLIS.
- * @param s new PostDialState
- */
- private void setPostDialState(PostDialState s) {
- if (postDialState != PostDialState.STARTED
- && s == PostDialState.STARTED) {
- acquireWakeLock();
- Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
- h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
- } else if (postDialState == PostDialState.STARTED
- && s != PostDialState.STARTED) {
- h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
- releaseWakeLock();
- }
- postDialState = s;
- }
-
- private void
- createWakeLock(Context context) {
- PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
- }
-
- private void
- acquireWakeLock() {
- log("acquireWakeLock");
- mPartialWakeLock.acquire();
- }
-
- private void
- releaseWakeLock() {
- synchronized(mPartialWakeLock) {
- if (mPartialWakeLock.isHeld()) {
- log("releaseWakeLock");
- mPartialWakeLock.release();
- }
- }
- }
-
- private void log(String msg) {
- Log.d(LOG_TAG, "[GSMConn] " + msg);
- }
-
- @Override
- public int getNumberPresentation() {
- return numberPresentation;
- }
-
- @Override
- public UUSInfo getUUSInfo() {
- return uusInfo;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
deleted file mode 100644
index 9801721..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.gsm;
-
-import android.os.Message;
-import android.util.Log;
-import android.util.Patterns;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RetryManager;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * {@hide}
- */
-public class GsmDataConnection extends DataConnection {
-
- private static final String LOG_TAG = "GSM";
-
- //***** Instance Variables
- protected int mProfileId = RILConstants.DATA_PROFILE_DEFAULT;
- //***** Constructor
- private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm,
- DataConnectionTracker dct) {
- super(phone, name, id, rm, dct);
- }
-
- /**
- * Create the connection object
- *
- * @param phone the Phone
- * @param id the connection id
- * @param rm the RetryManager
- * @return GsmDataConnection that was created.
- */
- static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm,
- DataConnectionTracker dct) {
- synchronized (mCountLock) {
- mCount += 1;
- }
- GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm, dct);
- gsmDc.start();
- if (DBG) gsmDc.log("Made " + gsmDc.getName());
- return gsmDc;
- }
-
- /**
- * Begin setting up a data connection, calls setupDataCall
- * and the ConnectionParams will be returned with the
- * EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj.
- *
- * @param cp is the connection parameters
- */
- @Override
- protected
- void onConnect(ConnectionParams cp) {
- mApn = cp.apn;
-
- if (DBG) log("Connecting to carrier: '" + mApn.carrier
- + "' APN: '" + mApn.apn
- + "' proxy: '" + mApn.proxy + "' port: '" + mApn.port);
-
- createTime = -1;
- lastFailTime = -1;
- lastFailCause = FailCause.NONE;
-
- // msg.obj will be returned in AsyncResult.userObj;
- Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
- msg.obj = cp;
-
- int authType = mApn.authType;
- if (authType == -1) {
- authType = TextUtils.isEmpty(mApn.user) ? RILConstants.SETUP_DATA_AUTH_NONE
- : RILConstants.SETUP_DATA_AUTH_PAP_CHAP;
- }
-
- String protocol;
- if (phone.getServiceState().getRoaming()) {
- protocol = mApn.roamingProtocol;
- } else {
- protocol = mApn.protocol;
- }
-
- phone.mCM.setupDataCall(
- Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_GSM)),
- Integer.toString(mProfileId),
- mApn.apn, mApn.user, mApn.password,
- Integer.toString(authType),
- protocol, msg);
- }
-
- public void setProfileId(int profileId) {
- mProfileId = profileId;
- }
-
- public int getProfileId() {
- return mProfileId;
- }
-
- @Override
- public String toString() {
- return "{" + getName() + ": State=" + getCurrentState().getName() +
- " apnSetting=" + mApn + " apnList= " + mApnList + " RefCount=" + mRefCount +
- " cid=" + cid + " create=" + createTime + " lastFail=" + lastFailTime +
- " lastFailCause=" + lastFailCause + "}";
- }
-
- @Override
- protected boolean isDnsOk(String[] domainNameServers) {
- if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1])
- && !phone.isDnsCheckDisabled()) {
- // Work around a race condition where QMI does not fill in DNS:
- // Deactivate PDP and let DataConnectionTracker retry.
- // Do not apply the race condition workaround for MMS APN
- // if Proxy is an IP-address.
- // Otherwise, the default APN will not be restored anymore.
- if (!mApn.types[0].equals(Phone.APN_TYPE_MMS)
- || !isIpAddress(mApn.mmsProxy)) {
- log(String.format(
- "isDnsOk: return false apn.types[0]=%s APN_TYPE_MMS=%s isIpAddress(%s)=%s",
- mApn.types[0], Phone.APN_TYPE_MMS, mApn.mmsProxy,
- isIpAddress(mApn.mmsProxy)));
- return false;
- }
- }
- return true;
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[" + getName() + "] " + s);
- }
-
- private boolean isIpAddress(String address) {
- if (address == null) return false;
-
- return Patterns.IP_ADDRESS.matcher(address).matches();
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("GsmDataConnection extends:");
- super.dump(fd, pw, args);
- pw.println(" mProfileId=" + mProfileId);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
deleted file mode 100644
index 23364b4..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ /dev/null
@@ -1,2646 +0,0 @@
-/*
- * 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.gsm;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.ConnectivityManager;
-import android.net.LinkAddress;
-import android.net.LinkCapabilities;
-import android.net.LinkProperties;
-import android.net.LinkProperties.CompareResult;
-import android.net.NetworkConfig;
-import android.net.NetworkUtils;
-import android.net.ProxyProperties;
-import android.net.TrafficStats;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.provider.Telephony;
-import android.telephony.CellLocation;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.cdma.CdmaCellLocation;
-import android.telephony.gsm.GsmCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-
-import com.android.internal.telephony.ApnContext;
-import com.android.internal.telephony.ApnSetting;
-import com.android.internal.telephony.DataCallState;
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnection.FailCause;
-import com.android.internal.telephony.DataConnection.UpdateLinkPropertyResult;
-import com.android.internal.telephony.DataConnectionAc;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.util.AsyncChannel;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * {@hide}
- */
-public final class GsmDataConnectionTracker extends DataConnectionTracker {
- protected final String LOG_TAG = "GSM";
- private static final boolean RADIO_TESTS = false;
-
- /**
- * Handles changes to the APN db.
- */
- private class ApnChangeObserver extends ContentObserver {
- public ApnChangeObserver () {
- super(mDataConnectionTracker);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- sendMessage(obtainMessage(EVENT_APN_CHANGED));
- }
- }
-
- //***** Instance Variables
-
- private boolean mReregisterOnReconnectFailure = false;
- private ContentResolver mResolver;
-
- // Recovery action taken in case of data stall
- private static class RecoveryAction {
- public static final int GET_DATA_CALL_LIST = 0;
- public static final int CLEANUP = 1;
- public static final int REREGISTER = 2;
- public static final int RADIO_RESTART = 3;
- public static final int RADIO_RESTART_WITH_PROP = 4;
-
- private static boolean isAggressiveRecovery(int value) {
- return ((value == RecoveryAction.CLEANUP) ||
- (value == RecoveryAction.REREGISTER) ||
- (value == RecoveryAction.RADIO_RESTART) ||
- (value == RecoveryAction.RADIO_RESTART_WITH_PROP));
- }
- }
-
- public int getRecoveryAction() {
- int action = Settings.System.getInt(mPhone.getContext().getContentResolver(),
- "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST);
- if (VDBG) log("getRecoveryAction: " + action);
- return action;
- }
- public void putRecoveryAction(int action) {
- Settings.System.putInt(mPhone.getContext().getContentResolver(),
- "radio.data.stall.recovery.action", action);
- if (VDBG) log("putRecoveryAction: " + action);
- }
-
- //***** Constants
-
- private static final int POLL_PDP_MILLIS = 5 * 1000;
-
- private static final String INTENT_RECONNECT_ALARM =
- "com.android.internal.telephony.gprs-reconnect";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT =
- "reconnect_alaram_extra_retry_count";
-
- private static final String INTENT_DATA_STALL_ALARM =
- "com.android.internal.telephony.gprs-data-stall";
-
- static final Uri PREFERAPN_NO_UPDATE_URI =
- Uri.parse("content://telephony/carriers/preferapn_no_update");
- static final String APN_ID = "apn_id";
- private boolean canSetPreferApn = false;
-
- private static final boolean DATA_STALL_SUSPECTED = true;
- private static final boolean DATA_STALL_NOT_SUSPECTED = false;
-
- @Override
- protected void onActionIntentReconnectAlarm(Intent intent) {
- String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
- int connectionId = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, -1);
- int retryCount = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, 0);
-
- DataConnectionAc dcac= mDataConnectionAsyncChannels.get(connectionId);
-
- if (DBG) {
- log("onActionIntentReconnectAlarm: mState=" + mState + " reason=" + reason +
- " connectionId=" + connectionId + " retryCount=" + retryCount);
- }
-
- if (dcac != null) {
- for (ApnContext apnContext : dcac.getApnListSync()) {
- apnContext.setDataConnectionAc(null);
- apnContext.setDataConnection(null);
- apnContext.setReason(reason);
- apnContext.setRetryCount(retryCount);
- if (apnContext.getState() == State.FAILED) {
- apnContext.setState(State.IDLE);
- }
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, apnContext));
- }
- // Alram had expired. Clear pending intent recorded on the DataConnection.
- dcac.setReconnectIntentSync(null);
- }
- }
-
- /** Watches for changes to the APN db. */
- private ApnChangeObserver mApnObserver;
-
- //***** Constructor
-
- public GsmDataConnectionTracker(PhoneBase p) {
- super(p);
- if (DBG) log("GsmDCT.constructor");
- p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
- p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- p.mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
- p.getCallTracker().registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
- p.getCallTracker().registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
- p.getServiceStateTracker().registerForDataConnectionAttached(this,
- EVENT_DATA_CONNECTION_ATTACHED, null);
- p.getServiceStateTracker().registerForDataConnectionDetached(this,
- EVENT_DATA_CONNECTION_DETACHED, null);
- p.getServiceStateTracker().registerForRoamingOn(this, EVENT_ROAMING_ON, null);
- p.getServiceStateTracker().registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
- p.getServiceStateTracker().registerForPsRestrictedEnabled(this,
- EVENT_PS_RESTRICT_ENABLED, null);
- p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
- EVENT_PS_RESTRICT_DISABLED, null);
-
- // install reconnect intent filter for this data connection.
- IntentFilter filter = new IntentFilter();
- filter.addAction(INTENT_DATA_STALL_ALARM);
- p.getContext().registerReceiver(mIntentReceiver, filter, null, p);
-
- mDataConnectionTracker = this;
- mResolver = mPhone.getContext().getContentResolver();
-
- mApnObserver = new ApnChangeObserver();
- p.getContext().getContentResolver().registerContentObserver(
- Telephony.Carriers.CONTENT_URI, true, mApnObserver);
-
- initApnContextsAndDataConnection();
- broadcastMessenger();
- }
-
- @Override
- public void dispose() {
- if (DBG) log("GsmDCT.dispose");
- cleanUpAllConnections(false, null);
-
- super.dispose();
-
- //Unregister for all events
- mPhone.mCM.unregisterForAvailable(this);
- mPhone.mCM.unregisterForOffOrNotAvailable(this);
- mPhone.mIccRecords.unregisterForRecordsLoaded(this);
- mPhone.mCM.unregisterForDataNetworkStateChanged(this);
- mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
- mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
- mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
- mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
- mPhone.getServiceStateTracker().unregisterForRoamingOn(this);
- mPhone.getServiceStateTracker().unregisterForRoamingOff(this);
- mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
- mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
-
- mPhone.getContext().getContentResolver().unregisterContentObserver(this.mApnObserver);
- mApnContexts.clear();
-
- destroyDataConnections();
- }
-
- @Override
- public boolean isApnTypeActive(String type) {
- ApnContext apnContext = mApnContexts.get(type);
- if (apnContext == null) return false;
-
- return (apnContext.getDataConnection() != null);
- }
-
- @Override
- protected boolean isDataPossible(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext == null) {
- return false;
- }
- boolean apnContextIsEnabled = apnContext.isEnabled();
- State apnContextState = apnContext.getState();
- boolean apnTypePossible = !(apnContextIsEnabled &&
- (apnContextState == State.FAILED));
- boolean dataAllowed = isDataAllowed();
- boolean possible = dataAllowed && apnTypePossible;
-
- if (DBG) {
- log(String.format("isDataPossible(%s): possible=%b isDataAllowed=%b " +
- "apnTypePossible=%b apnContextisEnabled=%b apnContextState()=%s",
- apnType, possible, dataAllowed, apnTypePossible,
- apnContextIsEnabled, apnContextState));
- }
- return possible;
- }
-
- @Override
- protected void finalize() {
- if(DBG) log("finalize");
- }
-
- @Override
- protected String getActionIntentReconnectAlarm() {
- return INTENT_RECONNECT_ALARM;
- }
-
- @Override
- protected String getActionIntentDataStallAlarm() {
- return INTENT_DATA_STALL_ALARM;
- }
-
- private ApnContext addApnContext(String type) {
- ApnContext apnContext = new ApnContext(type, LOG_TAG);
- apnContext.setDependencyMet(false);
- mApnContexts.put(type, apnContext);
- return apnContext;
- }
-
- protected void initApnContextsAndDataConnection() {
- boolean defaultEnabled = SystemProperties.getBoolean(DEFALUT_DATA_ON_BOOT_PROP, true);
- // Load device network attributes from resources
- String[] networkConfigStrings = mPhone.getContext().getResources().getStringArray(
- com.android.internal.R.array.networkAttributes);
- for (String networkConfigString : networkConfigStrings) {
- NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
- ApnContext apnContext = null;
-
- switch (networkConfig.type) {
- case ConnectivityManager.TYPE_MOBILE:
- apnContext = addApnContext(Phone.APN_TYPE_DEFAULT);
- apnContext.setEnabled(defaultEnabled);
- break;
- case ConnectivityManager.TYPE_MOBILE_MMS:
- apnContext = addApnContext(Phone.APN_TYPE_MMS);
- break;
- case ConnectivityManager.TYPE_MOBILE_SUPL:
- apnContext = addApnContext(Phone.APN_TYPE_SUPL);
- break;
- case ConnectivityManager.TYPE_MOBILE_DUN:
- apnContext = addApnContext(Phone.APN_TYPE_DUN);
- break;
- case ConnectivityManager.TYPE_MOBILE_HIPRI:
- apnContext = addApnContext(Phone.APN_TYPE_HIPRI);
- ApnContext defaultContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
- if (defaultContext != null) {
- applyNewState(apnContext, apnContext.isEnabled(),
- defaultContext.getDependencyMet());
- } else {
- // the default will set the hipri dep-met when it is created
- }
- continue;
- case ConnectivityManager.TYPE_MOBILE_FOTA:
- apnContext = addApnContext(Phone.APN_TYPE_FOTA);
- break;
- case ConnectivityManager.TYPE_MOBILE_IMS:
- apnContext = addApnContext(Phone.APN_TYPE_IMS);
- break;
- case ConnectivityManager.TYPE_MOBILE_CBS:
- apnContext = addApnContext(Phone.APN_TYPE_CBS);
- break;
- default:
- // skip unknown types
- continue;
- }
- if (apnContext != null) {
- // set the prop, but also apply the newly set enabled and dependency values
- onSetDependencyMet(apnContext.getApnType(), networkConfig.dependencyMet);
- }
- }
- }
-
- @Override
- protected LinkProperties getLinkProperties(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext != null) {
- DataConnectionAc dcac = apnContext.getDataConnectionAc();
- if (dcac != null) {
- if (DBG) log("return link properites for " + apnType);
- return dcac.getLinkPropertiesSync();
- }
- }
- if (DBG) log("return new LinkProperties");
- return new LinkProperties();
- }
-
- @Override
- protected LinkCapabilities getLinkCapabilities(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext!=null) {
- DataConnectionAc dataConnectionAc = apnContext.getDataConnectionAc();
- if (dataConnectionAc != null) {
- if (DBG) log("get active pdp is not null, return link Capabilities for " + apnType);
- return dataConnectionAc.getLinkCapabilitiesSync();
- }
- }
- if (DBG) log("return new LinkCapabilities");
- return new LinkCapabilities();
- }
-
- @Override
- // Return all active apn types
- public String[] getActiveApnTypes() {
- if (DBG) log("get all active apn types");
- ArrayList<String> result = new ArrayList<String>();
-
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.isReady()) {
- result.add(apnContext.getApnType());
- }
- }
-
- return (String[])result.toArray(new String[0]);
- }
-
- @Override
- // Return active apn of specific apn type
- public String getActiveApnString(String apnType) {
- if (DBG) log( "get active apn string for type:" + apnType);
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext != null) {
- ApnSetting apnSetting = apnContext.getApnSetting();
- if (apnSetting != null) {
- return apnSetting.apn;
- }
- }
- return null;
- }
-
- @Override
- public boolean isApnTypeEnabled(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext == null) {
- return false;
- }
- return apnContext.isEnabled();
- }
-
- @Override
- protected void setState(State s) {
- if (DBG) log("setState should not be used in GSM" + s);
- }
-
- // Return state of specific apn type
- @Override
- public State getState(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext != null) {
- return apnContext.getState();
- }
- return State.FAILED;
- }
-
- // Return state of overall
- public State getOverallState() {
- boolean isConnecting = false;
- boolean isFailed = true; // All enabled Apns should be FAILED.
- boolean isAnyEnabled = false;
-
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.isEnabled()) {
- isAnyEnabled = true;
- switch (apnContext.getState()) {
- case CONNECTED:
- case DISCONNECTING:
- if (DBG) log("overall state is CONNECTED");
- return State.CONNECTED;
- case CONNECTING:
- case INITING:
- isConnecting = true;
- isFailed = false;
- break;
- case IDLE:
- case SCANNING:
- isFailed = false;
- break;
- }
- }
- }
-
- if (!isAnyEnabled) { // Nothing enabled. return IDLE.
- if (DBG) log( "overall state is IDLE");
- return State.IDLE;
- }
-
- if (isConnecting) {
- if (DBG) log( "overall state is CONNECTING");
- return State.CONNECTING;
- } else if (!isFailed) {
- if (DBG) log( "overall state is IDLE");
- return State.IDLE;
- } else {
- if (DBG) log( "overall state is FAILED");
- return State.FAILED;
- }
- }
-
- /**
- * Ensure that we are connected to an APN of the specified type.
- *
- * @param type the APN type
- * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
- * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
- * broadcast will be sent by the ConnectivityManager when a
- * connection to the APN has been established.
- */
- @Override
- public synchronized int enableApnType(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext == null || !isApnTypeAvailable(apnType)) {
- if (DBG) log("enableApnType: " + apnType + " is type not available");
- return Phone.APN_TYPE_NOT_AVAILABLE;
- }
-
- // If already active, return
- if (DBG) log("enableApnType: " + apnType + " mState(" + apnContext.getState() + ")");
-
- if (apnContext.getState() == State.CONNECTED) {
- if (DBG) log("enableApnType: return APN_ALREADY_ACTIVE");
- return Phone.APN_ALREADY_ACTIVE;
- }
- setEnabled(apnTypeToId(apnType), true);
- if (DBG) {
- log("enableApnType: new apn request for type " + apnType +
- " return APN_REQUEST_STARTED");
- }
- return Phone.APN_REQUEST_STARTED;
- }
-
- // A new APN has gone active and needs to send events to catch up with the
- // current condition
- private void notifyApnIdUpToCurrent(String reason, ApnContext apnContext, String type) {
- switch (apnContext.getState()) {
- case IDLE:
- case INITING:
- break;
- case CONNECTING:
- case SCANNING:
- mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTING);
- break;
- case CONNECTED:
- case DISCONNECTING:
- mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTING);
- mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTED);
- break;
- }
- }
-
- @Override
- public synchronized int disableApnType(String type) {
- if (DBG) log("disableApnType:" + type);
- ApnContext apnContext = mApnContexts.get(type);
-
- if (apnContext != null) {
- setEnabled(apnTypeToId(type), false);
- if (apnContext.getState() != State.IDLE && apnContext.getState() != State.FAILED) {
- if (DBG) log("diableApnType: return APN_REQUEST_STARTED");
- return Phone.APN_REQUEST_STARTED;
- } else {
- if (DBG) log("disableApnType: return APN_ALREADY_INACTIVE");
- return Phone.APN_ALREADY_INACTIVE;
- }
-
- } else {
- if (DBG) {
- log("disableApnType: no apn context was found, return APN_REQUEST_FAILED");
- }
- return Phone.APN_REQUEST_FAILED;
- }
- }
-
- @Override
- protected boolean isApnTypeAvailable(String type) {
- if (type.equals(Phone.APN_TYPE_DUN) && fetchDunApn() != null) {
- return true;
- }
-
- if (mAllApns != null) {
- for (ApnSetting apn : mAllApns) {
- if (apn.canHandleType(type)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Report on whether data connectivity is enabled for any APN.
- * @return {@code false} if data connectivity has been explicitly disabled,
- * {@code true} otherwise.
- */
- @Override
- public boolean getAnyDataEnabled() {
- synchronized (mDataEnabledLock) {
- if (!(mInternalDataEnabled && mUserDataEnabled && sPolicyDataEnabled)) return false;
- for (ApnContext apnContext : mApnContexts.values()) {
- // Make sure we dont have a context that going down
- // and is explicitly disabled.
- if (isDataAllowed(apnContext)) {
- return true;
- }
- }
- return false;
- }
- }
-
- private boolean isDataAllowed(ApnContext apnContext) {
- return apnContext.isReady() && isDataAllowed();
- }
-
- //****** Called from ServiceStateTracker
- /**
- * Invoked when ServiceStateTracker observes a transition from GPRS
- * attach to detach.
- */
- protected void onDataConnectionDetached() {
- /*
- * We presently believe it is unnecessary to tear down the PDP context
- * when GPRS detaches, but we should stop the network polling.
- */
- if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
- stopNetStatPoll();
- stopDataStallAlarm();
- notifyDataConnection(Phone.REASON_DATA_DETACHED);
- }
-
- private void onDataConnectionAttached() {
- if (DBG) log("onDataConnectionAttached");
- if (getOverallState() == State.CONNECTED) {
- if (DBG) log("onDataConnectionAttached: start polling notify attached");
- startNetStatPoll();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- notifyDataConnection(Phone.REASON_DATA_ATTACHED);
- } else {
- // update APN availability so that APN can be enabled.
- notifyOffApnsOfAvailability(Phone.REASON_DATA_ATTACHED);
- }
-
- setupDataOnReadyApns(Phone.REASON_DATA_ATTACHED);
- }
-
- @Override
- protected boolean isDataAllowed() {
- final boolean internalDataEnabled;
- synchronized (mDataEnabledLock) {
- internalDataEnabled = mInternalDataEnabled;
- }
-
- int gprsState = mPhone.getServiceStateTracker().getCurrentDataConnectionState();
- boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
-
- boolean allowed =
- (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
- mPhone.mIccRecords.getRecordsLoaded() &&
- (mPhone.getState() == Phone.State.IDLE ||
- mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) &&
- internalDataEnabled &&
- (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
- !mIsPsRestricted &&
- desiredPowerState;
- if (!allowed && DBG) {
- String reason = "";
- if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
- reason += " - gprs= " + gprsState;
- }
- if (!mPhone.mIccRecords.getRecordsLoaded()) reason += " - SIM not loaded";
- if (mPhone.getState() != Phone.State.IDLE &&
- !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
- reason += " - PhoneState= " + mPhone.getState();
- reason += " - Concurrent voice and data not allowed";
- }
- if (!internalDataEnabled) reason += " - mInternalDataEnabled= false";
- if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) {
- reason += " - Roaming and data roaming not enabled";
- }
- if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
- if (!desiredPowerState) reason += " - desiredPowerState= false";
- if (DBG) log("isDataAllowed: not allowed due to" + reason);
- }
- return allowed;
- }
-
- private void setupDataOnReadyApns(String reason) {
- // Stop reconnect alarms on all data connections pending
- // retry. Reset ApnContext state to IDLE.
- for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
- if (dcac.getReconnectIntentSync() != null) {
- cancelReconnectAlarm(dcac);
- }
- // update retry config for existing calls to match up
- // ones for the new RAT.
- if (dcac.dataConnection != null) {
- Collection<ApnContext> apns = dcac.getApnListSync();
-
- boolean hasDefault = false;
- for (ApnContext apnContext : apns) {
- if (apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
- hasDefault = true;
- break;
- }
- }
- configureRetry(dcac.dataConnection, hasDefault, 0);
- }
- }
-
- // Be sure retry counts for Apncontexts and DC's are sync'd.
- // When DCT/ApnContexts are refactored and we cleanup retrying
- // this won't be needed.
- resetAllRetryCounts();
-
- // Only check for default APN state
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.getState() == State.FAILED) {
- // By this time, alarms for all failed Apns
- // should be stopped if any.
- // Make sure to set the state back to IDLE
- // so that setup data can happen.
- apnContext.setState(State.IDLE);
- }
- if (apnContext.isReady()) {
- if (apnContext.getState() == State.IDLE) {
- apnContext.setReason(reason);
- trySetupData(apnContext);
- }
- }
- }
- }
-
- private boolean trySetupData(String reason, String type) {
- if (DBG) {
- log("trySetupData: " + type + " due to " + (reason == null ? "(unspecified)" : reason)
- + " isPsRestricted=" + mIsPsRestricted);
- }
-
- if (type == null) {
- type = Phone.APN_TYPE_DEFAULT;
- }
-
- ApnContext apnContext = mApnContexts.get(type);
-
- if (apnContext == null ){
- if (DBG) log("trySetupData new apn context for type:" + type);
- apnContext = new ApnContext(type, LOG_TAG);
- mApnContexts.put(type, apnContext);
- }
- apnContext.setReason(reason);
-
- return trySetupData(apnContext);
- }
-
- private boolean trySetupData(ApnContext apnContext) {
- if (DBG) {
- log("trySetupData for type:" + apnContext.getApnType() +
- " due to " + apnContext.getReason());
- log("trySetupData with mIsPsRestricted=" + mIsPsRestricted);
- }
-
- if (mPhone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- apnContext.setState(State.CONNECTED);
- mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-
- log("trySetupData: (fix?) We're on the simulator; assuming data is connected");
- return true;
- }
-
- boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
-
- if ((apnContext.getState() == State.IDLE || apnContext.getState() == State.SCANNING) &&
- isDataAllowed(apnContext) && getAnyDataEnabled() && !isEmergency()) {
-
- if (apnContext.getState() == State.IDLE) {
- ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType());
- if (waitingApns.isEmpty()) {
- if (DBG) log("trySetupData: No APN found");
- notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN, apnContext);
- notifyOffApnsOfAvailability(apnContext.getReason());
- return false;
- } else {
- apnContext.setWaitingApns(waitingApns);
- if (DBG) {
- log ("trySetupData: Create from mAllApns : " + apnListToString(mAllApns));
- }
- }
- }
-
- if (DBG) {
- log ("Setup watingApns : " + apnListToString(apnContext.getWaitingApns()));
- }
- // apnContext.setReason(apnContext.getReason());
- boolean retValue = setupData(apnContext);
- notifyOffApnsOfAvailability(apnContext.getReason());
- return retValue;
- } else {
- // TODO: check the condition.
- if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)
- && (apnContext.getState() == State.IDLE
- || apnContext.getState() == State.SCANNING))
- mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
- notifyOffApnsOfAvailability(apnContext.getReason());
- return false;
- }
- }
-
- @Override
- // Disabled apn's still need avail/unavail notificiations - send them out
- protected void notifyOffApnsOfAvailability(String reason) {
- for (ApnContext apnContext : mApnContexts.values()) {
- if (!apnContext.isReady()) {
- if (DBG) log("notifyOffApnOfAvailability type:" + apnContext.getApnType());
- mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
- apnContext.getApnType(),
- Phone.DataState.DISCONNECTED);
- } else {
- if (DBG) {
- log("notifyOffApnsOfAvailability skipped apn due to isReady==false: " +
- apnContext.toString());
- }
- }
- }
- }
-
- /**
- * If tearDown is true, this only tears down a CONNECTED session. Presently,
- * there is no mechanism for abandoning an INITING/CONNECTING session,
- * but would likely involve cancelling pending async requests or
- * setting a flag or new state to ignore them when they came in
- * @param tearDown true if the underlying GsmDataConnection should be
- * disconnected.
- * @param reason reason for the clean up.
- */
- protected void cleanUpAllConnections(boolean tearDown, String reason) {
- if (DBG) log("cleanUpAllConnections: tearDown=" + tearDown + " reason=" + reason);
-
- for (ApnContext apnContext : mApnContexts.values()) {
- apnContext.setReason(reason);
- cleanUpConnection(tearDown, apnContext);
- }
-
- stopNetStatPoll();
- stopDataStallAlarm();
-
- // TODO: Do we need mRequestedApnType?
- mRequestedApnType = Phone.APN_TYPE_DEFAULT;
- }
-
- /**
- * Cleanup all connections.
- *
- * TODO: Cleanup only a specified connection passed as a parameter.
- * Also, make sure when you clean up a conn, if it is last apply
- * logic as though it is cleanupAllConnections
- *
- * @param tearDown true if the underlying DataConnection should be disconnected.
- * @param reason for the clean up.
- */
-
- @Override
- protected void onCleanUpAllConnections(String cause) {
- cleanUpAllConnections(true, cause);
- }
-
- private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
-
- if (apnContext == null) {
- if (DBG) log("cleanUpConnection: apn context is null");
- return;
- }
-
- DataConnectionAc dcac = apnContext.getDataConnectionAc();
- if (DBG) {
- log("cleanUpConnection: E tearDown=" + tearDown + " reason=" + apnContext.getReason() +
- " apnContext=" + apnContext);
- }
- if (tearDown) {
- if (apnContext.isDisconnected()) {
- // The request is tearDown and but ApnContext is not connected.
- // If apnContext is not enabled anymore, break the linkage to the DCAC/DC.
- apnContext.setState(State.IDLE);
- if (!apnContext.isReady()) {
- apnContext.setDataConnection(null);
- apnContext.setDataConnectionAc(null);
- }
- } else {
- // Connection is still there. Try to clean up.
- if (dcac != null) {
- if (apnContext.getState() != State.DISCONNECTING) {
- boolean disconnectAll = false;
- if (Phone.APN_TYPE_DUN.equals(apnContext.getApnType())) {
- ApnSetting dunSetting = fetchDunApn();
- if (dunSetting != null &&
- dunSetting.equals(apnContext.getApnSetting())) {
- if (DBG) log("tearing down dedicated DUN connection");
- // we need to tear it down - we brought it up just for dun and
- // other people are camped on it and now dun is done. We need
- // to stop using it and let the normal apn list get used to find
- // connections for the remaining desired connections
- disconnectAll = true;
- }
- }
- if (DBG) {
- log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :""));
- }
- Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
- if (disconnectAll) {
- apnContext.getDataConnection().tearDownAll(apnContext.getReason(), msg);
- } else {
- apnContext.getDataConnection().tearDown(apnContext.getReason(), msg);
- }
- apnContext.setState(State.DISCONNECTING);
- }
- } else {
- // apn is connected but no reference to dcac.
- // Should not be happen, but reset the state in case.
- apnContext.setState(State.IDLE);
- mPhone.notifyDataConnection(apnContext.getReason(),
- apnContext.getApnType());
- }
- }
- } else {
- // force clean up the data connection.
- if (dcac != null) dcac.resetSync();
- apnContext.setState(State.IDLE);
- mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
- apnContext.setDataConnection(null);
- apnContext.setDataConnectionAc(null);
- }
-
- // make sure reconnection alarm is cleaned up if there is no ApnContext
- // associated to the connection.
- if (dcac != null) {
- Collection<ApnContext> apnList = dcac.getApnListSync();
- if (apnList.isEmpty()) {
- cancelReconnectAlarm(dcac);
- }
- }
- if (DBG) {
- log("cleanUpConnection: X tearDown=" + tearDown + " reason=" + apnContext.getReason() +
- " apnContext=" + apnContext + " dc=" + apnContext.getDataConnection());
- }
- }
-
- /**
- * Cancels the alarm associated with DCAC.
- *
- * @param DataConnectionAc on which the alarm should be stopped.
- */
- private void cancelReconnectAlarm(DataConnectionAc dcac) {
- if (dcac == null) return;
-
- PendingIntent intent = dcac.getReconnectIntentSync();
-
- if (intent != null) {
- AlarmManager am =
- (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
- am.cancel(intent);
- dcac.setReconnectIntentSync(null);
- }
- }
-
- /**
- * @param types comma delimited list of APN types
- * @return array of APN types
- */
- private String[] parseTypes(String types) {
- String[] result;
- // If unset, set to DEFAULT.
- if (types == null || types.equals("")) {
- result = new String[1];
- result[0] = Phone.APN_TYPE_ALL;
- } else {
- result = types.split(",");
- }
- return result;
- }
-
- private ArrayList<ApnSetting> createApnList(Cursor cursor) {
- ArrayList<ApnSetting> result = new ArrayList<ApnSetting>();
- if (cursor.moveToFirst()) {
- do {
- String[] types = parseTypes(
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
- ApnSetting apn = new ApnSetting(
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
- NetworkUtils.trimV4AddrZeros(
- cursor.getString(
- cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
- NetworkUtils.trimV4AddrZeros(
- cursor.getString(
- cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
- NetworkUtils.trimV4AddrZeros(
- cursor.getString(
- cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
- types,
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
- cursor.getString(cursor.getColumnIndexOrThrow(
- Telephony.Carriers.ROAMING_PROTOCOL)),
- cursor.getInt(cursor.getColumnIndexOrThrow(
- Telephony.Carriers.CARRIER_ENABLED)) == 1,
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.BEARER)));
- result.add(apn);
- } while (cursor.moveToNext());
- }
- if (DBG) log("createApnList: X result=" + result);
- return result;
- }
-
- private boolean dataConnectionNotInUse(DataConnectionAc dcac) {
- if (DBG) log("dataConnectionNotInUse: check if dcac is inuse dc=" + dcac.dataConnection);
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.getDataConnectionAc() == dcac) {
- if (DBG) log("dataConnectionNotInUse: in use by apnContext=" + apnContext);
- return false;
- }
- }
- // TODO: Fix retry handling so free DataConnections have empty apnlists.
- // Probably move retry handling into DataConnections and reduce complexity
- // of DCT.
- for (ApnContext apnContext : dcac.getApnListSync()) {
- if (DBG) {
- log("dataConnectionNotInUse: removing apnContext=" + apnContext);
- }
- dcac.removeApnContextSync(apnContext);
- }
- if (DBG) log("dataConnectionNotInUse: not in use return true");
- return true;
- }
-
- private GsmDataConnection findFreeDataConnection() {
- for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
- if (dcac.isInactiveSync() && dataConnectionNotInUse(dcac)) {
- DataConnection dc = dcac.dataConnection;
- if (DBG) {
- log("findFreeDataConnection: found free GsmDataConnection=" +
- " dcac=" + dcac + " dc=" + dc);
- }
- return (GsmDataConnection) dc;
- }
- }
- log("findFreeDataConnection: NO free GsmDataConnection");
- return null;
- }
-
- protected GsmDataConnection findReadyDataConnection(ApnSetting apn) {
- if (apn == null) {
- return null;
- }
- if (DBG) {
- log("findReadyDataConnection: apn string <" + apn + ">" +
- " dcacs.size=" + mDataConnectionAsyncChannels.size());
- }
- for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
- ApnSetting apnSetting = dcac.getApnSettingSync();
- if (DBG) {
- log("findReadyDataConnection: dc apn string <" +
- (apnSetting != null ? (apnSetting.toString()) : "null") + ">");
- }
- if ((apnSetting != null) && TextUtils.equals(apnSetting.toString(), apn.toString())) {
- DataConnection dc = dcac.dataConnection;
- if (DBG) {
- log("findReadyDataConnection: found ready GsmDataConnection=" +
- " dcac=" + dcac + " dc=" + dc);
- }
- return (GsmDataConnection) dc;
- }
- }
- return null;
- }
-
-
- private boolean setupData(ApnContext apnContext) {
- if (DBG) log("setupData: apnContext=" + apnContext);
- ApnSetting apn;
- GsmDataConnection dc;
-
- int profileId = getApnProfileID(apnContext.getApnType());
- apn = apnContext.getNextWaitingApn();
- if (apn == null) {
- if (DBG) log("setupData: return for no apn found!");
- return false;
- }
-
-
- dc = (GsmDataConnection) checkForConnectionForApnContext(apnContext);
-
- if (dc == null) {
- dc = findReadyDataConnection(apn);
-
- if (dc == null) {
- if (DBG) log("setupData: No ready GsmDataConnection found!");
- // TODO: When allocating you are mapping type to id. If more than 1 free,
- // then could findFreeDataConnection get the wrong one??
- dc = findFreeDataConnection();
- }
-
- if (dc == null) {
- dc = createDataConnection();
- }
-
- if (dc == null) {
- if (DBG) log("setupData: No free GsmDataConnection found!");
- return false;
- }
- } else {
- apn = mDataConnectionAsyncChannels.get(dc.getDataConnectionId()).getApnSettingSync();
- }
-
- DataConnectionAc dcac = mDataConnectionAsyncChannels.get(dc.getDataConnectionId());
- dc.setProfileId( profileId ); // assumed no connection sharing on profiled types
-
- int refCount = dcac.getRefCountSync();
- if (DBG) log("setupData: init dc and apnContext refCount=" + refCount);
-
- // configure retry count if no other Apn is using the same connection.
- if (refCount == 0) {
- configureRetry(dc, apn.canHandleType(Phone.APN_TYPE_DEFAULT),
- apnContext.getRetryCount());
- }
- apnContext.setDataConnectionAc(dcac);
- apnContext.setDataConnection(dc);
-
- apnContext.setApnSetting(apn);
- apnContext.setState(State.INITING);
- mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
- // If reconnect alarm is active on this DataConnection, wait for the alarm being
- // fired so that we don't disruppt data retry pattern engaged.
- if (apnContext.getDataConnectionAc().getReconnectIntentSync() != null) {
- if (DBG) log("setupData: data reconnection pending");
- apnContext.setState(State.FAILED);
- mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
- return true;
- }
-
- Message msg = obtainMessage();
- msg.what = EVENT_DATA_SETUP_COMPLETE;
- msg.obj = apnContext;
- dc.bringUp(msg, apn);
-
- if (DBG) log("setupData: initing!");
- return true;
- }
-
- /**
- * Handles changes to the APN database.
- */
- private void onApnChanged() {
- State overallState = getOverallState();
- boolean isDisconnected = (overallState == State.IDLE || overallState == State.FAILED);
-
- if (mPhone instanceof GSMPhone) {
- // The "current" may no longer be valid. MMS depends on this to send properly. TBD
- ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
- }
-
- // TODO: It'd be nice to only do this if the changed entrie(s)
- // match the current operator.
- if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
- createAllApnList();
- cleanUpAllConnections(!isDisconnected, Phone.REASON_APN_CHANGED);
- if (isDisconnected) {
- setupDataOnReadyApns(Phone.REASON_APN_CHANGED);
- }
- }
-
- /**
- * @param cid Connection id provided from RIL.
- * @return DataConnectionAc associated with specified cid.
- */
- private DataConnectionAc findDataConnectionAcByCid(int cid) {
- for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
- if (dcac.getCidSync() == cid) {
- return dcac;
- }
- }
- return null;
- }
-
- /**
- * @param dcacs Collection of DataConnectionAc reported from RIL.
- * @return List of ApnContext which is connected, but is not present in
- * data connection list reported from RIL.
- */
- private List<ApnContext> findApnContextToClean(Collection<DataConnectionAc> dcacs) {
- if (dcacs == null) return null;
-
- if (DBG) log("findApnContextToClean(ar): E dcacs=" + dcacs);
-
- ArrayList<ApnContext> list = new ArrayList<ApnContext>();
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.getState() == State.CONNECTED) {
- boolean found = false;
- for (DataConnectionAc dcac : dcacs) {
- if (dcac == apnContext.getDataConnectionAc()) {
- // ApnContext holds the ref to dcac present in data call list.
- found = true;
- break;
- }
- }
- if (!found) {
- // ApnContext does not have dcac reported in data call list.
- // Fetch all the ApnContexts that map to this dcac which are in
- // INITING state too.
- if (DBG) log("findApnContextToClean(ar): Connected apn not found in the list (" +
- apnContext.toString() + ")");
- if (apnContext.getDataConnectionAc() != null) {
- list.addAll(apnContext.getDataConnectionAc().getApnListSync());
- } else {
- list.add(apnContext);
- }
- }
- }
- }
- if (DBG) log("findApnContextToClean(ar): X list=" + list);
- return list;
- }
-
- /**
- * @param ar is the result of RIL_REQUEST_DATA_CALL_LIST
- * or RIL_UNSOL_DATA_CALL_LIST_CHANGED
- */
- private void onDataStateChanged (AsyncResult ar) {
- ArrayList<DataCallState> dataCallStates;
-
- if (DBG) log("onDataStateChanged(ar): E");
- dataCallStates = (ArrayList<DataCallState>)(ar.result);
-
- if (ar.exception != null) {
- // This is probably "radio not available" or something
- // of that sort. If so, the whole connection is going
- // to come down soon anyway
- if (DBG) log("onDataStateChanged(ar): exception; likely radio not available, ignore");
- return;
- }
- if (DBG) log("onDataStateChanged(ar): DataCallState size=" + dataCallStates.size());
-
- // Create a hash map to store the dataCallState of each DataConnectionAc
- HashMap<DataCallState, DataConnectionAc> dataCallStateToDcac;
- dataCallStateToDcac = new HashMap<DataCallState, DataConnectionAc>();
- for (DataCallState dataCallState : dataCallStates) {
- DataConnectionAc dcac = findDataConnectionAcByCid(dataCallState.cid);
-
- if (dcac != null) dataCallStateToDcac.put(dataCallState, dcac);
- }
-
- // A list of apns to cleanup, those that aren't in the list we know we have to cleanup
- List<ApnContext> apnsToCleanup = findApnContextToClean(dataCallStateToDcac.values());
-
- // Find which connections have changed state and send a notification or cleanup
- for (DataCallState newState : dataCallStates) {
- DataConnectionAc dcac = dataCallStateToDcac.get(newState);
-
- if (dcac == null) {
- loge("onDataStateChanged(ar): No associated DataConnection ignore");
- continue;
- }
-
- // The list of apn's associated with this DataConnection
- Collection<ApnContext> apns = dcac.getApnListSync();
-
- // Find which ApnContexts of this DC are in the "Connected/Connecting" state.
- ArrayList<ApnContext> connectedApns = new ArrayList<ApnContext>();
- for (ApnContext apnContext : apns) {
- if (apnContext.getState() == State.CONNECTED ||
- apnContext.getState() == State.CONNECTING ||
- apnContext.getState() == State.INITING) {
- connectedApns.add(apnContext);
- }
- }
- if (connectedApns.size() == 0) {
- if (DBG) log("onDataStateChanged(ar): no connected apns");
- } else {
- // Determine if the connection/apnContext should be cleaned up
- // or just a notification should be sent out.
- if (DBG) log("onDataStateChanged(ar): Found ConnId=" + newState.cid
- + " newState=" + newState.toString());
- if (newState.active == 0) {
- if (DBG) {
- log("onDataStateChanged(ar): inactive, cleanup apns=" + connectedApns);
- }
- apnsToCleanup.addAll(connectedApns);
- } else {
- // Its active so update the DataConnections link properties
- UpdateLinkPropertyResult result =
- dcac.updateLinkPropertiesDataCallStateSync(newState);
- if (result.oldLp.equals(result.newLp)) {
- if (DBG) log("onDataStateChanged(ar): no change");
- } else {
- if (result.oldLp.isIdenticalInterfaceName(result.newLp)) {
- if (! result.oldLp.isIdenticalDnses(result.newLp) ||
- ! result.oldLp.isIdenticalRoutes(result.newLp) ||
- ! result.oldLp.isIdenticalHttpProxy(result.newLp) ||
- ! result.oldLp.isIdenticalAddresses(result.newLp)) {
- // If the same address type was removed and added we need to cleanup
- CompareResult<LinkAddress> car =
- result.oldLp.compareAddresses(result.newLp);
- if (DBG) {
- log("onDataStateChanged: oldLp=" + result.oldLp +
- " newLp=" + result.newLp + " car=" + car);
- }
- boolean needToClean = false;
- for (LinkAddress added : car.added) {
- for (LinkAddress removed : car.removed) {
- if (NetworkUtils.addressTypeMatches(removed.getAddress(),
- added.getAddress())) {
- needToClean = true;
- break;
- }
- }
- }
- if (needToClean) {
- if (DBG) {
- log("onDataStateChanged(ar): addr change, cleanup apns=" +
- connectedApns + " oldLp=" + result.oldLp +
- " newLp=" + result.newLp);
- }
- apnsToCleanup.addAll(connectedApns);
- } else {
- if (DBG) log("onDataStateChanged(ar): simple change");
- for (ApnContext apnContext : connectedApns) {
- mPhone.notifyDataConnection(
- Phone.REASON_LINK_PROPERTIES_CHANGED,
- apnContext.getApnType());
- }
- }
- } else {
- if (DBG) {
- log("onDataStateChanged(ar): no changes");
- }
- }
- } else {
- if (DBG) {
- log("onDataStateChanged(ar): interface change, cleanup apns="
- + connectedApns);
- }
- apnsToCleanup.addAll(connectedApns);
- }
- }
- }
- }
- }
-
- if (apnsToCleanup.size() != 0) {
- // Add an event log when the network drops PDP
- int cid = getCellLocationId();
- EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
- TelephonyManager.getDefault().getNetworkType());
- }
-
- // Cleanup those dropped connections
- if (DBG) log("onDataStateChange(ar): apnsToCleanup=" + apnsToCleanup);
- for (ApnContext apnContext : apnsToCleanup) {
- cleanUpConnection(true, apnContext);
- }
-
- if (DBG) log("onDataStateChanged(ar): X");
- }
-
- private void notifyDefaultData(ApnContext apnContext) {
- if (DBG) {
- log("notifyDefaultData: type=" + apnContext.getApnType()
- + ", reason:" + apnContext.getReason());
- }
- apnContext.setState(State.CONNECTED);
- // setState(State.CONNECTED);
- mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
- startNetStatPoll();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- // reset reconnect timer
- apnContext.setRetryCount(0);
- }
-
- // TODO: For multiple Active APNs not exactly sure how to do this.
- protected void gotoIdleAndNotifyDataConnection(String reason) {
- if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
- notifyDataConnection(reason);
- mActiveApn = null;
- }
-
- private void resetPollStats() {
- mTxPkts = -1;
- mRxPkts = -1;
- mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
- }
-
- private void doRecovery() {
- if (getOverallState() == State.CONNECTED) {
- // Go through a series of recovery steps, each action transitions to the next action
- int recoveryAction = getRecoveryAction();
- switch (recoveryAction) {
- case RecoveryAction.GET_DATA_CALL_LIST:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
- mSentSinceLastRecv);
- if (DBG) log("doRecovery() get data call list");
- mPhone.mCM.getDataCallList(obtainMessage(EVENT_DATA_STATE_CHANGED));
- putRecoveryAction(RecoveryAction.CLEANUP);
- break;
- case RecoveryAction.CLEANUP:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
- if (DBG) log("doRecovery() cleanup all connections");
- cleanUpAllConnections(true, Phone.REASON_PDP_RESET);
- putRecoveryAction(RecoveryAction.REREGISTER);
- break;
- case RecoveryAction.REREGISTER:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
- mSentSinceLastRecv);
- if (DBG) log("doRecovery() re-register");
- mPhone.getServiceStateTracker().reRegisterNetwork(null);
- putRecoveryAction(RecoveryAction.RADIO_RESTART);
- break;
- case RecoveryAction.RADIO_RESTART:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
- mSentSinceLastRecv);
- if (DBG) log("restarting radio");
- putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP);
- restartRadio();
- break;
- case RecoveryAction.RADIO_RESTART_WITH_PROP:
- // This is in case radio restart has not recovered the data.
- // It will set an additional "gsm.radioreset" property to tell
- // RIL or system to take further action.
- // The implementation of hard reset recovery action is up to OEM product.
- // Once gsm.radioreset property is consumed, it is expected to set back
- // to false by RIL.
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1);
- if (DBG) log("restarting radio with gsm.radioreset to true");
- SystemProperties.set("gsm.radioreset", "true");
- // give 1 sec so property change can be notified.
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {}
- restartRadio();
- putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
- break;
- default:
- throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
- recoveryAction);
- }
- }
- }
-
- @Override
- protected void startNetStatPoll() {
- if (getOverallState() == State.CONNECTED && mNetStatPollEnabled == false) {
- if (DBG) log("startNetStatPoll");
- resetPollStats();
- mNetStatPollEnabled = true;
- mPollNetStat.run();
- }
- }
-
- @Override
- protected void stopNetStatPoll() {
- mNetStatPollEnabled = false;
- removeCallbacks(mPollNetStat);
- if (DBG) log("stopNetStatPoll");
- }
-
- @Override
- protected void restartRadio() {
- if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
- cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
- mPhone.getServiceStateTracker().powerOffRadioSafely(this);
- /* Note: no need to call setRadioPower(true). Assuming the desired
- * radio power state is still ON (as tracked by ServiceStateTracker),
- * ServiceStateTracker will call setRadioPower when it receives the
- * RADIO_STATE_CHANGED notification for the power off. And if the
- * desired power state has changed in the interim, we don't want to
- * override it with an unconditional power on.
- */
-
- int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0"));
- SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1));
- }
-
-
- private void updateDataStallInfo() {
- long sent, received;
-
- TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
- mDataStallTxRxSum.updateTxRxSum();
-
- if (VDBG) {
- log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
- " preTxRxSum=" + preTxRxSum);
- }
-
- sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
- received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
-
- if (RADIO_TESTS) {
- if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
- log("updateDataStallInfo: radio.test.data.stall true received = 0;");
- received = 0;
- }
- }
- if ( sent > 0 && received > 0 ) {
- if (VDBG) log("updateDataStallInfo: IN/OUT");
- mSentSinceLastRecv = 0;
- putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
- } else if (sent > 0 && received == 0) {
- if (mPhone.getState() == Phone.State.IDLE) {
- mSentSinceLastRecv += sent;
- } else {
- mSentSinceLastRecv = 0;
- }
- if (DBG) {
- log("updateDataStallInfo: OUT sent=" + sent +
- " mSentSinceLastRecv=" + mSentSinceLastRecv);
- }
- } else if (sent == 0 && received > 0) {
- if (VDBG) log("updateDataStallInfo: IN");
- mSentSinceLastRecv = 0;
- putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
- } else {
- if (VDBG) log("updateDataStallInfo: NONE");
- }
- }
-
- @Override
- protected void onDataStallAlarm(int tag) {
- if (mDataStallAlarmTag != tag) {
- if (DBG) {
- log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
- }
- return;
- }
- updateDataStallInfo();
-
- int hangWatchdogTrigger = Settings.Secure.getInt(mResolver,
- Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
- NUMBER_SENT_PACKETS_OF_HANG);
-
- boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
- if (mSentSinceLastRecv >= hangWatchdogTrigger) {
- if (DBG) {
- log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction());
- }
- suspectedStall = DATA_STALL_SUSPECTED;
- sendMessage(obtainMessage(EVENT_DO_RECOVERY));
- } else {
- if (VDBG) {
- log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
- " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
- }
- }
- startDataStallAlarm(suspectedStall);
- }
-
-
- private void updateDataActivity() {
- long sent, received;
-
- Activity newActivity;
-
- TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
- TxRxSum curTxRxSum = new TxRxSum();
- curTxRxSum.updateTxRxSum();
- mTxPkts = curTxRxSum.txPkts;
- mRxPkts = curTxRxSum.rxPkts;
-
- if (VDBG) {
- log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
- }
-
- if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
- sent = mTxPkts - preTxRxSum.txPkts;
- received = mRxPkts - preTxRxSum.rxPkts;
-
- if (VDBG) log("updateDataActivity: sent=" + sent + " received=" + received);
- if ( sent > 0 && received > 0 ) {
- newActivity = Activity.DATAINANDOUT;
- } else if (sent > 0 && received == 0) {
- newActivity = Activity.DATAOUT;
- } else if (sent == 0 && received > 0) {
- newActivity = Activity.DATAIN;
- } else {
- newActivity = Activity.NONE;
- }
-
- if (mActivity != newActivity && mIsScreenOn) {
- if (VDBG) log("updateDataActivity: newActivity=" + newActivity);
- mActivity = newActivity;
- mPhone.notifyDataActivity();
- }
- }
- }
-
- private Runnable mPollNetStat = new Runnable()
- {
- @Override
- public void run() {
- updateDataActivity();
-
- if (mIsScreenOn) {
- mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
- Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
- } else {
- mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
- Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
- POLL_NETSTAT_SCREEN_OFF_MILLIS);
- }
-
- if (mNetStatPollEnabled) {
- mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
- }
- }
- };
-
- /**
- * Returns true if the last fail cause is something that
- * seems like it deserves an error notification.
- * Transient errors are ignored
- */
- private boolean shouldPostNotification(GsmDataConnection.FailCause cause) {
- return (cause != GsmDataConnection.FailCause.UNKNOWN);
- }
-
- /**
- * Return true if data connection need to be setup after disconnected due to
- * reason.
- *
- * @param reason the reason why data is disconnected
- * @return true if try setup data connection is need for this reason
- */
- private boolean retryAfterDisconnected(String reason) {
- boolean retry = true;
-
- if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ) {
- retry = false;
- }
- return retry;
- }
-
- private void reconnectAfterFail(FailCause lastFailCauseCode,
- ApnContext apnContext, int retryOverride) {
- if (apnContext == null) {
- loge("reconnectAfterFail: apnContext == null, impossible");
- return;
- }
- if (DBG) {
- log("reconnectAfterFail: lastFailCause=" + lastFailCauseCode +
- " retryOverride=" + retryOverride + " apnContext=" + apnContext);
- }
- if ((apnContext.getState() == State.FAILED) &&
- (apnContext.getDataConnection() != null)) {
- if (!apnContext.getDataConnection().isRetryNeeded()) {
- if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
- mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
- return;
- }
- if (mReregisterOnReconnectFailure) {
- // We've re-registerd once now just retry forever.
- apnContext.getDataConnection().retryForeverUsingLastTimeout();
- } else {
- // Try to Re-register to the network.
- if (DBG) log("reconnectAfterFail: activate failed, Reregistering to network");
- mReregisterOnReconnectFailure = true;
- mPhone.getServiceStateTracker().reRegisterNetwork(null);
- apnContext.setRetryCount(0);
- return;
- }
- }
-
- // If retry needs to be backed off for specific case (determined by RIL/Modem)
- // use the specified timer instead of pre-configured retry pattern.
- int nextReconnectDelay = retryOverride;
- if (nextReconnectDelay < 0) {
- nextReconnectDelay = apnContext.getDataConnection().getRetryTimer();
- apnContext.getDataConnection().increaseRetryCount();
- if (DBG) {
- log("reconnectAfterFail: increaseRetryCount=" +
- apnContext.getDataConnection().getRetryCount() +
- " nextReconnectDelay=" + nextReconnectDelay);
- }
- }
- startAlarmForReconnect(nextReconnectDelay, apnContext);
-
- if (!shouldPostNotification(lastFailCauseCode)) {
- if (DBG) {
- log("reconnectAfterFail: NOT Posting GPRS Unavailable notification "
- + "-- likely transient error");
- }
- } else {
- notifyNoData(lastFailCauseCode, apnContext);
- }
- }
- }
-
- private void startAlarmForReconnect(int delay, ApnContext apnContext) {
-
- DataConnectionAc dcac = apnContext.getDataConnectionAc();
-
- if ((dcac == null) || (dcac.dataConnection == null)) {
- // should not happen, but just in case.
- loge("startAlarmForReconnect: null dcac or dc.");
- return;
- }
-
- AlarmManager am =
- (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-
- Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' +
- dcac.dataConnection.getDataConnectionId());
- String reason = apnContext.getReason();
- intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
- int connectionId = dcac.dataConnection.getDataConnectionId();
- intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, connectionId);
-
- // TODO: Until a real fix is created, which probably entails pushing
- // retires into the DC itself, this fix gets the retry count and
- // puts it in the reconnect alarm. When the reconnect alarm fires
- // onActionIntentReconnectAlarm is called which will use the value saved
- // here and save it in the ApnContext and send the EVENT_CONNECT message
- // which invokes setupData. Then setupData will use the value in the ApnContext
- // and to tell the DC to set the retry count in the retry manager.
- int retryCount = dcac.dataConnection.getRetryCount();
- intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, retryCount);
-
- if (DBG) {
- log("startAlarmForReconnect: next attempt in " + (delay / 1000) + "s" +
- " reason='" + reason + "' connectionId=" + connectionId +
- " retryCount=" + retryCount);
- }
-
- PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
- intent, PendingIntent.FLAG_UPDATE_CURRENT);
- dcac.setReconnectIntentSync(alarmIntent);
- am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + delay, alarmIntent);
-
- }
-
- private void startDataStallAlarm(boolean suspectedStall) {
- int nextAction = getRecoveryAction();
- int delayInMs;
-
- // If screen is on or data stall is currently suspected, set the alarm
- // with an aggresive timeout.
- if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) {
- delayInMs = Settings.Secure.getInt(mResolver,
- Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
- DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
- } else {
- delayInMs = Settings.Secure.getInt(mResolver,
- Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
- DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
- }
-
- mDataStallAlarmTag += 1;
- if (VDBG) {
- log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
- " delay=" + (delayInMs / 1000) + "s");
- }
- AlarmManager am =
- (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-
- Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
- intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag);
- mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
- }
-
- private void stopDataStallAlarm() {
- AlarmManager am =
- (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-
- if (VDBG) {
- log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
- " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
- }
- mDataStallAlarmTag += 1;
- if (mDataStallAlarmIntent != null) {
- am.cancel(mDataStallAlarmIntent);
- mDataStallAlarmIntent = null;
- }
- }
-
- @Override
- protected void restartDataStallAlarm() {
- if (isConnected() == false) return;
- // To be called on screen status change.
- // Do not cancel the alarm if it is set with aggressive timeout.
- int nextAction = getRecoveryAction();
-
- if (RecoveryAction.isAggressiveRecovery(nextAction)) {
- if (DBG) log("data stall recovery action is pending. not resetting the alarm.");
- return;
- }
- stopDataStallAlarm();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- }
-
- private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode,
- ApnContext apnContext) {
- if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
- apnContext.setState(State.FAILED);
- if (lastFailCauseCode.isPermanentFail()
- && (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT))) {
- mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
- }
- }
-
- private void onRecordsLoaded() {
- if (DBG) log("onRecordsLoaded: createAllApnList");
- createAllApnList();
- if (mPhone.mCM.getRadioState().isOn()) {
- if (DBG) log("onRecordsLoaded: notifying data availability");
- notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
- }
- setupDataOnReadyApns(Phone.REASON_SIM_LOADED);
- }
-
- @Override
- protected void onSetDependencyMet(String apnType, boolean met) {
- // don't allow users to tweak hipri to work around default dependency not met
- if (Phone.APN_TYPE_HIPRI.equals(apnType)) return;
-
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext == null) {
- loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
- apnType + ", " + met + ")");
- return;
- }
- applyNewState(apnContext, apnContext.isEnabled(), met);
- if (Phone.APN_TYPE_DEFAULT.equals(apnType)) {
- // tie actions on default to similar actions on HIPRI regarding dependencyMet
- apnContext = mApnContexts.get(Phone.APN_TYPE_HIPRI);
- if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
- }
- }
-
- private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {
- boolean cleanup = false;
- boolean trySetup = false;
- if (DBG) {
- log("applyNewState(" + apnContext.getApnType() + ", " + enabled +
- "(" + apnContext.isEnabled() + "), " + met + "(" +
- apnContext.getDependencyMet() +"))");
- }
- if (apnContext.isReady()) {
- if (enabled && met) return;
- if (!enabled) {
- apnContext.setReason(Phone.REASON_DATA_DISABLED);
- } else {
- apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
- }
- cleanup = true;
- } else {
- if (enabled && met) {
- if (apnContext.isEnabled()) {
- apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
- } else {
- apnContext.setReason(Phone.REASON_DATA_ENABLED);
- }
- if (apnContext.getState() == State.FAILED) {
- apnContext.setState(State.IDLE);
- }
- trySetup = true;
- }
- }
- apnContext.setEnabled(enabled);
- apnContext.setDependencyMet(met);
- if (cleanup) cleanUpConnection(true, apnContext);
- if (trySetup) trySetupData(apnContext);
- }
-
- private DataConnection checkForConnectionForApnContext(ApnContext apnContext) {
- // Loop through all apnContexts looking for one with a conn that satisfies this apnType
- String apnType = apnContext.getApnType();
- ApnSetting dunSetting = null;
-
- if (Phone.APN_TYPE_DUN.equals(apnType)) {
- dunSetting = fetchDunApn();
- }
-
- DataConnection potential = null;
- for (ApnContext c : mApnContexts.values()) {
- DataConnection conn = c.getDataConnection();
- if (conn != null) {
- ApnSetting apnSetting = c.getApnSetting();
- if (dunSetting != null) {
- if (dunSetting.equals(apnSetting)) {
- switch (c.getState()) {
- case CONNECTED:
- if (DBG) {
- log("checkForConnectionForApnContext: apnContext=" +
- apnContext + " found conn=" + conn);
- }
- return conn;
- case CONNECTING:
- potential = conn;
- }
- }
- } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
- switch (c.getState()) {
- case CONNECTED:
- if (DBG) {
- log("checkForConnectionForApnContext: apnContext=" + apnContext +
- " found conn=" + conn);
- }
- return conn;
- case CONNECTING:
- potential = conn;
- }
- }
- }
- }
- if (potential != null) {
- if (DBG) {
- log("checkForConnectionForApnContext: apnContext=" + apnContext +
- " found conn=" + potential);
- }
- return potential;
- }
-
- if (DBG) log("checkForConnectionForApnContext: apnContext=" + apnContext + " NO conn");
- return null;
- }
-
- @Override
- protected void onEnableApn(int apnId, int enabled) {
- ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
- if (apnContext == null) {
- loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
- return;
- }
- // TODO change our retry manager to use the appropriate numbers for the new APN
- if (DBG) log("onEnableApn: apnContext=" + apnContext + " call applyNewState");
- applyNewState(apnContext, enabled == ENABLED, apnContext.getDependencyMet());
- }
-
- @Override
- // TODO: We shouldnt need this.
- protected boolean onTrySetupData(String reason) {
- if (DBG) log("onTrySetupData: reason=" + reason);
- setupDataOnReadyApns(reason);
- return true;
- }
-
- protected boolean onTrySetupData(ApnContext apnContext) {
- if (DBG) log("onTrySetupData: apnContext=" + apnContext);
- return trySetupData(apnContext);
- }
-
- @Override
- protected void onRoamingOff() {
- if (DBG) log("onRoamingOff");
-
- if (mUserDataEnabled == false) return;
-
- if (getDataOnRoamingEnabled() == false) {
- notifyOffApnsOfAvailability(Phone.REASON_ROAMING_OFF);
- setupDataOnReadyApns(Phone.REASON_ROAMING_OFF);
- } else {
- notifyDataConnection(Phone.REASON_ROAMING_OFF);
- }
- }
-
- @Override
- protected void onRoamingOn() {
- if (mUserDataEnabled == false) return;
-
- if (getDataOnRoamingEnabled()) {
- if (DBG) log("onRoamingOn: setup data on roaming");
- setupDataOnReadyApns(Phone.REASON_ROAMING_ON);
- notifyDataConnection(Phone.REASON_ROAMING_ON);
- } else {
- if (DBG) log("onRoamingOn: Tear down data connection on roaming.");
- cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
- notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
- }
- }
-
- @Override
- protected void onRadioAvailable() {
- if (DBG) log("onRadioAvailable");
- if (mPhone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- // setState(State.CONNECTED);
- notifyDataConnection(null);
-
- log("onRadioAvailable: We're on the simulator; assuming data is connected");
- }
-
- if (mPhone.mIccRecords.getRecordsLoaded()) {
- notifyOffApnsOfAvailability(null);
- }
-
- if (getOverallState() != State.IDLE) {
- cleanUpConnection(true, null);
- }
- }
-
- @Override
- protected void onRadioOffOrNotAvailable() {
- // Make sure our reconnect delay starts at the initial value
- // next time the radio comes on
-
- resetAllRetryCounts();
- mReregisterOnReconnectFailure = false;
-
- if (mPhone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- log("We're on the simulator; assuming radio off is meaningless");
- } else {
- if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
- cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
- }
- notifyOffApnsOfAvailability(null);
- }
-
- @Override
- protected void onDataSetupComplete(AsyncResult ar) {
-
- DataConnection.FailCause cause = DataConnection.FailCause.UNKNOWN;
- boolean handleError = false;
- ApnContext apnContext = null;
-
- if(ar.userObj instanceof ApnContext){
- apnContext = (ApnContext)ar.userObj;
- } else {
- throw new RuntimeException("onDataSetupComplete: No apnContext");
- }
-
- if (isDataSetupCompleteOk(ar)) {
- DataConnectionAc dcac = apnContext.getDataConnectionAc();
-
- if (RADIO_TESTS) {
- // Note: To change radio.test.onDSC.null.dcac from command line you need to
- // adb root and adb remount and from the command line you can only change the
- // value to 1 once. To change it a second time you can reboot or execute
- // adb shell stop and then adb shell start. The command line to set the value is:
- // adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "insert into system (name,value) values ('radio.test.onDSC.null.dcac', '1');"
- ContentResolver cr = mPhone.getContext().getContentResolver();
- String radioTestProperty = "radio.test.onDSC.null.dcac";
- if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
- log("onDataSetupComplete: " + radioTestProperty +
- " is true, set dcac to null and reset property to false");
- dcac = null;
- Settings.System.putInt(cr, radioTestProperty, 0);
- log("onDataSetupComplete: " + radioTestProperty + "=" +
- Settings.System.getInt(mPhone.getContext().getContentResolver(),
- radioTestProperty, -1));
- }
- }
- if (dcac == null) {
- log("onDataSetupComplete: no connection to DC, handle as error");
- cause = DataConnection.FailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
- handleError = true;
- } else {
- DataConnection dc = apnContext.getDataConnection();
- ApnSetting apn = apnContext.getApnSetting();
- if (DBG) {
- log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
- }
- if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
- try {
- String port = apn.port;
- if (TextUtils.isEmpty(port)) port = "8080";
- ProxyProperties proxy = new ProxyProperties(apn.proxy,
- Integer.parseInt(port), null);
- dcac.setLinkPropertiesHttpProxySync(proxy);
- } catch (NumberFormatException e) {
- loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
- apn.port + "): " + e);
- }
- }
-
- // everything is setup
- if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) {
- SystemProperties.set("gsm.defaultpdpcontext.active", "true");
- if (canSetPreferApn && mPreferredApn == null) {
- if (DBG) log("onDataSetupComplete: PREFERED APN is null");
- mPreferredApn = apn;
- if (mPreferredApn != null) {
- setPreferredApn(mPreferredApn.id);
- }
- }
- } else {
- SystemProperties.set("gsm.defaultpdpcontext.active", "false");
- }
- notifyDefaultData(apnContext);
- }
- } else {
- cause = (DataConnection.FailCause) (ar.result);
- if (DBG) {
- ApnSetting apn = apnContext.getApnSetting();
- log(String.format("onDataSetupComplete: error apn=%s cause=%s",
- (apn == null ? "unknown" : apn.apn), cause));
- }
- if (cause.isEventLoggable()) {
- // Log this failure to the Event Logs.
- int cid = getCellLocationId();
- EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
- cause.ordinal(), cid, TelephonyManager.getDefault().getNetworkType());
- }
-
- // Count permanent failures and remove the APN we just tried
- if (cause.isPermanentFail()) apnContext.decWaitingApnsPermFailCount();
-
- apnContext.removeWaitingApn(apnContext.getApnSetting());
- if (DBG) {
- log(String.format("onDataSetupComplete: WaitingApns.size=%d" +
- " WaitingApnsPermFailureCountDown=%d",
- apnContext.getWaitingApns().size(),
- apnContext.getWaitingApnsPermFailCount()));
- }
- handleError = true;
- }
-
- if (handleError) {
- // See if there are more APN's to try
- if (apnContext.getWaitingApns().isEmpty()) {
- if (apnContext.getWaitingApnsPermFailCount() == 0) {
- if (DBG) {
- log("onDataSetupComplete: All APN's had permanent failures, stop retrying");
- }
- apnContext.setState(State.FAILED);
- mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
-
- apnContext.setDataConnection(null);
- apnContext.setDataConnectionAc(null);
- } else {
- if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
- // check to see if retry should be overridden for this failure.
- int retryOverride = -1;
- if (ar.exception instanceof DataConnection.CallSetupException) {
- retryOverride =
- ((DataConnection.CallSetupException)ar.exception).getRetryOverride();
- }
- if (retryOverride == RILConstants.MAX_INT) {
- if (DBG) log("No retry is suggested.");
- } else {
- startDelayedRetry(cause, apnContext, retryOverride);
- }
- }
- } else {
- if (DBG) log("onDataSetupComplete: Try next APN");
- apnContext.setState(State.SCANNING);
- // Wait a bit before trying the next APN, so that
- // we're not tying up the RIL command channel
- startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
- }
- }
- }
-
- /**
- * Called when EVENT_DISCONNECT_DONE is received.
- */
- @Override
- protected void onDisconnectDone(int connId, AsyncResult ar) {
- ApnContext apnContext = null;
-
- if (ar.userObj instanceof ApnContext) {
- apnContext = (ApnContext) ar.userObj;
- } else {
- loge("onDisconnectDone: Invalid ar in onDisconnectDone, ignore");
- return;
- }
-
- if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
- apnContext.setState(State.IDLE);
-
- mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
-
- // if all data connection are gone, check whether Airplane mode request was
- // pending.
- if (isDisconnected()) {
- if (mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
- // Radio will be turned off. No need to retry data setup
- apnContext.setApnSetting(null);
- apnContext.setDataConnection(null);
- apnContext.setDataConnectionAc(null);
- return;
- }
- }
-
- // If APN is still enabled, try to bring it back up automatically
- if (apnContext.isReady() && retryAfterDisconnected(apnContext.getReason())) {
- SystemProperties.set("gsm.defaultpdpcontext.active", "false"); // TODO - what the heck? This shoudld go
- // Wait a bit before trying the next APN, so that
- // we're not tying up the RIL command channel.
- // This also helps in any external dependency to turn off the context.
- startAlarmForReconnect(APN_DELAY_MILLIS, apnContext);
- } else {
- apnContext.setApnSetting(null);
- apnContext.setDataConnection(null);
- apnContext.setDataConnectionAc(null);
- }
- }
-
- protected void onPollPdp() {
- if (getOverallState() == State.CONNECTED) {
- // only poll when connected
- mPhone.mCM.getDataCallList(this.obtainMessage(EVENT_DATA_STATE_CHANGED));
- sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
- }
- }
-
- @Override
- protected void onVoiceCallStarted() {
- if (DBG) log("onVoiceCallStarted");
- if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
- if (DBG) log("onVoiceCallStarted stop polling");
- stopNetStatPoll();
- stopDataStallAlarm();
- notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
- }
- }
-
- @Override
- protected void onVoiceCallEnded() {
- if (DBG) log("onVoiceCallEnded");
- if (isConnected()) {
- if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
- startNetStatPoll();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
- } else {
- // clean slate after call end.
- resetPollStats();
- }
- }
- // reset reconnect timer
- setupDataOnReadyApns(Phone.REASON_VOICE_CALL_ENDED);
- }
-
- @Override
- protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
- if (DBG) log("onCleanUpConnection");
- ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
- if (apnContext != null) {
- apnContext.setReason(reason);
- cleanUpConnection(tearDown, apnContext);
- }
- }
-
- protected boolean isConnected() {
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.getState() == State.CONNECTED) {
- // At least one context is connected, return true
- return true;
- }
- }
- // There are not any contexts connected, return false
- return false;
- }
-
- @Override
- public boolean isDisconnected() {
- for (ApnContext apnContext : mApnContexts.values()) {
- if (!apnContext.isDisconnected()) {
- // At least one context was not disconnected return false
- return false;
- }
- }
- // All contexts were disconnected so return true
- return true;
- }
-
- @Override
- protected void notifyDataConnection(String reason) {
- if (DBG) log("notifyDataConnection: reason=" + reason);
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.isReady()) {
- if (DBG) log("notifyDataConnection: type:"+apnContext.getApnType());
- mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
- apnContext.getApnType());
- }
- }
- notifyOffApnsOfAvailability(reason);
- }
-
- /**
- * Based on the sim operator numeric, create a list for all possible
- * Data Connections and setup the preferredApn.
- */
- private void createAllApnList() {
- mAllApns = new ArrayList<ApnSetting>();
- String operator = mPhone.mIccRecords.getOperatorNumeric();
- if (operator != null) {
- String selection = "numeric = '" + operator + "'";
- // query only enabled apn.
- // carrier_enabled : 1 means enabled apn, 0 disabled apn.
- selection += " and carrier_enabled = 1";
- if (DBG) log("createAllApnList: selection=" + selection);
-
- Cursor cursor = mPhone.getContext().getContentResolver().query(
- Telephony.Carriers.CONTENT_URI, null, selection, null, null);
-
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- mAllApns = createApnList(cursor);
- }
- cursor.close();
- }
- }
-
- if (mAllApns.isEmpty()) {
- if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
- mPreferredApn = null;
- // TODO: What is the right behaviour?
- //notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
- } else {
- mPreferredApn = getPreferredApn();
- if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
- mPreferredApn = null;
- setPreferredApn(-1);
- }
- if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
- }
- if (DBG) log("createAllApnList: X mAllApns=" + mAllApns);
- }
-
- /** Return the id for a new data connection */
- private GsmDataConnection createDataConnection() {
- if (DBG) log("createDataConnection E");
-
- RetryManager rm = new RetryManager();
- int id = mUniqueIdGenerator.getAndIncrement();
- GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm, this);
- mDataConnections.put(id, conn);
- DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG);
- int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
- if (status == AsyncChannel.STATUS_SUCCESSFUL) {
- mDataConnectionAsyncChannels.put(dcac.dataConnection.getDataConnectionId(), dcac);
- } else {
- loge("createDataConnection: Could not connect to dcac.mDc=" + dcac.dataConnection +
- " status=" + status);
- }
-
- // install reconnect intent filter for this data connection.
- IntentFilter filter = new IntentFilter();
- filter.addAction(INTENT_RECONNECT_ALARM + '.' + id);
- mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
-
- if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
- return conn;
- }
-
- private void configureRetry(DataConnection dc, boolean forDefault, int retryCount) {
- if (DBG) {
- log("configureRetry: forDefault=" + forDefault + " retryCount=" + retryCount +
- " dc=" + dc);
- }
- if (dc == null) return;
-
- if (!dc.configureRetry(getReryConfig(forDefault))) {
- if (forDefault) {
- if (!dc.configureRetry(DEFAULT_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple linear sequence.
- loge("configureRetry: Could not configure using " +
- "DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG);
- dc.configureRetry(20, 2000, 1000);
- }
- } else {
- if (!dc.configureRetry(SECONDARY_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple sequence.
- loge("configureRetry: Could note configure using " +
- "SECONDARY_DATA_RETRY_CONFIG=" + SECONDARY_DATA_RETRY_CONFIG);
- dc.configureRetry("max_retries=3, 333, 333, 333");
- }
- }
- }
- dc.setRetryCount(retryCount);
- }
-
- private void destroyDataConnections() {
- if(mDataConnections != null) {
- if (DBG) log("destroyDataConnections: clear mDataConnectionList");
- mDataConnections.clear();
- } else {
- if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
- }
- }
-
- /**
- * Build a list of APNs to be used to create PDP's.
- *
- * @param requestedApnType
- * @return waitingApns list to be used to create PDP
- * error when waitingApns.isEmpty()
- */
- private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType) {
- ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
-
- if (requestedApnType.equals(Phone.APN_TYPE_DUN)) {
- ApnSetting dun = fetchDunApn();
- if (dun != null) {
- apnList.add(dun);
- if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
- return apnList;
- }
- }
-
- String operator = mPhone.mIccRecords.getOperatorNumeric();
- int radioTech = mPhone.getServiceState().getRilRadioTechnology();
-
- if (canSetPreferApn && mPreferredApn != null &&
- mPreferredApn.canHandleType(requestedApnType)) {
- if (DBG) {
- log("buildWaitingApns: Preferred APN:" + operator + ":"
- + mPreferredApn.numeric + ":" + mPreferredApn);
- }
- if (mPreferredApn.numeric.equals(operator)) {
- if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
- apnList.add(mPreferredApn);
- if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
- return apnList;
- } else {
- if (DBG) log("buildWaitingApns: no preferred APN");
- setPreferredApn(-1);
- mPreferredApn = null;
- }
- } else {
- if (DBG) log("buildWaitingApns: no preferred APN");
- setPreferredApn(-1);
- mPreferredApn = null;
- }
- }
- if (mAllApns != null) {
- for (ApnSetting apn : mAllApns) {
- if (apn.canHandleType(requestedApnType)) {
- if (apn.bearer == 0 || apn.bearer == radioTech) {
- if (DBG) log("apn info : " +apn.toString());
- apnList.add(apn);
- }
- }
- }
- } else {
- loge("mAllApns is empty!");
- }
- if (DBG) log("buildWaitingApns: X apnList=" + apnList);
- return apnList;
- }
-
- private String apnListToString (ArrayList<ApnSetting> apns) {
- StringBuilder result = new StringBuilder();
- for (int i = 0, size = apns.size(); i < size; i++) {
- result.append('[')
- .append(apns.get(i).toString())
- .append(']');
- }
- return result.toString();
- }
-
- private void startDelayedRetry(GsmDataConnection.FailCause cause,
- ApnContext apnContext, int retryOverride) {
- notifyNoData(cause, apnContext);
- reconnectAfterFail(cause, apnContext, retryOverride);
- }
-
- private void setPreferredApn(int pos) {
- if (!canSetPreferApn) {
- log("setPreferredApn: X !canSEtPreferApn");
- return;
- }
-
- log("setPreferredApn: delete");
- ContentResolver resolver = mPhone.getContext().getContentResolver();
- resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null);
-
- if (pos >= 0) {
- log("setPreferredApn: insert");
- ContentValues values = new ContentValues();
- values.put(APN_ID, pos);
- resolver.insert(PREFERAPN_NO_UPDATE_URI, values);
- }
- }
-
- private ApnSetting getPreferredApn() {
- if (mAllApns.isEmpty()) {
- log("getPreferredApn: X not found mAllApns.isEmpty");
- return null;
- }
-
- Cursor cursor = mPhone.getContext().getContentResolver().query(
- PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" },
- null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
-
- if (cursor != null) {
- canSetPreferApn = true;
- } else {
- canSetPreferApn = false;
- }
-
- if (canSetPreferApn && cursor.getCount() > 0) {
- int pos;
- cursor.moveToFirst();
- pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
- for(ApnSetting p:mAllApns) {
- if (p.id == pos && p.canHandleType(mRequestedApnType)) {
- log("getPreferredApn: X found apnSetting" + p);
- cursor.close();
- return p;
- }
- }
- }
-
- if (cursor != null) {
- cursor.close();
- }
-
- log("getPreferredApn: X not found");
- return null;
- }
-
- @Override
- public void handleMessage (Message msg) {
- if (DBG) log("handleMessage msg=" + msg);
-
- if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
- loge("handleMessage: Ignore GSM msgs since GSM phone is inactive");
- return;
- }
-
- switch (msg.what) {
- case EVENT_RECORDS_LOADED:
- onRecordsLoaded();
- break;
-
- case EVENT_DATA_CONNECTION_DETACHED:
- onDataConnectionDetached();
- break;
-
- case EVENT_DATA_CONNECTION_ATTACHED:
- onDataConnectionAttached();
- break;
-
- case EVENT_DATA_STATE_CHANGED:
- onDataStateChanged((AsyncResult) msg.obj);
- break;
-
- case EVENT_POLL_PDP:
- onPollPdp();
- break;
-
- case EVENT_DO_RECOVERY:
- doRecovery();
- break;
-
- case EVENT_APN_CHANGED:
- onApnChanged();
- break;
-
- case EVENT_PS_RESTRICT_ENABLED:
- /**
- * We don't need to explicitly to tear down the PDP context
- * when PS restricted is enabled. The base band will deactive
- * PDP context and notify us with PDP_CONTEXT_CHANGED.
- * But we should stop the network polling and prevent reset PDP.
- */
- if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
- stopNetStatPoll();
- stopDataStallAlarm();
- mIsPsRestricted = true;
- break;
-
- case EVENT_PS_RESTRICT_DISABLED:
- /**
- * When PS restrict is removed, we need setup PDP connection if
- * PDP connection is down.
- */
- if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
- mIsPsRestricted = false;
- if (isConnected()) {
- startNetStatPoll();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- } else {
- // TODO: Should all PDN states be checked to fail?
- if (mState == State.FAILED) {
- cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
- resetAllRetryCounts();
- mReregisterOnReconnectFailure = false;
- }
- trySetupData(Phone.REASON_PS_RESTRICT_ENABLED, Phone.APN_TYPE_DEFAULT);
- }
- break;
- case EVENT_TRY_SETUP_DATA:
- if (msg.obj instanceof ApnContext) {
- onTrySetupData((ApnContext)msg.obj);
- } else if (msg.obj instanceof String) {
- onTrySetupData((String)msg.obj);
- } else {
- loge("EVENT_TRY_SETUP request w/o apnContext or String");
- }
- break;
-
- case EVENT_CLEAN_UP_CONNECTION:
- boolean tearDown = (msg.arg1 == 0) ? false : true;
- if (DBG) log("EVENT_CLEAN_UP_CONNECTION tearDown=" + tearDown);
- if (msg.obj instanceof ApnContext) {
- cleanUpConnection(tearDown, (ApnContext)msg.obj);
- } else {
- loge("EVENT_CLEAN_UP_CONNECTION request w/o apn context");
- }
- break;
- default:
- // handle the message in the super class DataConnectionTracker
- super.handleMessage(msg);
- break;
- }
- }
-
- protected int getApnProfileID(String apnType) {
- if (TextUtils.equals(apnType, Phone.APN_TYPE_IMS)) {
- return RILConstants.DATA_PROFILE_IMS;
- } else if (TextUtils.equals(apnType, Phone.APN_TYPE_FOTA)) {
- return RILConstants.DATA_PROFILE_FOTA;
- } else if (TextUtils.equals(apnType, Phone.APN_TYPE_CBS)) {
- return RILConstants.DATA_PROFILE_CBS;
- } else {
- return RILConstants.DATA_PROFILE_DEFAULT;
- }
- }
-
- private int getCellLocationId() {
- int cid = -1;
- CellLocation loc = mPhone.getCellLocation();
-
- if (loc != null) {
- if (loc instanceof GsmCellLocation) {
- cid = ((GsmCellLocation)loc).getCid();
- } else if (loc instanceof CdmaCellLocation) {
- cid = ((CdmaCellLocation)loc).getBaseStationId();
- }
- }
- return cid;
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[GsmDCT] "+ s);
- }
-
- @Override
- protected void loge(String s) {
- Log.e(LOG_TAG, "[GsmDCT] " + s);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("GsmDataConnectionTracker extends:");
- super.dump(fd, pw, args);
- pw.println(" RADIO_TESTS=" + RADIO_TESTS);
- pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
- pw.println(" mResolver=" + mResolver);
- pw.println(" canSetPreferApn=" + canSetPreferApn);
- pw.println(" mApnObserver=" + mApnObserver);
- pw.println(" getOverallState=" + getOverallState());
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
deleted file mode 100644
index 9b3d5cd..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * 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.gsm;
-
-import android.content.Context;
-import com.android.internal.telephony.*;
-
-import android.os.*;
-import android.telephony.PhoneNumberUtils;
-import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.util.Log;
-
-import static com.android.internal.telephony.CommandsInterface.*;
-
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
-/**
- * The motto for this file is:
- *
- * "NOTE: By using the # as a separator, most cases are expected to be unambiguous."
- * -- TS 22.030 6.5.2
- *
- * {@hide}
- *
- */
-public final class GsmMmiCode extends Handler implements MmiCode {
- static final String LOG_TAG = "GSM";
-
- //***** Constants
-
- // Max Size of the Short Code (aka Short String from TS 22.030 6.5.2)
- static final int MAX_LENGTH_SHORT_CODE = 2;
-
- // TS 22.030 6.5.2 Every Short String USSD command will end with #-key
- // (known as #-String)
- static final char END_OF_USSD_COMMAND = '#';
-
- // From TS 22.030 6.5.2
- static final String ACTION_ACTIVATE = "*";
- static final String ACTION_DEACTIVATE = "#";
- static final String ACTION_INTERROGATE = "*#";
- static final String ACTION_REGISTER = "**";
- static final String ACTION_ERASURE = "##";
-
- // Supp Service codes from TS 22.030 Annex B
-
- //Called line presentation
- static final String SC_CLIP = "30";
- static final String SC_CLIR = "31";
-
- // Call Forwarding
- static final String SC_CFU = "21";
- static final String SC_CFB = "67";
- static final String SC_CFNRy = "61";
- static final String SC_CFNR = "62";
-
- static final String SC_CF_All = "002";
- static final String SC_CF_All_Conditional = "004";
-
- // Call Waiting
- static final String SC_WAIT = "43";
-
- // Call Barring
- static final String SC_BAOC = "33";
- static final String SC_BAOIC = "331";
- static final String SC_BAOICxH = "332";
- static final String SC_BAIC = "35";
- static final String SC_BAICr = "351";
-
- static final String SC_BA_ALL = "330";
- static final String SC_BA_MO = "333";
- static final String SC_BA_MT = "353";
-
- // Supp Service Password registration
- static final String SC_PWD = "03";
-
- // PIN/PIN2/PUK/PUK2
- static final String SC_PIN = "04";
- static final String SC_PIN2 = "042";
- static final String SC_PUK = "05";
- static final String SC_PUK2 = "052";
-
- //***** Event Constants
-
- static final int EVENT_SET_COMPLETE = 1;
- static final int EVENT_GET_CLIR_COMPLETE = 2;
- static final int EVENT_QUERY_CF_COMPLETE = 3;
- static final int EVENT_USSD_COMPLETE = 4;
- static final int EVENT_QUERY_COMPLETE = 5;
- static final int EVENT_SET_CFF_COMPLETE = 6;
- static final int EVENT_USSD_CANCEL_COMPLETE = 7;
-
- //***** Instance Variables
-
- GSMPhone phone;
- Context context;
-
- String action; // One of ACTION_*
- String sc; // Service Code
- String sia, sib, sic; // Service Info a,b,c
- String poundString; // Entire MMI string up to and including #
- String dialingNumber;
- String pwd; // For password registration
-
- /** Set to true in processCode, not at newFromDialString time */
- private boolean isPendingUSSD;
-
- private boolean isUssdRequest;
-
- State state = State.PENDING;
- CharSequence message;
-
- //***** Class Variables
-
-
- // See TS 22.030 6.5.2 "Structure of the MMI"
-
- static Pattern sPatternSuppService = Pattern.compile(
- "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)([^#]*)");
-/* 1 2 3 4 5 6 7 8 9 10 11 12
-
- 1 = Full string up to and including #
- 2 = action (activation/interrogation/registration/erasure)
- 3 = service code
- 5 = SIA
- 7 = SIB
- 9 = SIC
- 10 = dialing number which must not include #, e.g. *SCn*SI#DN format
-*/
-
- static final int MATCH_GROUP_POUND_STRING = 1;
-
- static final int MATCH_GROUP_ACTION = 2;
- //(activation/interrogation/registration/erasure)
-
- static final int MATCH_GROUP_SERVICE_CODE = 3;
- static final int MATCH_GROUP_SIA = 5;
- static final int MATCH_GROUP_SIB = 7;
- static final int MATCH_GROUP_SIC = 9;
- static final int MATCH_GROUP_PWD_CONFIRM = 11;
- static final int MATCH_GROUP_DIALING_NUMBER = 12;
- static private String[] sTwoDigitNumberPattern;
-
- //***** Public Class methods
-
- /**
- * Some dial strings in GSM are defined to do non-call setup
- * things, such as modify or query supplementary service settings (eg, call
- * forwarding). These are generally referred to as "MMI codes".
- * We look to see if the dial string contains a valid MMI code (potentially
- * with a dial string at the end as well) and return info here.
- *
- * If the dial string contains no MMI code, we return an instance with
- * only "dialingNumber" set
- *
- * Please see flow chart in TS 22.030 6.5.3.2
- */
-
- static GsmMmiCode
- newFromDialString(String dialString, GSMPhone phone) {
- Matcher m;
- GsmMmiCode ret = null;
-
- m = sPatternSuppService.matcher(dialString);
-
- // Is this formatted like a standard supplementary service code?
- if (m.matches()) {
- ret = new GsmMmiCode(phone);
- ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
- ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
- ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
- ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
- ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
- ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
- ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
- ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));
-
- } else if (dialString.endsWith("#")) {
- // TS 22.030 sec 6.5.3.2
- // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet
- // (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND".
-
- ret = new GsmMmiCode(phone);
- ret.poundString = dialString;
- } else if (isTwoDigitShortCode(phone.getContext(), dialString)) {
- //Is a country-specific exception to short codes as defined in TS 22.030, 6.5.3.2
- ret = null;
- } else if (isShortCode(dialString, phone)) {
- // this may be a short code, as defined in TS 22.030, 6.5.3.2
- ret = new GsmMmiCode(phone);
- ret.dialingNumber = dialString;
- }
-
- return ret;
- }
-
- static GsmMmiCode
- newNetworkInitiatedUssd (String ussdMessage,
- boolean isUssdRequest, GSMPhone phone) {
- GsmMmiCode ret;
-
- ret = new GsmMmiCode(phone);
-
- ret.message = ussdMessage;
- ret.isUssdRequest = isUssdRequest;
-
- // If it's a request, set to PENDING so that it's cancelable.
- if (isUssdRequest) {
- ret.isPendingUSSD = true;
- ret.state = State.PENDING;
- } else {
- ret.state = State.COMPLETE;
- }
-
- return ret;
- }
-
- static GsmMmiCode newFromUssdUserInput(String ussdMessge, GSMPhone phone) {
- GsmMmiCode ret = new GsmMmiCode(phone);
-
- ret.message = ussdMessge;
- ret.state = State.PENDING;
- ret.isPendingUSSD = true;
-
- return ret;
- }
-
- //***** Private Class methods
-
- /** make empty strings be null.
- * Regexp returns empty strings for empty groups
- */
- private static String
- makeEmptyNull (String s) {
- if (s != null && s.length() == 0) return null;
-
- return s;
- }
-
- /** returns true of the string is empty or null */
- private static boolean
- isEmptyOrNull(CharSequence s) {
- return s == null || (s.length() == 0);
- }
-
-
- private static int
- scToCallForwardReason(String sc) {
- if (sc == null) {
- throw new RuntimeException ("invalid call forward sc");
- }
-
- if (sc.equals(SC_CF_All)) {
- return CommandsInterface.CF_REASON_ALL;
- } else if (sc.equals(SC_CFU)) {
- return CommandsInterface.CF_REASON_UNCONDITIONAL;
- } else if (sc.equals(SC_CFB)) {
- return CommandsInterface.CF_REASON_BUSY;
- } else if (sc.equals(SC_CFNR)) {
- return CommandsInterface.CF_REASON_NOT_REACHABLE;
- } else if (sc.equals(SC_CFNRy)) {
- return CommandsInterface.CF_REASON_NO_REPLY;
- } else if (sc.equals(SC_CF_All_Conditional)) {
- return CommandsInterface.CF_REASON_ALL_CONDITIONAL;
- } else {
- throw new RuntimeException ("invalid call forward sc");
- }
- }
-
- private static int
- siToServiceClass(String si) {
- if (si == null || si.length() == 0) {
- return SERVICE_CLASS_NONE;
- } else {
- // NumberFormatException should cause MMI fail
- int serviceCode = Integer.parseInt(si, 10);
-
- switch (serviceCode) {
- case 10: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE;
- case 11: return SERVICE_CLASS_VOICE;
- case 12: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX;
- case 13: return SERVICE_CLASS_FAX;
-
- case 16: return SERVICE_CLASS_SMS;
-
- case 19: return SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE;
-/*
- Note for code 20:
- From TS 22.030 Annex C:
- "All GPRS bearer services" are not included in "All tele and bearer services"
- and "All bearer services"."
-....so SERVICE_CLASS_DATA, which (according to 27.007) includes GPRS
-*/
- case 20: return SERVICE_CLASS_DATA_ASYNC + SERVICE_CLASS_DATA_SYNC;
-
- case 21: return SERVICE_CLASS_PAD + SERVICE_CLASS_DATA_ASYNC;
- case 22: return SERVICE_CLASS_PACKET + SERVICE_CLASS_DATA_SYNC;
- case 24: return SERVICE_CLASS_DATA_SYNC;
- case 25: return SERVICE_CLASS_DATA_ASYNC;
- case 26: return SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE;
- case 99: return SERVICE_CLASS_PACKET;
-
- default:
- throw new RuntimeException("unsupported MMI service code " + si);
- }
- }
- }
-
- private static int
- siToTime (String si) {
- if (si == null || si.length() == 0) {
- return 0;
- } else {
- // NumberFormatException should cause MMI fail
- return Integer.parseInt(si, 10);
- }
- }
-
- static boolean
- isServiceCodeCallForwarding(String sc) {
- return sc != null &&
- (sc.equals(SC_CFU)
- || sc.equals(SC_CFB) || sc.equals(SC_CFNRy)
- || sc.equals(SC_CFNR) || sc.equals(SC_CF_All)
- || sc.equals(SC_CF_All_Conditional));
- }
-
- static boolean
- isServiceCodeCallBarring(String sc) {
- return sc != null &&
- (sc.equals(SC_BAOC)
- || sc.equals(SC_BAOIC)
- || sc.equals(SC_BAOICxH)
- || sc.equals(SC_BAIC)
- || sc.equals(SC_BAICr)
- || sc.equals(SC_BA_ALL)
- || sc.equals(SC_BA_MO)
- || sc.equals(SC_BA_MT));
- }
-
- static String
- scToBarringFacility(String sc) {
- if (sc == null) {
- throw new RuntimeException ("invalid call barring sc");
- }
-
- if (sc.equals(SC_BAOC)) {
- return CommandsInterface.CB_FACILITY_BAOC;
- } else if (sc.equals(SC_BAOIC)) {
- return CommandsInterface.CB_FACILITY_BAOIC;
- } else if (sc.equals(SC_BAOICxH)) {
- return CommandsInterface.CB_FACILITY_BAOICxH;
- } else if (sc.equals(SC_BAIC)) {
- return CommandsInterface.CB_FACILITY_BAIC;
- } else if (sc.equals(SC_BAICr)) {
- return CommandsInterface.CB_FACILITY_BAICr;
- } else if (sc.equals(SC_BA_ALL)) {
- return CommandsInterface.CB_FACILITY_BA_ALL;
- } else if (sc.equals(SC_BA_MO)) {
- return CommandsInterface.CB_FACILITY_BA_MO;
- } else if (sc.equals(SC_BA_MT)) {
- return CommandsInterface.CB_FACILITY_BA_MT;
- } else {
- throw new RuntimeException ("invalid call barring sc");
- }
- }
-
- //***** Constructor
-
- GsmMmiCode (GSMPhone phone) {
- // The telephony unit-test cases may create GsmMmiCode's
- // in secondary threads
- super(phone.getHandler().getLooper());
- this.phone = phone;
- this.context = phone.getContext();
- }
-
- //***** MmiCode implementation
-
- public State
- getState() {
- return state;
- }
-
- public CharSequence
- getMessage() {
- return message;
- }
-
- // inherited javadoc suffices
- public void
- cancel() {
- // Complete or failed cannot be cancelled
- if (state == State.COMPLETE || state == State.FAILED) {
- return;
- }
-
- state = State.CANCELLED;
-
- if (isPendingUSSD) {
- /*
- * There can only be one pending USSD session, so tell the radio to
- * cancel it.
- */
- phone.mCM.cancelPendingUssd(obtainMessage(EVENT_USSD_CANCEL_COMPLETE, this));
-
- /*
- * Don't call phone.onMMIDone here; wait for CANCEL_COMPLETE notice
- * from RIL.
- */
- } else {
- // TODO in cases other than USSD, it would be nice to cancel
- // the pending radio operation. This requires RIL cancellation
- // support, which does not presently exist.
-
- phone.onMMIDone (this);
- }
-
- }
-
- public boolean isCancelable() {
- /* Can only cancel pending USSD sessions. */
- return isPendingUSSD;
- }
-
- //***** Instance Methods
-
- /** Does this dial string contain a structured or unstructured MMI code? */
- boolean
- isMMI() {
- return poundString != null;
- }
-
- /* Is this a 1 or 2 digit "short code" as defined in TS 22.030 sec 6.5.3.2? */
- boolean
- isShortCode() {
- return poundString == null
- && dialingNumber != null && dialingNumber.length() <= 2;
-
- }
-
- static private boolean
- isTwoDigitShortCode(Context context, String dialString) {
- Log.d(LOG_TAG, "isTwoDigitShortCode");
-
- if (dialString == null || dialString.length() != 2) return false;
-
- if (sTwoDigitNumberPattern == null) {
- sTwoDigitNumberPattern = context.getResources().getStringArray(
- com.android.internal.R.array.config_twoDigitNumberPattern);
- }
-
- for (String dialnumber : sTwoDigitNumberPattern) {
- Log.d(LOG_TAG, "Two Digit Number Pattern " + dialnumber);
- if (dialString.equals(dialnumber)) {
- Log.d(LOG_TAG, "Two Digit Number Pattern -true");
- return true;
- }
- }
- Log.d(LOG_TAG, "Two Digit Number Pattern -false");
- return false;
- }
-
- /**
- * Helper function for newFromDialString. Returns true if dialString appears
- * to be a short code AND conditions are correct for it to be treated as
- * such.
- */
- static private boolean isShortCode(String dialString, GSMPhone phone) {
- // Refer to TS 22.030 Figure 3.5.3.2:
- if (dialString == null) {
- return false;
- }
-
- // Illegal dial string characters will give a ZERO length.
- // At this point we do not want to crash as any application with
- // call privileges may send a non dial string.
- // It return false as when the dialString is equal to NULL.
- if (dialString.length() == 0) {
- return false;
- }
-
- if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
- return false;
- } else {
- return isShortCodeUSSD(dialString, phone);
- }
- }
-
- /**
- * Helper function for isShortCode. Returns true if dialString appears to be
- * a short code and it is a USSD structure
- *
- * According to the 3PGG TS 22.030 specification Figure 3.5.3.2: A 1 or 2
- * digit "short code" is treated as USSD if it is entered while on a call or
- * does not satisfy the condition (exactly 2 digits && starts with '1'), there
- * are however exceptions to this rule (see below)
- *
- * Exception (1) to Call initiation is: If the user of the device is already in a call
- * and enters a Short String without any #-key at the end and the length of the Short String is
- * equal or less then the MAX_LENGTH_SHORT_CODE [constant that is equal to 2]
- *
- * The phone shall initiate a USSD/SS commands.
- *
- * Exception (2) to Call initiation is: If the user of the device enters one
- * Digit followed by the #-key. This rule defines this String as the
- * #-String which is a USSD/SS command.
- *
- * The phone shall initiate a USSD/SS command.
- */
- static private boolean isShortCodeUSSD(String dialString, GSMPhone phone) {
- if (dialString != null) {
- if (phone.isInCall()) {
- // The maximum length of a Short Code (aka Short String) is 2
- if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
- return true;
- }
- }
-
- // The maximum length of a Short Code (aka Short String) is 2
- if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
- if (dialString.charAt(dialString.length() - 1) == END_OF_USSD_COMMAND) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
- */
- boolean isPinCommand() {
- return sc != null && (sc.equals(SC_PIN) || sc.equals(SC_PIN2)
- || sc.equals(SC_PUK) || sc.equals(SC_PUK2));
- }
-
- /**
- * See TS 22.030 Annex B.
- * In temporary mode, to suppress CLIR for a single call, enter:
- * " * 31 # [called number] SEND "
- * In temporary mode, to invoke CLIR for a single call enter:
- * " # 31 # [called number] SEND "
- */
- boolean
- isTemporaryModeCLIR() {
- return sc != null && sc.equals(SC_CLIR) && dialingNumber != null
- && (isActivate() || isDeactivate());
- }
-
- /**
- * returns CommandsInterface.CLIR_*
- * See also isTemporaryModeCLIR()
- */
- int
- getCLIRMode() {
- if (sc != null && sc.equals(SC_CLIR)) {
- if (isActivate()) {
- return CommandsInterface.CLIR_SUPPRESSION;
- } else if (isDeactivate()) {
- return CommandsInterface.CLIR_INVOCATION;
- }
- }
-
- return CommandsInterface.CLIR_DEFAULT;
- }
-
- boolean isActivate() {
- return action != null && action.equals(ACTION_ACTIVATE);
- }
-
- boolean isDeactivate() {
- return action != null && action.equals(ACTION_DEACTIVATE);
- }
-
- boolean isInterrogate() {
- return action != null && action.equals(ACTION_INTERROGATE);
- }
-
- boolean isRegister() {
- return action != null && action.equals(ACTION_REGISTER);
- }
-
- boolean isErasure() {
- return action != null && action.equals(ACTION_ERASURE);
- }
-
- /**
- * Returns true if this is a USSD code that's been submitted to the
- * network...eg, after processCode() is called
- */
- public boolean isPendingUSSD() {
- return isPendingUSSD;
- }
-
- public boolean isUssdRequest() {
- return isUssdRequest;
- }
-
- /** Process a MMI code or short code...anything that isn't a dialing number */
- void
- processCode () {
- try {
- if (isShortCode()) {
- Log.d(LOG_TAG, "isShortCode");
- // These just get treated as USSD.
- sendUssd(dialingNumber);
- } else if (dialingNumber != null) {
- // We should have no dialing numbers here
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- } else if (sc != null && sc.equals(SC_CLIP)) {
- Log.d(LOG_TAG, "is CLIP");
- if (isInterrogate()) {
- phone.mCM.queryCLIP(
- obtainMessage(EVENT_QUERY_COMPLETE, this));
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
- } else if (sc != null && sc.equals(SC_CLIR)) {
- Log.d(LOG_TAG, "is CLIR");
- if (isActivate()) {
- phone.mCM.setCLIR(CommandsInterface.CLIR_INVOCATION,
- obtainMessage(EVENT_SET_COMPLETE, this));
- } else if (isDeactivate()) {
- phone.mCM.setCLIR(CommandsInterface.CLIR_SUPPRESSION,
- obtainMessage(EVENT_SET_COMPLETE, this));
- } else if (isInterrogate()) {
- phone.mCM.getCLIR(
- obtainMessage(EVENT_GET_CLIR_COMPLETE, this));
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
- } else if (isServiceCodeCallForwarding(sc)) {
- Log.d(LOG_TAG, "is CF");
-
- String dialingNumber = sia;
- int serviceClass = siToServiceClass(sib);
- int reason = scToCallForwardReason(sc);
- int time = siToTime(sic);
-
- if (isInterrogate()) {
- phone.mCM.queryCallForwardStatus(
- reason, serviceClass, dialingNumber,
- obtainMessage(EVENT_QUERY_CF_COMPLETE, this));
- } else {
- int cfAction;
-
- if (isActivate()) {
- cfAction = CommandsInterface.CF_ACTION_ENABLE;
- } else if (isDeactivate()) {
- cfAction = CommandsInterface.CF_ACTION_DISABLE;
- } else if (isRegister()) {
- cfAction = CommandsInterface.CF_ACTION_REGISTRATION;
- } else if (isErasure()) {
- cfAction = CommandsInterface.CF_ACTION_ERASURE;
- } else {
- throw new RuntimeException ("invalid action");
- }
-
- int isSettingUnconditionalVoice =
- (((reason == CommandsInterface.CF_REASON_UNCONDITIONAL) ||
- (reason == CommandsInterface.CF_REASON_ALL)) &&
- (((serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0) ||
- (serviceClass == CommandsInterface.SERVICE_CLASS_NONE))) ? 1 : 0;
-
- int isEnableDesired =
- ((cfAction == CommandsInterface.CF_ACTION_ENABLE) ||
- (cfAction == CommandsInterface.CF_ACTION_REGISTRATION)) ? 1 : 0;
-
- Log.d(LOG_TAG, "is CF setCallForward");
- phone.mCM.setCallForward(cfAction, reason, serviceClass,
- dialingNumber, time, obtainMessage(
- EVENT_SET_CFF_COMPLETE,
- isSettingUnconditionalVoice,
- isEnableDesired, this));
- }
- } else if (isServiceCodeCallBarring(sc)) {
- // sia = password
- // sib = basic service group
-
- String password = sia;
- int serviceClass = siToServiceClass(sib);
- String facility = scToBarringFacility(sc);
-
- if (isInterrogate()) {
- phone.mCM.queryFacilityLock(facility, password,
- serviceClass, obtainMessage(EVENT_QUERY_COMPLETE, this));
- } else if (isActivate() || isDeactivate()) {
- phone.mCM.setFacilityLock(facility, isActivate(), password,
- serviceClass, obtainMessage(EVENT_SET_COMPLETE, this));
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
-
- } else if (sc != null && sc.equals(SC_PWD)) {
- // sia = fac
- // sib = old pwd
- // sic = new pwd
- // pwd = new pwd
- String facility;
- String oldPwd = sib;
- String newPwd = sic;
- if (isActivate() || isRegister()) {
- // Even though ACTIVATE is acceptable, this is really termed a REGISTER
- action = ACTION_REGISTER;
-
- if (sia == null) {
- // If sc was not specified, treat it as BA_ALL.
- facility = CommandsInterface.CB_FACILITY_BA_ALL;
- } else {
- facility = scToBarringFacility(sia);
- }
- if (newPwd.equals(pwd)) {
- phone.mCM.changeBarringPassword(facility, oldPwd,
- newPwd, obtainMessage(EVENT_SET_COMPLETE, this));
- } else {
- // password mismatch; return error
- handlePasswordError(com.android.internal.R.string.passwordIncorrect);
- }
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
-
- } else if (sc != null && sc.equals(SC_WAIT)) {
- // sia = basic service group
- int serviceClass = siToServiceClass(sia);
-
- if (isActivate() || isDeactivate()) {
- phone.mCM.setCallWaiting(isActivate(), serviceClass,
- obtainMessage(EVENT_SET_COMPLETE, this));
- } else if (isInterrogate()) {
- phone.mCM.queryCallWaiting(serviceClass,
- obtainMessage(EVENT_QUERY_COMPLETE, this));
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
- } else if (isPinCommand()) {
- // sia = old PIN or PUK
- // sib = new PIN
- // sic = new PIN
- String oldPinOrPuk = sia;
- String newPin = sib;
- int pinLen = newPin.length();
- if (isRegister()) {
- if (!newPin.equals(sic)) {
- // password mismatch; return error
- handlePasswordError(com.android.internal.R.string.mismatchPin);
- } else if (pinLen < 4 || pinLen > 8 ) {
- // invalid length
- handlePasswordError(com.android.internal.R.string.invalidPin);
- } else if (sc.equals(SC_PIN) &&
- phone.getIccCard().getState() == IccCard.State.PUK_REQUIRED ) {
- // Sim is puk-locked
- handlePasswordError(com.android.internal.R.string.needPuk);
- } else {
- // pre-checks OK
- if (sc.equals(SC_PIN)) {
- phone.mCM.changeIccPin(oldPinOrPuk, newPin,
- obtainMessage(EVENT_SET_COMPLETE, this));
- } else if (sc.equals(SC_PIN2)) {
- phone.mCM.changeIccPin2(oldPinOrPuk, newPin,
- obtainMessage(EVENT_SET_COMPLETE, this));
- } else if (sc.equals(SC_PUK)) {
- phone.mCM.supplyIccPuk(oldPinOrPuk, newPin,
- obtainMessage(EVENT_SET_COMPLETE, this));
- } else if (sc.equals(SC_PUK2)) {
- phone.mCM.supplyIccPuk2(oldPinOrPuk, newPin,
- obtainMessage(EVENT_SET_COMPLETE, this));
- }
- }
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
- } else if (poundString != null) {
- sendUssd(poundString);
- } else {
- throw new RuntimeException ("Invalid or Unsupported MMI Code");
- }
- } catch (RuntimeException exc) {
- state = State.FAILED;
- message = context.getText(com.android.internal.R.string.mmiError);
- phone.onMMIDone(this);
- }
- }
-
- private void handlePasswordError(int res) {
- state = State.FAILED;
- StringBuilder sb = new StringBuilder(getScString());
- sb.append("\n");
- sb.append(context.getText(res));
- message = sb;
- phone.onMMIDone(this);
- }
-
- /**
- * Called from GSMPhone
- *
- * An unsolicited USSD NOTIFY or REQUEST has come in matching
- * up with this pending USSD request
- *
- * Note: If REQUEST, this exchange is complete, but the session remains
- * active (ie, the network expects user input).
- */
- void
- onUssdFinished(String ussdMessage, boolean isUssdRequest) {
- if (state == State.PENDING) {
- if (ussdMessage == null) {
- message = context.getText(com.android.internal.R.string.mmiComplete);
- } else {
- message = ussdMessage;
- }
- this.isUssdRequest = isUssdRequest;
- // If it's a request, leave it PENDING so that it's cancelable.
- if (!isUssdRequest) {
- state = State.COMPLETE;
- }
-
- phone.onMMIDone(this);
- }
- }
-
- /**
- * Called from GSMPhone
- *
- * The radio has reset, and this is still pending
- */
-
- void
- onUssdFinishedError() {
- if (state == State.PENDING) {
- state = State.FAILED;
- message = context.getText(com.android.internal.R.string.mmiError);
-
- phone.onMMIDone(this);
- }
- }
-
- void sendUssd(String ussdMessage) {
- // Treat this as a USSD string
- isPendingUSSD = true;
-
- // Note that unlike most everything else, the USSD complete
- // response does not complete this MMI code...we wait for
- // an unsolicited USSD "Notify" or "Request".
- // The matching up of this is done in GSMPhone.
-
- phone.mCM.sendUSSD(ussdMessage,
- obtainMessage(EVENT_USSD_COMPLETE, this));
- }
-
- /** Called from GSMPhone.handleMessage; not a Handler subclass */
- public void
- handleMessage (Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_SET_COMPLETE:
- ar = (AsyncResult) (msg.obj);
-
- onSetComplete(ar);
- break;
-
- case EVENT_SET_CFF_COMPLETE:
- ar = (AsyncResult) (msg.obj);
-
- /*
- * msg.arg1 = 1 means to set unconditional voice call forwarding
- * msg.arg2 = 1 means to enable voice call forwarding
- */
- if ((ar.exception == null) && (msg.arg1 == 1)) {
- boolean cffEnabled = (msg.arg2 == 1);
- phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
- }
-
- onSetComplete(ar);
- break;
-
- case EVENT_GET_CLIR_COMPLETE:
- ar = (AsyncResult) (msg.obj);
- onGetClirComplete(ar);
- break;
-
- case EVENT_QUERY_CF_COMPLETE:
- ar = (AsyncResult) (msg.obj);
- onQueryCfComplete(ar);
- break;
-
- case EVENT_QUERY_COMPLETE:
- ar = (AsyncResult) (msg.obj);
- onQueryComplete(ar);
- break;
-
- case EVENT_USSD_COMPLETE:
- ar = (AsyncResult) (msg.obj);
-
- if (ar.exception != null) {
- state = State.FAILED;
- message = getErrorMessage(ar);
-
- phone.onMMIDone(this);
- }
-
- // Note that unlike most everything else, the USSD complete
- // response does not complete this MMI code...we wait for
- // an unsolicited USSD "Notify" or "Request".
- // The matching up of this is done in GSMPhone.
-
- break;
-
- case EVENT_USSD_CANCEL_COMPLETE:
- phone.onMMIDone(this);
- break;
- }
- }
- //***** Private instance methods
-
- private CharSequence getErrorMessage(AsyncResult ar) {
-
- if (ar.exception instanceof CommandException) {
- CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
- if (err == CommandException.Error.FDN_CHECK_FAILURE) {
- Log.i(LOG_TAG, "FDN_CHECK_FAILURE");
- return context.getText(com.android.internal.R.string.mmiFdnError);
- }
- }
-
- return context.getText(com.android.internal.R.string.mmiError);
- }
-
- private CharSequence getScString() {
- if (sc != null) {
- if (isServiceCodeCallBarring(sc)) {
- return context.getText(com.android.internal.R.string.BaMmi);
- } else if (isServiceCodeCallForwarding(sc)) {
- return context.getText(com.android.internal.R.string.CfMmi);
- } else if (sc.equals(SC_CLIP)) {
- return context.getText(com.android.internal.R.string.ClipMmi);
- } else if (sc.equals(SC_CLIR)) {
- return context.getText(com.android.internal.R.string.ClirMmi);
- } else if (sc.equals(SC_PWD)) {
- return context.getText(com.android.internal.R.string.PwdMmi);
- } else if (sc.equals(SC_WAIT)) {
- return context.getText(com.android.internal.R.string.CwMmi);
- } else if (isPinCommand()) {
- return context.getText(com.android.internal.R.string.PinMmi);
- }
- }
-
- return "";
- }
-
- private void
- onSetComplete(AsyncResult ar){
- StringBuilder sb = new StringBuilder(getScString());
- sb.append("\n");
-
- if (ar.exception != null) {
- state = State.FAILED;
- if (ar.exception instanceof CommandException) {
- CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
- if (err == CommandException.Error.PASSWORD_INCORRECT) {
- if (isPinCommand()) {
- // look specifically for the PUK commands and adjust
- // the message accordingly.
- if (sc.equals(SC_PUK) || sc.equals(SC_PUK2)) {
- sb.append(context.getText(
- com.android.internal.R.string.badPuk));
- } else {
- sb.append(context.getText(
- com.android.internal.R.string.badPin));
- }
- } else {
- sb.append(context.getText(
- com.android.internal.R.string.passwordIncorrect));
- }
- } else if (err == CommandException.Error.SIM_PUK2) {
- sb.append(context.getText(
- com.android.internal.R.string.badPin));
- sb.append("\n");
- sb.append(context.getText(
- com.android.internal.R.string.needPuk2));
- } else if (err == CommandException.Error.FDN_CHECK_FAILURE) {
- Log.i(LOG_TAG, "FDN_CHECK_FAILURE");
- sb.append(context.getText(com.android.internal.R.string.mmiFdnError));
- } else {
- sb.append(context.getText(
- com.android.internal.R.string.mmiError));
- }
- } else {
- sb.append(context.getText(
- com.android.internal.R.string.mmiError));
- }
- } else if (isActivate()) {
- state = State.COMPLETE;
- sb.append(context.getText(
- com.android.internal.R.string.serviceEnabled));
- // Record CLIR setting
- if (sc.equals(SC_CLIR)) {
- phone.saveClirSetting(CommandsInterface.CLIR_INVOCATION);
- }
- } else if (isDeactivate()) {
- state = State.COMPLETE;
- sb.append(context.getText(
- com.android.internal.R.string.serviceDisabled));
- // Record CLIR setting
- if (sc.equals(SC_CLIR)) {
- phone.saveClirSetting(CommandsInterface.CLIR_SUPPRESSION);
- }
- } else if (isRegister()) {
- state = State.COMPLETE;
- sb.append(context.getText(
- com.android.internal.R.string.serviceRegistered));
- } else if (isErasure()) {
- state = State.COMPLETE;
- sb.append(context.getText(
- com.android.internal.R.string.serviceErased));
- } else {
- state = State.FAILED;
- sb.append(context.getText(
- com.android.internal.R.string.mmiError));
- }
-
- message = sb;
- phone.onMMIDone(this);
- }
-
- private void
- onGetClirComplete(AsyncResult ar) {
- StringBuilder sb = new StringBuilder(getScString());
- sb.append("\n");
-
- if (ar.exception != null) {
- state = State.FAILED;
- sb.append(getErrorMessage(ar));
- } else {
- int clirArgs[];
-
- clirArgs = (int[])ar.result;
-
- // the 'm' parameter from TS 27.007 7.7
- switch (clirArgs[1]) {
- case 0: // CLIR not provisioned
- sb.append(context.getText(
- com.android.internal.R.string.serviceNotProvisioned));
- state = State.COMPLETE;
- break;
-
- case 1: // CLIR provisioned in permanent mode
- sb.append(context.getText(
- com.android.internal.R.string.CLIRPermanent));
- state = State.COMPLETE;
- break;
-
- case 2: // unknown (e.g. no network, etc.)
- sb.append(context.getText(
- com.android.internal.R.string.mmiError));
- state = State.FAILED;
- break;
-
- case 3: // CLIR temporary mode presentation restricted
-
- // the 'n' parameter from TS 27.007 7.7
- switch (clirArgs[0]) {
- default:
- case 0: // Default
- sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOnNextCallOn));
- break;
- case 1: // CLIR invocation
- sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOnNextCallOn));
- break;
- case 2: // CLIR suppression
- sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOnNextCallOff));
- break;
- }
- state = State.COMPLETE;
- break;
-
- case 4: // CLIR temporary mode presentation allowed
- // the 'n' parameter from TS 27.007 7.7
- switch (clirArgs[0]) {
- default:
- case 0: // Default
- sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOffNextCallOff));
- break;
- case 1: // CLIR invocation
- sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOffNextCallOn));
- break;
- case 2: // CLIR suppression
- sb.append(context.getText(
- com.android.internal.R.string.CLIRDefaultOffNextCallOff));
- break;
- }
-
- state = State.COMPLETE;
- break;
- }
- }
-
- message = sb;
- phone.onMMIDone(this);
- }
-
- /**
- * @param serviceClass 1 bit of the service class bit vectory
- * @return String to be used for call forward query MMI response text.
- * Returns null if unrecognized
- */
-
- private CharSequence
- serviceClassToCFString (int serviceClass) {
- switch (serviceClass) {
- case SERVICE_CLASS_VOICE:
- return context.getText(com.android.internal.R.string.serviceClassVoice);
- case SERVICE_CLASS_DATA:
- return context.getText(com.android.internal.R.string.serviceClassData);
- case SERVICE_CLASS_FAX:
- return context.getText(com.android.internal.R.string.serviceClassFAX);
- case SERVICE_CLASS_SMS:
- return context.getText(com.android.internal.R.string.serviceClassSMS);
- case SERVICE_CLASS_DATA_SYNC:
- return context.getText(com.android.internal.R.string.serviceClassDataSync);
- case SERVICE_CLASS_DATA_ASYNC:
- return context.getText(com.android.internal.R.string.serviceClassDataAsync);
- case SERVICE_CLASS_PACKET:
- return context.getText(com.android.internal.R.string.serviceClassPacket);
- case SERVICE_CLASS_PAD:
- return context.getText(com.android.internal.R.string.serviceClassPAD);
- default:
- return null;
- }
- }
-
-
- /** one CallForwardInfo + serviceClassMask -> one line of text */
- private CharSequence
- makeCFQueryResultMessage(CallForwardInfo info, int serviceClassMask) {
- CharSequence template;
- String sources[] = {"{0}", "{1}", "{2}"};
- CharSequence destinations[] = new CharSequence[3];
- boolean needTimeTemplate;
-
- // CF_REASON_NO_REPLY also has a time value associated with
- // it. All others don't.
-
- needTimeTemplate =
- (info.reason == CommandsInterface.CF_REASON_NO_REPLY);
-
- if (info.status == 1) {
- if (needTimeTemplate) {
- template = context.getText(
- com.android.internal.R.string.cfTemplateForwardedTime);
- } else {
- template = context.getText(
- com.android.internal.R.string.cfTemplateForwarded);
- }
- } else if (info.status == 0 && isEmptyOrNull(info.number)) {
- template = context.getText(
- com.android.internal.R.string.cfTemplateNotForwarded);
- } else { /* (info.status == 0) && !isEmptyOrNull(info.number) */
- // A call forward record that is not active but contains
- // a phone number is considered "registered"
-
- if (needTimeTemplate) {
- template = context.getText(
- com.android.internal.R.string.cfTemplateRegisteredTime);
- } else {
- template = context.getText(
- com.android.internal.R.string.cfTemplateRegistered);
- }
- }
-
- // In the template (from strings.xmls)
- // {0} is one of "bearerServiceCode*"
- // {1} is dialing number
- // {2} is time in seconds
-
- destinations[0] = serviceClassToCFString(info.serviceClass & serviceClassMask);
- destinations[1] = PhoneNumberUtils.stringFromStringAndTOA(info.number, info.toa);
- destinations[2] = Integer.toString(info.timeSeconds);
-
- if (info.reason == CommandsInterface.CF_REASON_UNCONDITIONAL &&
- (info.serviceClass & serviceClassMask)
- == CommandsInterface.SERVICE_CLASS_VOICE) {
- boolean cffEnabled = (info.status == 1);
- phone.mIccRecords.setVoiceCallForwardingFlag(1, cffEnabled);
- }
-
- return TextUtils.replace(template, sources, destinations);
- }
-
-
- private void
- onQueryCfComplete(AsyncResult ar) {
- StringBuilder sb = new StringBuilder(getScString());
- sb.append("\n");
-
- if (ar.exception != null) {
- state = State.FAILED;
- sb.append(getErrorMessage(ar));
- } else {
- CallForwardInfo infos[];
-
- infos = (CallForwardInfo[]) ar.result;
-
- if (infos.length == 0) {
- // Assume the default is not active
- sb.append(context.getText(com.android.internal.R.string.serviceDisabled));
-
- // Set unconditional CFF in SIM to false
- phone.mIccRecords.setVoiceCallForwardingFlag(1, false);
- } else {
-
- SpannableStringBuilder tb = new SpannableStringBuilder();
-
- // Each bit in the service class gets its own result line
- // The service classes may be split up over multiple
- // CallForwardInfos. So, for each service class, find out
- // which CallForwardInfo represents it and then build
- // the response text based on that
-
- for (int serviceClassMask = 1
- ; serviceClassMask <= SERVICE_CLASS_MAX
- ; serviceClassMask <<= 1
- ) {
- for (int i = 0, s = infos.length; i < s ; i++) {
- if ((serviceClassMask & infos[i].serviceClass) != 0) {
- tb.append(makeCFQueryResultMessage(infos[i],
- serviceClassMask));
- tb.append("\n");
- }
- }
- }
- sb.append(tb);
- }
-
- state = State.COMPLETE;
- }
-
- message = sb;
- phone.onMMIDone(this);
-
- }
-
- private void
- onQueryComplete(AsyncResult ar) {
- StringBuilder sb = new StringBuilder(getScString());
- sb.append("\n");
-
- if (ar.exception != null) {
- state = State.FAILED;
- sb.append(getErrorMessage(ar));
- } else {
- int[] ints = (int[])ar.result;
-
- if (ints.length != 0) {
- if (ints[0] == 0) {
- sb.append(context.getText(com.android.internal.R.string.serviceDisabled));
- } else if (sc.equals(SC_WAIT)) {
- // Call Waiting includes additional data in the response.
- sb.append(createQueryCallWaitingResultMessage(ints[1]));
- } else if (isServiceCodeCallBarring(sc)) {
- // ints[0] for Call Barring is a bit vector of services
- sb.append(createQueryCallBarringResultMessage(ints[0]));
- } else if (ints[0] == 1) {
- // for all other services, treat it as a boolean
- sb.append(context.getText(com.android.internal.R.string.serviceEnabled));
- } else {
- sb.append(context.getText(com.android.internal.R.string.mmiError));
- }
- } else {
- sb.append(context.getText(com.android.internal.R.string.mmiError));
- }
- state = State.COMPLETE;
- }
-
- message = sb;
- phone.onMMIDone(this);
- }
-
- private CharSequence
- createQueryCallWaitingResultMessage(int serviceClass) {
- StringBuilder sb =
- new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor));
-
- for (int classMask = 1
- ; classMask <= SERVICE_CLASS_MAX
- ; classMask <<= 1
- ) {
- if ((classMask & serviceClass) != 0) {
- sb.append("\n");
- sb.append(serviceClassToCFString(classMask & serviceClass));
- }
- }
- return sb;
- }
- private CharSequence
- createQueryCallBarringResultMessage(int serviceClass)
- {
- StringBuilder sb = new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor));
-
- for (int classMask = 1
- ; classMask <= SERVICE_CLASS_MAX
- ; classMask <<= 1
- ) {
- if ((classMask & serviceClass) != 0) {
- sb.append("\n");
- sb.append(serviceClassToCFString(classMask & serviceClass));
- }
- }
- return sb;
- }
-
- /***
- * TODO: It would be nice to have a method here that can take in a dialstring and
- * figure out if there is an MMI code embedded within it. This code would replace
- * some of the string parsing functionality in the Phone App's
- * SpecialCharSequenceMgr class.
- */
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("GsmMmiCode {");
-
- sb.append("State=" + getState());
- if (action != null) sb.append(" action=" + action);
- if (sc != null) sb.append(" sc=" + sc);
- if (sia != null) sb.append(" sia=" + sia);
- if (sib != null) sb.append(" sib=" + sib);
- if (sic != null) sb.append(" sic=" + sic);
- if (poundString != null) sb.append(" poundString=" + poundString);
- if (dialingNumber != null) sb.append(" dialingNumber=" + dialingNumber);
- if (pwd != null) sb.append(" pwd=" + pwd);
- sb.append("}");
- return sb.toString();
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
deleted file mode 100644
index bfa2bb1..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * 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.gsm;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.Intent;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.provider.Telephony.Sms;
-import android.provider.Telephony.Sms.Intents;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.telephony.SmsManager;
-import android.telephony.gsm.GsmCellLocation;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.telephony.SmsStorageMonitor;
-import com.android.internal.telephony.SmsUsageMonitor;
-import com.android.internal.telephony.TelephonyProperties;
-
-import java.util.HashMap;
-import java.util.Iterator;
-
-import static android.telephony.SmsMessage.MessageClass;
-
-public final class GsmSMSDispatcher extends SMSDispatcher {
- private static final String TAG = "GSM";
-
- /** Status report received */
- private static final int EVENT_NEW_SMS_STATUS_REPORT = 100;
-
- /** New broadcast SMS */
- private static final int EVENT_NEW_BROADCAST_SMS = 101;
-
- /** Result of writing SM to UICC (when SMS-PP service is not available). */
- private static final int EVENT_WRITE_SMS_COMPLETE = 102;
-
- /** Handler for SMS-PP data download messages to UICC. */
- private final UsimDataDownloadHandler mDataDownloadHandler;
-
- public GsmSMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor,
- SmsUsageMonitor usageMonitor) {
- super(phone, storageMonitor, usageMonitor);
- mDataDownloadHandler = new UsimDataDownloadHandler(mCm);
- mCm.setOnNewGsmSms(this, EVENT_NEW_SMS, null);
- mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
- mCm.setOnNewGsmBroadcastSms(this, EVENT_NEW_BROADCAST_SMS, null);
- }
-
- @Override
- public void dispose() {
- mCm.unSetOnNewGsmSms(this);
- mCm.unSetOnSmsStatus(this);
- mCm.unSetOnNewGsmBroadcastSms(this);
- }
-
- @Override
- protected String getFormat() {
- return android.telephony.SmsMessage.FORMAT_3GPP;
- }
-
- /**
- * Handles 3GPP format-specific events coming from the phone stack.
- * Other events are handled by {@link SMSDispatcher#handleMessage}.
- *
- * @param msg the message to handle
- */
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_NEW_SMS_STATUS_REPORT:
- handleStatusReport((AsyncResult) msg.obj);
- break;
-
- case EVENT_NEW_BROADCAST_SMS:
- handleBroadcastSms((AsyncResult)msg.obj);
- break;
-
- case EVENT_WRITE_SMS_COMPLETE:
- AsyncResult ar = (AsyncResult) msg.obj;
- if (ar.exception == null) {
- Log.d(TAG, "Successfully wrote SMS-PP message to UICC");
- mCm.acknowledgeLastIncomingGsmSms(true, 0, null);
- } else {
- Log.d(TAG, "Failed to write SMS-PP message to UICC", ar.exception);
- mCm.acknowledgeLastIncomingGsmSms(false,
- CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR, null);
- }
- break;
-
- default:
- super.handleMessage(msg);
- }
- }
-
- /**
- * Called when a status report is received. This should correspond to
- * a previously successful SEND.
- *
- * @param ar AsyncResult passed into the message handler. ar.result should
- * be a String representing the status report PDU, as ASCII hex.
- */
- private void handleStatusReport(AsyncResult ar) {
- String pduString = (String) ar.result;
- SmsMessage sms = SmsMessage.newFromCDS(pduString);
-
- if (sms != null) {
- int tpStatus = sms.getStatus();
- int messageRef = sms.messageRef;
- for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
- SmsTracker tracker = deliveryPendingList.get(i);
- if (tracker.mMessageRef == messageRef) {
- // Found it. Remove from list and broadcast.
- if(tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING ) {
- deliveryPendingList.remove(i);
- }
- PendingIntent intent = tracker.mDeliveryIntent;
- Intent fillIn = new Intent();
- fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
- fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP);
- try {
- intent.send(mContext, Activity.RESULT_OK, fillIn);
- } catch (CanceledException ex) {}
-
- // Only expect to see one tracker matching this messageref
- break;
- }
- }
- }
- acknowledgeLastIncomingSms(true, Intents.RESULT_SMS_HANDLED, null);
- }
-
- /** {@inheritDoc} */
- @Override
- public int dispatchMessage(SmsMessageBase smsb) {
-
- // If sms is null, means there was a parsing error.
- if (smsb == null) {
- Log.e(TAG, "dispatchMessage: message is null");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
-
- SmsMessage sms = (SmsMessage) smsb;
-
- if (sms.isTypeZero()) {
- // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be
- // Displayed/Stored/Notified. They should only be acknowledged.
- Log.d(TAG, "Received short message type 0, Don't display or store it. Send Ack");
- return Intents.RESULT_SMS_HANDLED;
- }
-
- // Send SMS-PP data download messages to UICC. See 3GPP TS 31.111 section 7.1.1.
- if (sms.isUsimDataDownload()) {
- UsimServiceTable ust = mPhone.getUsimServiceTable();
- // If we receive an SMS-PP message before the UsimServiceTable has been loaded,
- // assume that the data download service is not present. This is very unlikely to
- // happen because the IMS connection will not be established until after the ISIM
- // records have been loaded, after the USIM service table has been loaded.
- if (ust != null && ust.isAvailable(
- UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP)) {
- Log.d(TAG, "Received SMS-PP data download, sending to UICC.");
- return mDataDownloadHandler.startDataDownload(sms);
- } else {
- Log.d(TAG, "DATA_DL_VIA_SMS_PP service not available, storing message to UICC.");
- String smsc = IccUtils.bytesToHexString(
- PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(
- sms.getServiceCenterAddress()));
- mCm.writeSmsToSim(SmsManager.STATUS_ON_ICC_UNREAD, smsc,
- IccUtils.bytesToHexString(sms.getPdu()),
- obtainMessage(EVENT_WRITE_SMS_COMPLETE));
- return Activity.RESULT_OK; // acknowledge after response from write to USIM
- }
- }
-
- if (mSmsReceiveDisabled) {
- // Device doesn't support SMS service,
- Log.d(TAG, "Received short message on device which doesn't support "
- + "SMS service. Ignored.");
- return Intents.RESULT_SMS_HANDLED;
- }
-
- // Special case the message waiting indicator messages
- boolean handled = false;
- if (sms.isMWISetMessage()) {
- mPhone.setVoiceMessageWaiting(1, -1); // line 1: unknown number of msgs waiting
- handled = sms.isMwiDontStore();
- if (false) {
- Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled);
- }
- } else if (sms.isMWIClearMessage()) {
- mPhone.setVoiceMessageWaiting(1, 0); // line 1: no msgs waiting
- handled = sms.isMwiDontStore();
- if (false) {
- Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled);
- }
- }
-
- if (handled) {
- return Intents.RESULT_SMS_HANDLED;
- }
-
- if (!mStorageMonitor.isStorageAvailable() &&
- sms.getMessageClass() != MessageClass.CLASS_0) {
- // It's a storable message and there's no storage available. Bail.
- // (See TS 23.038 for a description of class 0 messages.)
- return Intents.RESULT_SMS_OUT_OF_MEMORY;
- }
-
- return dispatchNormalMessage(smsb);
- }
-
- /** {@inheritDoc} */
- @Override
- protected void sendData(String destAddr, String scAddr, int destPort,
- byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
- scAddr, destAddr, destPort, data, (deliveryIntent != null));
- if (pdu != null) {
- sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent,
- destAddr);
- } else {
- Log.e(TAG, "GsmSMSDispatcher.sendData(): getSubmitPdu() returned null");
- }
- }
-
- /** {@inheritDoc} */
- @Override
- protected void sendText(String destAddr, String scAddr, String text,
- PendingIntent sentIntent, PendingIntent deliveryIntent) {
- SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
- scAddr, destAddr, text, (deliveryIntent != null));
- if (pdu != null) {
- sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent,
- destAddr);
- } else {
- Log.e(TAG, "GsmSMSDispatcher.sendText(): getSubmitPdu() returned null");
- }
- }
-
- /** {@inheritDoc} */
- @Override
- protected TextEncodingDetails calculateLength(CharSequence messageBody,
- boolean use7bitOnly) {
- return SmsMessage.calculateLength(messageBody, use7bitOnly);
- }
-
- /** {@inheritDoc} */
- @Override
- protected void sendNewSubmitPdu(String destinationAddress, String scAddress,
- String message, SmsHeader smsHeader, int encoding,
- PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) {
- SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
- message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader),
- encoding, smsHeader.languageTable, smsHeader.languageShiftTable);
- if (pdu != null) {
- sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent,
- destinationAddress);
- } else {
- Log.e(TAG, "GsmSMSDispatcher.sendNewSubmitPdu(): getSubmitPdu() returned null");
- }
- }
-
- /** {@inheritDoc} */
- @Override
- protected void sendSms(SmsTracker tracker) {
- HashMap<String, Object> map = tracker.mData;
-
- byte smsc[] = (byte[]) map.get("smsc");
- byte pdu[] = (byte[]) map.get("pdu");
-
- Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
- mCm.sendSMS(IccUtils.bytesToHexString(smsc), IccUtils.bytesToHexString(pdu), reply);
- }
-
- /** {@inheritDoc} */
- @Override
- protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) {
- mCm.acknowledgeLastIncomingGsmSms(success, resultToCause(result), response);
- }
-
- private static int resultToCause(int rc) {
- switch (rc) {
- case Activity.RESULT_OK:
- case Intents.RESULT_SMS_HANDLED:
- // Cause code is ignored on success.
- return 0;
- case Intents.RESULT_SMS_OUT_OF_MEMORY:
- return CommandsInterface.GSM_SMS_FAIL_CAUSE_MEMORY_CAPACITY_EXCEEDED;
- case Intents.RESULT_SMS_GENERIC_ERROR:
- default:
- return CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR;
- }
- }
-
- /**
- * Holds all info about a message page needed to assemble a complete
- * concatenated message
- */
- private static final class SmsCbConcatInfo {
-
- private final SmsCbHeader mHeader;
- private final SmsCbLocation mLocation;
-
- public SmsCbConcatInfo(SmsCbHeader header, SmsCbLocation location) {
- mHeader = header;
- mLocation = location;
- }
-
- @Override
- public int hashCode() {
- return (mHeader.getSerialNumber() * 31) + mLocation.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof SmsCbConcatInfo) {
- SmsCbConcatInfo other = (SmsCbConcatInfo)obj;
-
- // Two pages match if they have the same serial number (which includes the
- // geographical scope and update number), and both pages belong to the same
- // location (PLMN, plus LAC and CID if these are part of the geographical scope).
- return mHeader.getSerialNumber() == other.mHeader.getSerialNumber()
- && mLocation.equals(other.mLocation);
- }
-
- return false;
- }
-
- /**
- * Compare the location code for this message to the current location code. The match is
- * relative to the geographical scope of the message, which determines whether the LAC
- * and Cell ID are saved in mLocation or set to -1 to match all values.
- *
- * @param plmn the current PLMN
- * @param lac the current Location Area (GSM) or Service Area (UMTS)
- * @param cid the current Cell ID
- * @return true if this message is valid for the current location; false otherwise
- */
- public boolean matchesLocation(String plmn, int lac, int cid) {
- return mLocation.isInLocationArea(plmn, lac, cid);
- }
- }
-
- // This map holds incomplete concatenated messages waiting for assembly
- private final HashMap<SmsCbConcatInfo, byte[][]> mSmsCbPageMap =
- new HashMap<SmsCbConcatInfo, byte[][]>();
-
- /**
- * Handle 3GPP format SMS-CB message.
- * @param ar the AsyncResult containing the received PDUs
- */
- private void handleBroadcastSms(AsyncResult ar) {
- try {
- byte[] receivedPdu = (byte[])ar.result;
-
- if (false) {
- for (int i = 0; i < receivedPdu.length; i += 8) {
- StringBuilder sb = new StringBuilder("SMS CB pdu data: ");
- for (int j = i; j < i + 8 && j < receivedPdu.length; j++) {
- int b = receivedPdu[j] & 0xff;
- if (b < 0x10) {
- sb.append('0');
- }
- sb.append(Integer.toHexString(b)).append(' ');
- }
- Log.d(TAG, sb.toString());
- }
- }
-
- SmsCbHeader header = new SmsCbHeader(receivedPdu);
- String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
- GsmCellLocation cellLocation = (GsmCellLocation) mPhone.getCellLocation();
- int lac = cellLocation.getLac();
- int cid = cellLocation.getCid();
-
- SmsCbLocation location;
- switch (header.getGeographicalScope()) {
- case SmsCbMessage.GEOGRAPHICAL_SCOPE_LA_WIDE:
- location = new SmsCbLocation(plmn, lac, -1);
- break;
-
- case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE:
- case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE:
- location = new SmsCbLocation(plmn, lac, cid);
- break;
-
- case SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE:
- default:
- location = new SmsCbLocation(plmn);
- break;
- }
-
- byte[][] pdus;
- int pageCount = header.getNumberOfPages();
- if (pageCount > 1) {
- // Multi-page message
- SmsCbConcatInfo concatInfo = new SmsCbConcatInfo(header, location);
-
- // Try to find other pages of the same message
- pdus = mSmsCbPageMap.get(concatInfo);
-
- if (pdus == null) {
- // This is the first page of this message, make room for all
- // pages and keep until complete
- pdus = new byte[pageCount][];
-
- mSmsCbPageMap.put(concatInfo, pdus);
- }
-
- // Page parameter is one-based
- pdus[header.getPageIndex() - 1] = receivedPdu;
-
- for (int i = 0; i < pdus.length; i++) {
- if (pdus[i] == null) {
- // Still missing pages, exit
- return;
- }
- }
-
- // Message complete, remove and dispatch
- mSmsCbPageMap.remove(concatInfo);
- } else {
- // Single page message
- pdus = new byte[1][];
- pdus[0] = receivedPdu;
- }
-
- SmsCbMessage message = GsmSmsCbMessage.createSmsCbMessage(header, location, pdus);
- dispatchBroadcastMessage(message);
-
- // Remove messages that are out of scope to prevent the map from
- // growing indefinitely, containing incomplete messages that were
- // never assembled
- Iterator<SmsCbConcatInfo> iter = mSmsCbPageMap.keySet().iterator();
-
- while (iter.hasNext()) {
- SmsCbConcatInfo info = iter.next();
-
- if (!info.matchesLocation(plmn, lac, cid)) {
- iter.remove();
- }
- }
- } catch (RuntimeException e) {
- Log.e(TAG, "Error in decoding SMS CB pdu", e);
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
deleted file mode 100644
index 4896efb..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ /dev/null
@@ -1,1727 +0,0 @@
-/*
- * 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.gsm;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.EventLogTags;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCardStatus;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RestrictedState;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
-
-import android.app.AlarmManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.provider.Telephony.Intents;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.gsm.GsmCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.TimeUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.TimeZone;
-
-/**
- * {@hide}
- */
-final class GsmServiceStateTracker extends ServiceStateTracker {
- static final String LOG_TAG = "GSM";
- static final boolean DBG = true;
-
- GSMPhone phone;
- GsmCellLocation cellLoc;
- GsmCellLocation newCellLoc;
- int mPreferredNetworkType;
-
- private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
- private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
- private int mMaxDataCalls = 1;
- private int mNewMaxDataCalls = 1;
- private int mReasonDataDenied = -1;
- private int mNewReasonDataDenied = -1;
-
- /**
- * GSM roaming status solely based on TS 27.007 7.2 CREG. Only used by
- * handlePollStateResult to store CREG roaming result.
- */
- private boolean mGsmRoaming = false;
-
- /**
- * Data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by
- * handlePollStateResult to store CGREG roaming result.
- */
- private boolean mDataRoaming = false;
-
- /**
- * Mark when service state is in emergency call only mode
- */
- private boolean mEmergencyOnly = false;
-
- /**
- * Sometimes we get the NITZ time before we know what country we
- * are in. Keep the time zone information from the NITZ string so
- * we can fix the time zone once know the country.
- */
- private boolean mNeedFixZoneAfterNitz = false;
- private int mZoneOffset;
- private boolean mZoneDst;
- private long mZoneTime;
- private boolean mGotCountryCode = false;
- private ContentResolver cr;
-
- /** Boolean is true is setTimeFromNITZString was called */
- private boolean mNitzUpdatedTime = false;
-
- String mSavedTimeZone;
- long mSavedTime;
- long mSavedAtTime;
-
- /**
- * We can't register for SIM_RECORDS_LOADED immediately because the
- * SIMRecords object may not be instantiated yet.
- */
- private boolean mNeedToRegForSimLoaded;
-
- /** Started the recheck process after finding gprs should registered but not. */
- private boolean mStartedGprsRegCheck = false;
-
- /** Already sent the event-log for no gprs register. */
- private boolean mReportedGprsNoReg = false;
-
- /**
- * The Notification object given to the NotificationManager.
- */
- private Notification mNotification;
-
- /** Wake lock used while setting time of day. */
- private PowerManager.WakeLock mWakeLock;
- private static final String WAKELOCK_TAG = "ServiceStateTracker";
-
- /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
- private String curSpn = null;
- private String curPlmn = null;
- private int curSpnRule = 0;
-
- /** waiting period before recheck gprs and voice registration. */
- static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
-
- /** Notification type. */
- static final int PS_ENABLED = 1001; // Access Control blocks data service
- static final int PS_DISABLED = 1002; // Access Control enables data service
- static final int CS_ENABLED = 1003; // Access Control blocks all voice/sms service
- static final int CS_DISABLED = 1004; // Access Control enables all voice/sms service
- static final int CS_NORMAL_ENABLED = 1005; // Access Control blocks normal voice/sms service
- static final int CS_EMERGENCY_ENABLED = 1006; // Access Control blocks emergency call service
-
- /** Notification id. */
- static final int PS_NOTIFICATION = 888; // Id to update and cancel PS restricted
- static final int CS_NOTIFICATION = 999; // Id to update and cancel CS restricted
-
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
- // update emergency string whenever locale changed
- updateSpnDisplay();
- }
- }
- };
-
- private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
- @Override
- public void onChange(boolean selfChange) {
- Log.i("GsmServiceStateTracker", "Auto time state changed");
- revertToNitzTime();
- }
- };
-
- private ContentObserver mAutoTimeZoneObserver = new ContentObserver(new Handler()) {
- @Override
- public void onChange(boolean selfChange) {
- Log.i("GsmServiceStateTracker", "Auto time zone state changed");
- revertToNitzTimeZone();
- }
- };
-
- public GsmServiceStateTracker(GSMPhone phone) {
- super();
-
- this.phone = phone;
- cm = phone.mCM;
- ss = new ServiceState();
- newSS = new ServiceState();
- cellLoc = new GsmCellLocation();
- newCellLoc = new GsmCellLocation();
- mSignalStrength = new SignalStrength();
-
- PowerManager powerManager =
- (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
- mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
-
- cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
- cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
-
- cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
- cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
- cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
- cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
- phone.getIccCard().registerForReady(this, EVENT_SIM_READY, null);
-
- // system setting property AIRPLANE_MODE_ON is set in Settings.
- int airplaneMode = Settings.System.getInt(
- phone.getContext().getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0);
- mDesiredPowerState = ! (airplaneMode > 0);
-
- cr = phone.getContext().getContentResolver();
- cr.registerContentObserver(
- Settings.System.getUriFor(Settings.System.AUTO_TIME), true,
- mAutoTimeObserver);
- cr.registerContentObserver(
- Settings.System.getUriFor(Settings.System.AUTO_TIME_ZONE), true,
- mAutoTimeZoneObserver);
-
- setSignalStrengthDefaultValues();
- mNeedToRegForSimLoaded = true;
-
- // Monitor locale change
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_LOCALE_CHANGED);
- phone.getContext().registerReceiver(mIntentReceiver, filter);
-
- // Gsm doesn't support OTASP so its not needed
- phone.notifyOtaspChanged(OTASP_NOT_NEEDED);
- }
-
- public void dispose() {
- // Unregister for all events.
- cm.unregisterForAvailable(this);
- cm.unregisterForRadioStateChanged(this);
- cm.unregisterForVoiceNetworkStateChanged(this);
- phone.getIccCard().unregisterForReady(this);
- phone.mIccRecords.unregisterForRecordsLoaded(this);
- cm.unSetOnSignalStrengthUpdate(this);
- cm.unSetOnRestrictedStateChanged(this);
- cm.unSetOnNITZTime(this);
- cr.unregisterContentObserver(this.mAutoTimeObserver);
- cr.unregisterContentObserver(this.mAutoTimeZoneObserver);
- }
-
- protected void finalize() {
- if(DBG) log("finalize");
- }
-
- @Override
- protected Phone getPhone() {
- return phone;
- }
-
- public void handleMessage (Message msg) {
- AsyncResult ar;
- int[] ints;
- String[] strings;
- Message message;
-
- if (!phone.mIsTheCurrentActivePhone) {
- Log.e(LOG_TAG, "Received message " + msg +
- "[" + msg.what + "] while being destroyed. Ignoring.");
- return;
- }
- switch (msg.what) {
- case EVENT_RADIO_AVAILABLE:
- //this is unnecessary
- //setPowerStateToDesired();
- break;
-
- case EVENT_SIM_READY:
- // Set the network type, in case the radio does not restore it.
- cm.setCurrentPreferredNetworkType();
-
- // The SIM is now ready i.e if it was locked
- // it has been unlocked. At this stage, the radio is already
- // powered on.
- if (mNeedToRegForSimLoaded) {
- phone.mIccRecords.registerForRecordsLoaded(this,
- EVENT_SIM_RECORDS_LOADED, null);
- mNeedToRegForSimLoaded = false;
- }
-
- boolean skipRestoringSelection = phone.getContext().getResources().getBoolean(
- com.android.internal.R.bool.skip_restoring_network_selection);
-
- if (!skipRestoringSelection) {
- // restore the previous network selection.
- phone.restoreSavedNetworkSelection(null);
- }
- pollState();
- // Signal strength polling stops when radio is off
- queueNextSignalStrengthPoll();
- break;
-
- case EVENT_RADIO_STATE_CHANGED:
- // This will do nothing in the radio not
- // available case
- setPowerStateToDesired();
- pollState();
- break;
-
- case EVENT_NETWORK_STATE_CHANGED:
- pollState();
- break;
-
- case EVENT_GET_SIGNAL_STRENGTH:
- // This callback is called when signal strength is polled
- // all by itself
-
- if (!(cm.getRadioState().isOn())) {
- // Polling will continue when radio turns back on
- return;
- }
- ar = (AsyncResult) msg.obj;
- onSignalStrengthResult(ar);
- queueNextSignalStrengthPoll();
-
- break;
-
- case EVENT_GET_LOC_DONE:
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception == null) {
- String states[] = (String[])ar.result;
- int lac = -1;
- int cid = -1;
- if (states.length >= 3) {
- try {
- if (states[1] != null && states[1].length() > 0) {
- lac = Integer.parseInt(states[1], 16);
- }
- if (states[2] != null && states[2].length() > 0) {
- cid = Integer.parseInt(states[2], 16);
- }
- } catch (NumberFormatException ex) {
- Log.w(LOG_TAG, "error parsing location: " + ex);
- }
- }
- cellLoc.setLacAndCid(lac, cid);
- phone.notifyLocationChanged();
- }
-
- // Release any temporary cell lock, which could have been
- // acquired to allow a single-shot location update.
- disableSingleLocationUpdate();
- break;
-
- case EVENT_POLL_STATE_REGISTRATION:
- case EVENT_POLL_STATE_GPRS:
- case EVENT_POLL_STATE_OPERATOR:
- case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
- ar = (AsyncResult) msg.obj;
-
- handlePollStateResult(msg.what, ar);
- break;
-
- case EVENT_POLL_SIGNAL_STRENGTH:
- // Just poll signal strength...not part of pollState()
-
- cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
- break;
-
- case EVENT_NITZ_TIME:
- ar = (AsyncResult) msg.obj;
-
- String nitzString = (String)((Object[])ar.result)[0];
- long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
-
- setTimeFromNITZString(nitzString, nitzReceiveTime);
- break;
-
- case EVENT_SIGNAL_STRENGTH_UPDATE:
- // This is a notification from
- // CommandsInterface.setOnSignalStrengthUpdate
-
- ar = (AsyncResult) msg.obj;
-
- // The radio is telling us about signal strength changes
- // we don't have to ask it
- dontPollSignalStrength = true;
-
- onSignalStrengthResult(ar);
- break;
-
- case EVENT_SIM_RECORDS_LOADED:
- updateSpnDisplay();
- break;
-
- case EVENT_LOCATION_UPDATES_ENABLED:
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception == null) {
- cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
- }
- break;
-
- case EVENT_SET_PREFERRED_NETWORK_TYPE:
- ar = (AsyncResult) msg.obj;
- // Don't care the result, only use for dereg network (COPS=2)
- message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj);
- cm.setPreferredNetworkType(mPreferredNetworkType, message);
- break;
-
- case EVENT_RESET_PREFERRED_NETWORK_TYPE:
- ar = (AsyncResult) msg.obj;
- if (ar.userObj != null) {
- AsyncResult.forMessage(((Message) ar.userObj)).exception
- = ar.exception;
- ((Message) ar.userObj).sendToTarget();
- }
- break;
-
- case EVENT_GET_PREFERRED_NETWORK_TYPE:
- ar = (AsyncResult) msg.obj;
-
- if (ar.exception == null) {
- mPreferredNetworkType = ((int[])ar.result)[0];
- } else {
- mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
- }
-
- message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj);
- int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL;
-
- cm.setPreferredNetworkType(toggledNetworkType, message);
- break;
-
- case EVENT_CHECK_REPORT_GPRS:
- if (ss != null && !isGprsConsistent(gprsState, ss.getState())) {
-
- // Can't register data service while voice service is ok
- // i.e. CREG is ok while CGREG is not
- // possible a network or baseband side error
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
- EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL,
- ss.getOperatorNumeric(), loc != null ? loc.getCid() : -1);
- mReportedGprsNoReg = true;
- }
- mStartedGprsRegCheck = false;
- break;
-
- case EVENT_RESTRICTED_STATE_CHANGED:
- // This is a notification from
- // CommandsInterface.setOnRestrictedStateChanged
-
- if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED");
-
- ar = (AsyncResult) msg.obj;
-
- onRestrictedStateChanged(ar);
- break;
-
- default:
- super.handleMessage(msg);
- break;
- }
- }
-
- protected void setPowerStateToDesired() {
- // If we want it on and it's off, turn it on
- if (mDesiredPowerState
- && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
- cm.setRadioPower(true, null);
- } else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
- // If it's on and available and we want it off gracefully
- DataConnectionTracker dcTracker = phone.mDataConnectionTracker;
- powerOffRadioSafely(dcTracker);
- } // Otherwise, we're in the desired state
- }
-
- @Override
- protected void hangupAndPowerOff() {
- // hang up all active voice calls
- if (phone.isInCall()) {
- phone.mCT.ringingCall.hangupIfAlive();
- phone.mCT.backgroundCall.hangupIfAlive();
- phone.mCT.foregroundCall.hangupIfAlive();
- }
-
- cm.setRadioPower(false, null);
- }
-
- protected void updateSpnDisplay() {
- int rule = phone.mIccRecords.getDisplayRule(ss.getOperatorNumeric());
- String spn = phone.mIccRecords.getServiceProviderName();
- String plmn = ss.getOperatorAlphaLong();
-
- // For emergency calls only, pass the EmergencyCallsOnly string via EXTRA_PLMN
- if (mEmergencyOnly && cm.getRadioState().isOn()) {
- plmn = Resources.getSystem().
- getText(com.android.internal.R.string.emergency_calls_only).toString();
- if (DBG) log("updateSpnDisplay: emergency only and radio is on plmn='" + plmn + "'");
- }
-
- if (rule != curSpnRule
- || !TextUtils.equals(spn, curSpn)
- || !TextUtils.equals(plmn, curPlmn)) {
- boolean showSpn = !mEmergencyOnly && !TextUtils.isEmpty(spn)
- && (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN;
- boolean showPlmn = !TextUtils.isEmpty(plmn) && (mEmergencyOnly ||
- ((rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN));
-
- if (DBG) {
- log(String.format("updateSpnDisplay: changed sending intent" + " rule=" + rule +
- " showPlmn='%b' plmn='%s' showSpn='%b' spn='%s'",
- showPlmn, plmn, showSpn, spn));
- }
- Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn);
- intent.putExtra(Intents.EXTRA_SPN, spn);
- intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn);
- intent.putExtra(Intents.EXTRA_PLMN, plmn);
- phone.getContext().sendStickyBroadcast(intent);
- }
-
- curSpnRule = rule;
- curSpn = spn;
- curPlmn = plmn;
- }
-
- /**
- * Handle the result of one of the pollState()-related requests
- */
- protected void handlePollStateResult (int what, AsyncResult ar) {
- int ints[];
- String states[];
-
- // Ignore stale requests from last poll
- if (ar.userObj != pollingContext) return;
-
- if (ar.exception != null) {
- CommandException.Error err=null;
-
- if (ar.exception instanceof CommandException) {
- err = ((CommandException)(ar.exception)).getCommandError();
- }
-
- if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
- // Radio has crashed or turned off
- cancelPollState();
- return;
- }
-
- if (!cm.getRadioState().isOn()) {
- // Radio has crashed or turned off
- cancelPollState();
- return;
- }
-
- if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
- loge("RIL implementation has returned an error where it must succeed" +
- ar.exception);
- }
- } else try {
- switch (what) {
- case EVENT_POLL_STATE_REGISTRATION:
- states = (String[])ar.result;
- int lac = -1;
- int cid = -1;
- int regState = -1;
- int reasonRegStateDenied = -1;
- int psc = -1;
- if (states.length > 0) {
- try {
- regState = Integer.parseInt(states[0]);
- if (states.length >= 3) {
- if (states[1] != null && states[1].length() > 0) {
- lac = Integer.parseInt(states[1], 16);
- }
- if (states[2] != null && states[2].length() > 0) {
- cid = Integer.parseInt(states[2], 16);
- }
- }
- if (states.length > 14) {
- if (states[14] != null && states[14].length() > 0) {
- psc = Integer.parseInt(states[14], 16);
- }
- }
- } catch (NumberFormatException ex) {
- loge("error parsing RegistrationState: " + ex);
- }
- }
-
- mGsmRoaming = regCodeIsRoaming(regState);
- newSS.setState (regCodeToServiceState(regState));
-
- if (regState == 10 || regState == 12 || regState == 13 || regState == 14) {
- mEmergencyOnly = true;
- } else {
- mEmergencyOnly = false;
- }
-
- // LAC and CID are -1 if not avail
- newCellLoc.setLacAndCid(lac, cid);
- newCellLoc.setPsc(psc);
- break;
-
- case EVENT_POLL_STATE_GPRS:
- states = (String[])ar.result;
-
- int type = 0;
- regState = -1;
- mNewReasonDataDenied = -1;
- mNewMaxDataCalls = 1;
- if (states.length > 0) {
- try {
- regState = Integer.parseInt(states[0]);
-
- // states[3] (if present) is the current radio technology
- if (states.length >= 4 && states[3] != null) {
- type = Integer.parseInt(states[3]);
- }
- if ((states.length >= 5 ) && (regState == 3)) {
- mNewReasonDataDenied = Integer.parseInt(states[4]);
- }
- if (states.length >= 6) {
- mNewMaxDataCalls = Integer.parseInt(states[5]);
- }
- } catch (NumberFormatException ex) {
- loge("error parsing GprsRegistrationState: " + ex);
- }
- }
- newGPRSState = regCodeToServiceState(regState);
- mDataRoaming = regCodeIsRoaming(regState);
- mNewRilRadioTechnology = type;
- newSS.setRadioTechnology(type);
- break;
-
- case EVENT_POLL_STATE_OPERATOR:
- String opNames[] = (String[])ar.result;
-
- if (opNames != null && opNames.length >= 3) {
- newSS.setOperatorName (opNames[0], opNames[1], opNames[2]);
- }
- break;
-
- case EVENT_POLL_STATE_NETWORK_SELECTION_MODE:
- ints = (int[])ar.result;
- newSS.setIsManualSelection(ints[0] == 1);
- break;
- }
-
- } catch (RuntimeException ex) {
- loge("Exception while polling service state. Probably malformed RIL response." + ex);
- }
-
- pollingContext[0]--;
-
- if (pollingContext[0] == 0) {
- /**
- * Since the roaming states of gsm service (from +CREG) and
- * data service (from +CGREG) could be different, the new SS
- * is set roaming while either one is roaming.
- *
- * There is an exception for the above rule. The new SS is not set
- * as roaming while gsm service reports roaming but indeed it is
- * not roaming between operators.
- */
- boolean roaming = (mGsmRoaming || mDataRoaming);
- if (mGsmRoaming && !isRoamingBetweenOperators(mGsmRoaming, newSS)) {
- roaming = false;
- }
- newSS.setRoaming(roaming);
- newSS.setEmergencyOnly(mEmergencyOnly);
- pollStateDone();
- }
- }
-
- private void setSignalStrengthDefaultValues() {
- // TODO Make a constructor only has boolean gsm as parameter
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, SignalStrength.INVALID_SNR, -1, true);
- }
-
- /**
- * A complete "service state" from our perspective is
- * composed of a handful of separate requests to the radio.
- *
- * We make all of these requests at once, but then abandon them
- * and start over again if the radio notifies us that some
- * event has changed
- */
- private void pollState() {
- pollingContext = new int[1];
- pollingContext[0] = 0;
-
- switch (cm.getRadioState()) {
- case RADIO_UNAVAILABLE:
- newSS.setStateOutOfService();
- newCellLoc.setStateInvalid();
- setSignalStrengthDefaultValues();
- mGotCountryCode = false;
- mNitzUpdatedTime = false;
- pollStateDone();
- break;
-
- case RADIO_OFF:
- newSS.setStateOff();
- newCellLoc.setStateInvalid();
- setSignalStrengthDefaultValues();
- mGotCountryCode = false;
- mNitzUpdatedTime = false;
- pollStateDone();
- break;
-
- default:
- // Issue all poll-related commands at once
- // then count down the responses, which
- // are allowed to arrive out-of-order
-
- pollingContext[0]++;
- cm.getOperator(
- obtainMessage(
- EVENT_POLL_STATE_OPERATOR, pollingContext));
-
- pollingContext[0]++;
- cm.getDataRegistrationState(
- obtainMessage(
- EVENT_POLL_STATE_GPRS, pollingContext));
-
- pollingContext[0]++;
- cm.getVoiceRegistrationState(
- obtainMessage(
- EVENT_POLL_STATE_REGISTRATION, pollingContext));
-
- pollingContext[0]++;
- cm.getNetworkSelectionMode(
- obtainMessage(
- EVENT_POLL_STATE_NETWORK_SELECTION_MODE, pollingContext));
- break;
- }
- }
-
- private void pollStateDone() {
- if (DBG) {
- log("Poll ServiceState done: " +
- " oldSS=[" + ss + "] newSS=[" + newSS +
- "] oldGprs=" + gprsState + " newData=" + newGPRSState +
- " oldMaxDataCalls=" + mMaxDataCalls +
- " mNewMaxDataCalls=" + mNewMaxDataCalls +
- " oldReasonDataDenied=" + mReasonDataDenied +
- " mNewReasonDataDenied=" + mNewReasonDataDenied +
- " oldType=" + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
- " newType=" + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology));
- }
-
- boolean hasRegistered =
- ss.getState() != ServiceState.STATE_IN_SERVICE
- && newSS.getState() == ServiceState.STATE_IN_SERVICE;
-
- boolean hasDeregistered =
- ss.getState() == ServiceState.STATE_IN_SERVICE
- && newSS.getState() != ServiceState.STATE_IN_SERVICE;
-
- boolean hasGprsAttached =
- gprsState != ServiceState.STATE_IN_SERVICE
- && newGPRSState == ServiceState.STATE_IN_SERVICE;
-
- boolean hasGprsDetached =
- gprsState == ServiceState.STATE_IN_SERVICE
- && newGPRSState != ServiceState.STATE_IN_SERVICE;
-
- boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
-
- boolean hasChanged = !newSS.equals(ss);
-
- boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
-
- boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
-
- boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
-
- // Add an event log when connection state changes
- if (ss.getState() != newSS.getState() || gprsState != newGPRSState) {
- EventLog.writeEvent(EventLogTags.GSM_SERVICE_STATE_CHANGE,
- ss.getState(), gprsState, newSS.getState(), newGPRSState);
- }
-
- ServiceState tss;
- tss = ss;
- ss = newSS;
- newSS = tss;
- // clean slate for next time
- newSS.setStateOutOfService();
-
- GsmCellLocation tcl = cellLoc;
- cellLoc = newCellLoc;
- newCellLoc = tcl;
-
- // Add an event log when network type switched
- // TODO: we may add filtering to reduce the event logged,
- // i.e. check preferred network setting, only switch to 2G, etc
- if (hasRadioTechnologyChanged) {
- int cid = -1;
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
- if (loc != null) cid = loc.getCid();
- EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRilRadioTechnology,
- mNewRilRadioTechnology);
- if (DBG) {
- log("RAT switched " + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
- " -> " + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology) +
- " at cell " + cid);
- }
- }
-
- gprsState = newGPRSState;
- mReasonDataDenied = mNewReasonDataDenied;
- mMaxDataCalls = mNewMaxDataCalls;
- mRilRadioTechnology = mNewRilRadioTechnology;
- // this new state has been applied - forget it until we get a new new state
- mNewRilRadioTechnology = 0;
-
-
- newSS.setStateOutOfService(); // clean slate for next time
-
- if (hasRadioTechnologyChanged) {
- phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
- ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
- }
-
- if (hasRegistered) {
- mNetworkAttachedRegistrants.notifyRegistrants();
-
- if (DBG) {
- log("pollStateDone: registering current mNitzUpdatedTime=" +
- mNitzUpdatedTime + " changing to false");
- }
- mNitzUpdatedTime = false;
- }
-
- if (hasChanged) {
- String operatorNumeric;
-
- updateSpnDisplay();
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
- ss.getOperatorAlphaLong());
-
- String prevOperatorNumeric =
- SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
- operatorNumeric = ss.getOperatorNumeric();
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
-
- if (operatorNumeric == null) {
- if (DBG) log("operatorNumeric is null");
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
- mGotCountryCode = false;
- mNitzUpdatedTime = false;
- } else {
- String iso = "";
- String mcc = operatorNumeric.substring(0, 3);
- try{
- iso = MccTable.countryCodeForMcc(Integer.parseInt(mcc));
- } catch ( NumberFormatException ex){
- loge("pollStateDone: countryCodeForMcc error" + ex);
- } catch ( StringIndexOutOfBoundsException ex) {
- loge("pollStateDone: countryCodeForMcc error" + ex);
- }
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
- mGotCountryCode = true;
-
- TimeZone zone = null;
-
- if (!mNitzUpdatedTime && !mcc.equals("000") && !TextUtils.isEmpty(iso) &&
- getAutoTimeZone()) {
-
- // Test both paths if ignore nitz is true
- boolean testOneUniqueOffsetPath = SystemProperties.getBoolean(
- TelephonyProperties.PROPERTY_IGNORE_NITZ, false) &&
- ((SystemClock.uptimeMillis() & 1) == 0);
-
- ArrayList<TimeZone> uniqueZones = TimeUtils.getTimeZonesWithUniqueOffsets(iso);
- if ((uniqueZones.size() == 1) || testOneUniqueOffsetPath) {
- zone = uniqueZones.get(0);
- if (DBG) {
- log("pollStateDone: no nitz but one TZ for iso-cc=" + iso +
- " with zone.getID=" + zone.getID() +
- " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath);
- }
- setAndBroadcastNetworkSetTimeZone(zone.getID());
- } else {
- if (DBG) {
- log("pollStateDone: there are " + uniqueZones.size() +
- " unique offsets for iso-cc='" + iso +
- " testOneUniqueOffsetPath=" + testOneUniqueOffsetPath +
- "', do nothing");
- }
- }
- }
-
- if (shouldFixTimeZoneNow(phone, operatorNumeric, prevOperatorNumeric,
- mNeedFixZoneAfterNitz)) {
- // If the offset is (0, false) and the timezone property
- // is set, use the timezone property rather than
- // GMT.
- String zoneName = SystemProperties.get(TIMEZONE_PROPERTY);
- if (DBG) {
- log("pollStateDone: fix time zone zoneName='" + zoneName +
- "' mZoneOffset=" + mZoneOffset + " mZoneDst=" + mZoneDst +
- " iso-cc='" + iso +
- "' iso-cc-idx=" + Arrays.binarySearch(GMT_COUNTRY_CODES, iso));
- }
-
- // "(mZoneOffset == 0) && (mZoneDst == false) &&
- // (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)"
- // means that we received a NITZ string telling
- // it is in GMT+0 w/ DST time zone
- // BUT iso tells is NOT, e.g, a wrong NITZ reporting
- // local time w/ 0 offset.
- if ((mZoneOffset == 0) && (mZoneDst == false) &&
- (zoneName != null) && (zoneName.length() > 0) &&
- (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) {
- zone = TimeZone.getDefault();
- if (mNeedFixZoneAfterNitz) {
- // For wrong NITZ reporting local time w/ 0 offset,
- // need adjust time to reflect default timezone setting
- long ctm = System.currentTimeMillis();
- long tzOffset = zone.getOffset(ctm);
- if (DBG) {
- log("pollStateDone: tzOffset=" + tzOffset + " ltod=" +
- TimeUtils.logTimeOfDay(ctm));
- }
- if (getAutoTime()) {
- long adj = ctm - tzOffset;
- if (DBG) log("pollStateDone: adj ltod=" +
- TimeUtils.logTimeOfDay(adj));
- setAndBroadcastNetworkSetTime(adj);
- } else {
- // Adjust the saved NITZ time to account for tzOffset.
- mSavedTime = mSavedTime - tzOffset;
- }
- }
- if (DBG) log("pollStateDone: using default TimeZone");
- } else if (iso.equals("")){
- // Country code not found. This is likely a test network.
- // Get a TimeZone based only on the NITZ parameters (best guess).
- zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime);
- if (DBG) log("pollStateDone: using NITZ TimeZone");
- } else {
- zone = TimeUtils.getTimeZone(mZoneOffset, mZoneDst, mZoneTime, iso);
- if (DBG) log("pollStateDone: using getTimeZone(off, dst, time, iso)");
- }
-
- mNeedFixZoneAfterNitz = false;
-
- if (zone != null) {
- log("pollStateDone: zone != null zone.getID=" + zone.getID());
- if (getAutoTimeZone()) {
- setAndBroadcastNetworkSetTimeZone(zone.getID());
- }
- saveNitzTimeZone(zone.getID());
- } else {
- log("pollStateDone: zone == null");
- }
- }
- }
-
- phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
- ss.getRoaming() ? "true" : "false");
-
- phone.notifyServiceStateChanged(ss);
- }
-
- if (hasGprsAttached) {
- mAttachedRegistrants.notifyRegistrants();
- }
-
- if (hasGprsDetached) {
- mDetachedRegistrants.notifyRegistrants();
- }
-
- if (hasRadioTechnologyChanged) {
- phone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED);
- }
-
- if (hasRoamingOn) {
- mRoamingOnRegistrants.notifyRegistrants();
- }
-
- if (hasRoamingOff) {
- mRoamingOffRegistrants.notifyRegistrants();
- }
-
- if (hasLocationChanged) {
- phone.notifyLocationChanged();
- }
-
- if (! isGprsConsistent(gprsState, ss.getState())) {
- if (!mStartedGprsRegCheck && !mReportedGprsNoReg) {
- mStartedGprsRegCheck = true;
-
- int check_period = Settings.Secure.getInt(
- phone.getContext().getContentResolver(),
- Settings.Secure.GPRS_REGISTER_CHECK_PERIOD_MS,
- DEFAULT_GPRS_CHECK_PERIOD_MILLIS);
- sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS),
- check_period);
- }
- } else {
- mReportedGprsNoReg = false;
- }
- }
-
- /**
- * Check if GPRS got registered while voice is registered.
- *
- * @param gprsState for GPRS registration state, i.e. CGREG in GSM
- * @param serviceState for voice registration state, i.e. CREG in GSM
- * @return false if device only register to voice but not gprs
- */
- private boolean isGprsConsistent(int gprsState, int serviceState) {
- return !((serviceState == ServiceState.STATE_IN_SERVICE) &&
- (gprsState != ServiceState.STATE_IN_SERVICE));
- }
-
- /**
- * Returns a TimeZone object based only on parameters from the NITZ string.
- */
- private TimeZone getNitzTimeZone(int offset, boolean dst, long when) {
- TimeZone guess = findTimeZone(offset, dst, when);
- if (guess == null) {
- // Couldn't find a proper timezone. Perhaps the DST data is wrong.
- guess = findTimeZone(offset, !dst, when);
- }
- if (DBG) log("getNitzTimeZone returning " + (guess == null ? guess : guess.getID()));
- return guess;
- }
-
- private TimeZone findTimeZone(int offset, boolean dst, long when) {
- int rawOffset = offset;
- if (dst) {
- rawOffset -= 3600000;
- }
- String[] zones = TimeZone.getAvailableIDs(rawOffset);
- TimeZone guess = null;
- Date d = new Date(when);
- for (String zone : zones) {
- TimeZone tz = TimeZone.getTimeZone(zone);
- if (tz.getOffset(when) == offset &&
- tz.inDaylightTime(d) == dst) {
- guess = tz;
- break;
- }
- }
-
- return guess;
- }
-
- private void queueNextSignalStrengthPoll() {
- if (dontPollSignalStrength) {
- // The radio is telling us about signal strength changes
- // we don't have to ask it
- return;
- }
-
- Message msg;
-
- msg = obtainMessage();
- msg.what = EVENT_POLL_SIGNAL_STRENGTH;
-
- long nextTime;
-
- // TODO Don't poll signal strength if screen is off
- sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
- }
-
- /**
- * Send signal-strength-changed notification if changed.
- * Called both for solicited and unsolicited signal strength updates.
- */
- private void onSignalStrengthResult(AsyncResult ar) {
- SignalStrength oldSignalStrength = mSignalStrength;
- int rssi = 99;
- int lteSignalStrength = -1;
- int lteRsrp = -1;
- int lteRsrq = -1;
- int lteRssnr = SignalStrength.INVALID_SNR;
- int lteCqi = -1;
-
- if (ar.exception != null) {
- // -1 = unknown
- // most likely radio is resetting/disconnected
- setSignalStrengthDefaultValues();
- } else {
- int[] ints = (int[])ar.result;
-
- // bug 658816 seems to be a case where the result is 0-length
- if (ints.length != 0) {
- rssi = ints[0];
- lteSignalStrength = ints[7];
- lteRsrp = ints[8];
- lteRsrq = ints[9];
- lteRssnr = ints[10];
- lteCqi = ints[11];
- } else {
- loge("Bogus signal strength response");
- rssi = 99;
- }
- }
-
- mSignalStrength = new SignalStrength(rssi, -1, -1, -1,
- -1, -1, -1, lteSignalStrength, lteRsrp, lteRsrq, lteRssnr, lteCqi, true);
-
- if (!mSignalStrength.equals(oldSignalStrength)) {
- try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
- // POLL_PERIOD_MILLIS) during Radio Technology Change)
- phone.notifySignalStrength();
- } catch (NullPointerException ex) {
- log("onSignalStrengthResult() Phone already destroyed: " + ex
- + "SignalStrength not notified");
- }
- }
- }
-
- /**
- * Set restricted state based on the OnRestrictedStateChanged notification
- * If any voice or packet restricted state changes, trigger a UI
- * notification and notify registrants when sim is ready.
- *
- * @param ar an int value of RIL_RESTRICTED_STATE_*
- */
- private void onRestrictedStateChanged(AsyncResult ar) {
- RestrictedState newRs = new RestrictedState();
-
- if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState);
-
- if (ar.exception == null) {
- int[] ints = (int[])ar.result;
- int state = ints[0];
-
- newRs.setCsEmergencyRestricted(
- ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) ||
- ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
- //ignore the normal call and data restricted state before SIM READY
- if (phone.getIccCard().getState() == IccCard.State.READY) {
- newRs.setCsNormalRestricted(
- ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) ||
- ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) );
- newRs.setPsRestricted(
- (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0);
- }
-
- if (DBG) log("onRestrictedStateChanged: new rs "+ newRs);
-
- if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) {
- mPsRestrictEnabledRegistrants.notifyRegistrants();
- setNotification(PS_ENABLED);
- } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) {
- mPsRestrictDisabledRegistrants.notifyRegistrants();
- setNotification(PS_DISABLED);
- }
-
- /**
- * There are two kind of cs restriction, normal and emergency. So
- * there are 4 x 4 combinations in current and new restricted states
- * and we only need to notify when state is changed.
- */
- if (mRestrictedState.isCsRestricted()) {
- if (!newRs.isCsRestricted()) {
- // remove all restriction
- setNotification(CS_DISABLED);
- } else if (!newRs.isCsNormalRestricted()) {
- // remove normal restriction
- setNotification(CS_EMERGENCY_ENABLED);
- } else if (!newRs.isCsEmergencyRestricted()) {
- // remove emergency restriction
- setNotification(CS_NORMAL_ENABLED);
- }
- } else if (mRestrictedState.isCsEmergencyRestricted() &&
- !mRestrictedState.isCsNormalRestricted()) {
- if (!newRs.isCsRestricted()) {
- // remove all restriction
- setNotification(CS_DISABLED);
- } else if (newRs.isCsRestricted()) {
- // enable all restriction
- setNotification(CS_ENABLED);
- } else if (newRs.isCsNormalRestricted()) {
- // remove emergency restriction and enable normal restriction
- setNotification(CS_NORMAL_ENABLED);
- }
- } else if (!mRestrictedState.isCsEmergencyRestricted() &&
- mRestrictedState.isCsNormalRestricted()) {
- if (!newRs.isCsRestricted()) {
- // remove all restriction
- setNotification(CS_DISABLED);
- } else if (newRs.isCsRestricted()) {
- // enable all restriction
- setNotification(CS_ENABLED);
- } else if (newRs.isCsEmergencyRestricted()) {
- // remove normal restriction and enable emergency restriction
- setNotification(CS_EMERGENCY_ENABLED);
- }
- } else {
- if (newRs.isCsRestricted()) {
- // enable all restriction
- setNotification(CS_ENABLED);
- } else if (newRs.isCsEmergencyRestricted()) {
- // enable emergency restriction
- setNotification(CS_EMERGENCY_ENABLED);
- } else if (newRs.isCsNormalRestricted()) {
- // enable normal restriction
- setNotification(CS_NORMAL_ENABLED);
- }
- }
-
- mRestrictedState = newRs;
- }
- log("onRestrictedStateChanged: X rs "+ mRestrictedState);
- }
-
- /** code is registration state 0-5 from TS 27.007 7.2 */
- private int regCodeToServiceState(int code) {
- switch (code) {
- case 0:
- case 2: // 2 is "searching"
- case 3: // 3 is "registration denied"
- case 4: // 4 is "unknown" no vaild in current baseband
- case 10:// same as 0, but indicates that emergency call is possible.
- case 12:// same as 2, but indicates that emergency call is possible.
- case 13:// same as 3, but indicates that emergency call is possible.
- case 14:// same as 4, but indicates that emergency call is possible.
- return ServiceState.STATE_OUT_OF_SERVICE;
-
- case 1:
- return ServiceState.STATE_IN_SERVICE;
-
- case 5:
- // in service, roam
- return ServiceState.STATE_IN_SERVICE;
-
- default:
- loge("regCodeToServiceState: unexpected service state " + code);
- return ServiceState.STATE_OUT_OF_SERVICE;
- }
- }
-
-
- /**
- * code is registration state 0-5 from TS 27.007 7.2
- * returns true if registered roam, false otherwise
- */
- private boolean regCodeIsRoaming (int code) {
- // 5 is "in service -- roam"
- return 5 == code;
- }
-
- /**
- * Set roaming state when gsmRoaming is true and, if operator mcc is the
- * same as sim mcc, ons is different from spn
- * @param gsmRoaming TS 27.007 7.2 CREG registered roaming
- * @param s ServiceState hold current ons
- * @return true for roaming state set
- */
- private boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
- String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
-
- String onsl = s.getOperatorAlphaLong();
- String onss = s.getOperatorAlphaShort();
-
- boolean equalsOnsl = onsl != null && spn.equals(onsl);
- boolean equalsOnss = onss != null && spn.equals(onss);
-
- String simNumeric = SystemProperties.get(
- TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
- String operatorNumeric = s.getOperatorNumeric();
-
- boolean equalsMcc = true;
- try {
- equalsMcc = simNumeric.substring(0, 3).
- equals(operatorNumeric.substring(0, 3));
- } catch (Exception e){
- }
-
- return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss));
- }
-
- private static int twoDigitsAt(String s, int offset) {
- int a, b;
-
- a = Character.digit(s.charAt(offset), 10);
- b = Character.digit(s.charAt(offset+1), 10);
-
- if (a < 0 || b < 0) {
-
- throw new RuntimeException("invalid format");
- }
-
- return a*10 + b;
- }
-
- /**
- * @return The current GPRS state. IN_SERVICE is the same as "attached"
- * and OUT_OF_SERVICE is the same as detached.
- */
- int getCurrentGprsState() {
- return gprsState;
- }
-
- public int getCurrentDataConnectionState() {
- return gprsState;
- }
-
- /**
- * @return true if phone is camping on a technology (eg UMTS)
- * that could support voice and data simultaneously.
- */
- public boolean isConcurrentVoiceAndDataAllowed() {
- return (mRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
- }
-
- /**
- * Provides the name of the algorithmic time zone for the specified
- * offset. Taken from TimeZone.java.
- */
- private static String displayNameFor(int off) {
- off = off / 1000 / 60;
-
- char[] buf = new char[9];
- buf[0] = 'G';
- buf[1] = 'M';
- buf[2] = 'T';
-
- if (off < 0) {
- buf[3] = '-';
- off = -off;
- } else {
- buf[3] = '+';
- }
-
- int hours = off / 60;
- int minutes = off % 60;
-
- buf[4] = (char) ('0' + hours / 10);
- buf[5] = (char) ('0' + hours % 10);
-
- buf[6] = ':';
-
- buf[7] = (char) ('0' + minutes / 10);
- buf[8] = (char) ('0' + minutes % 10);
-
- return new String(buf);
- }
-
- /**
- * nitzReceiveTime is time_t that the NITZ time was posted
- */
- private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
- // "yy/mm/dd,hh:mm:ss(+/-)tz"
- // tz is in number of quarter-hours
-
- long start = SystemClock.elapsedRealtime();
- if (DBG) {log("NITZ: " + nitz + "," + nitzReceiveTime +
- " start=" + start + " delay=" + (start - nitzReceiveTime));
- }
-
- try {
- /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
- * offset as well (which we won't worry about until later) */
- Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
-
- c.clear();
- c.set(Calendar.DST_OFFSET, 0);
-
- String[] nitzSubs = nitz.split("[/:,+-]");
-
- int year = 2000 + Integer.parseInt(nitzSubs[0]);
- c.set(Calendar.YEAR, year);
-
- // month is 0 based!
- int month = Integer.parseInt(nitzSubs[1]) - 1;
- c.set(Calendar.MONTH, month);
-
- int date = Integer.parseInt(nitzSubs[2]);
- c.set(Calendar.DATE, date);
-
- int hour = Integer.parseInt(nitzSubs[3]);
- c.set(Calendar.HOUR, hour);
-
- int minute = Integer.parseInt(nitzSubs[4]);
- c.set(Calendar.MINUTE, minute);
-
- int second = Integer.parseInt(nitzSubs[5]);
- c.set(Calendar.SECOND, second);
-
- boolean sign = (nitz.indexOf('-') == -1);
-
- int tzOffset = Integer.parseInt(nitzSubs[6]);
-
- int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7])
- : 0;
-
- // The zone offset received from NITZ is for current local time,
- // so DST correction is already applied. Don't add it again.
- //
- // tzOffset += dst * 4;
- //
- // We could unapply it if we wanted the raw offset.
-
- tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000;
-
- TimeZone zone = null;
-
- // As a special extension, the Android emulator appends the name of
- // the host computer's timezone to the nitz string. this is zoneinfo
- // timezone name of the form Area!Location or Area!Location!SubLocation
- // so we need to convert the ! into /
- if (nitzSubs.length >= 9) {
- String tzname = nitzSubs[8].replace('!','/');
- zone = TimeZone.getTimeZone( tzname );
- }
-
- String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
-
- if (zone == null) {
-
- if (mGotCountryCode) {
- if (iso != null && iso.length() > 0) {
- zone = TimeUtils.getTimeZone(tzOffset, dst != 0,
- c.getTimeInMillis(),
- iso);
- } else {
- // We don't have a valid iso country code. This is
- // most likely because we're on a test network that's
- // using a bogus MCC (eg, "001"), so get a TimeZone
- // based only on the NITZ parameters.
- zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis());
- }
- }
- }
-
- if ((zone == null) || (mZoneOffset != tzOffset) || (mZoneDst != (dst != 0))){
- // We got the time before the country or the zone has changed
- // so we don't know how to identify the DST rules yet. Save
- // the information and hope to fix it up later.
-
- mNeedFixZoneAfterNitz = true;
- mZoneOffset = tzOffset;
- mZoneDst = dst != 0;
- mZoneTime = c.getTimeInMillis();
- }
-
- if (zone != null) {
- if (getAutoTimeZone()) {
- setAndBroadcastNetworkSetTimeZone(zone.getID());
- }
- saveNitzTimeZone(zone.getID());
- }
-
- String ignore = SystemProperties.get("gsm.ignore-nitz");
- if (ignore != null && ignore.equals("yes")) {
- log("NITZ: Not setting clock because gsm.ignore-nitz is set");
- return;
- }
-
- try {
- mWakeLock.acquire();
-
- if (getAutoTime()) {
- long millisSinceNitzReceived
- = SystemClock.elapsedRealtime() - nitzReceiveTime;
-
- if (millisSinceNitzReceived < 0) {
- // Sanity check: something is wrong
- if (DBG) {
- log("NITZ: not setting time, clock has rolled "
- + "backwards since NITZ time was received, "
- + nitz);
- }
- return;
- }
-
- if (millisSinceNitzReceived > Integer.MAX_VALUE) {
- // If the time is this far off, something is wrong > 24 days!
- if (DBG) {
- log("NITZ: not setting time, processing has taken "
- + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
- + " days");
- }
- return;
- }
-
- // Note: with range checks above, cast to int is safe
- c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
-
- if (DBG) {
- log("NITZ: Setting time of day to " + c.getTime()
- + " NITZ receive delay(ms): " + millisSinceNitzReceived
- + " gained(ms): "
- + (c.getTimeInMillis() - System.currentTimeMillis())
- + " from " + nitz);
- }
-
- setAndBroadcastNetworkSetTime(c.getTimeInMillis());
- Log.i(LOG_TAG, "NITZ: after Setting time of day");
- }
- SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
- saveNitzTime(c.getTimeInMillis());
- if (false) {
- long end = SystemClock.elapsedRealtime();
- log("NITZ: end=" + end + " dur=" + (end - start));
- }
- mNitzUpdatedTime = true;
- } finally {
- mWakeLock.release();
- }
- } catch (RuntimeException ex) {
- loge("NITZ: Parsing NITZ time " + nitz + " ex=" + ex);
- }
- }
-
- private boolean getAutoTime() {
- try {
- return Settings.System.getInt(phone.getContext().getContentResolver(),
- Settings.System.AUTO_TIME) > 0;
- } catch (SettingNotFoundException snfe) {
- return true;
- }
- }
-
- private boolean getAutoTimeZone() {
- try {
- return Settings.System.getInt(phone.getContext().getContentResolver(),
- Settings.System.AUTO_TIME_ZONE) > 0;
- } catch (SettingNotFoundException snfe) {
- return true;
- }
- }
-
- private void saveNitzTimeZone(String zoneId) {
- mSavedTimeZone = zoneId;
- }
-
- private void saveNitzTime(long time) {
- mSavedTime = time;
- mSavedAtTime = SystemClock.elapsedRealtime();
- }
-
- /**
- * Set the timezone and send out a sticky broadcast so the system can
- * determine if the timezone was set by the carrier.
- *
- * @param zoneId timezone set by carrier
- */
- private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
- if (DBG) log("setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
- AlarmManager alarm =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
- alarm.setTimeZone(zoneId);
- Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra("time-zone", zoneId);
- phone.getContext().sendStickyBroadcast(intent);
- if (DBG) {
- log("setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast zoneId=" +
- zoneId);
- }
- }
-
- /**
- * Set the time and Send out a sticky broadcast so the system can determine
- * if the time was set by the carrier.
- *
- * @param time time set by network
- */
- private void setAndBroadcastNetworkSetTime(long time) {
- if (DBG) log("setAndBroadcastNetworkSetTime: time=" + time + "ms");
- SystemClock.setCurrentTimeMillis(time);
- Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra("time", time);
- phone.getContext().sendStickyBroadcast(intent);
- }
-
- private void revertToNitzTime() {
- if (Settings.System.getInt(phone.getContext().getContentResolver(),
- Settings.System.AUTO_TIME, 0) == 0) {
- return;
- }
- if (DBG) {
- log("Reverting to NITZ Time: mSavedTime=" + mSavedTime
- + " mSavedAtTime=" + mSavedAtTime);
- }
- if (mSavedTime != 0 && mSavedAtTime != 0) {
- setAndBroadcastNetworkSetTime(mSavedTime
- + (SystemClock.elapsedRealtime() - mSavedAtTime));
- }
- }
-
- private void revertToNitzTimeZone() {
- if (Settings.System.getInt(phone.getContext().getContentResolver(),
- Settings.System.AUTO_TIME_ZONE, 0) == 0) {
- return;
- }
- if (DBG) log("Reverting to NITZ TimeZone: tz='" + mSavedTimeZone);
- if (mSavedTimeZone != null) {
- setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);
- }
- }
-
- /**
- * Post a notification to NotificationManager for restricted state
- *
- * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE
- */
- private void setNotification(int notifyType) {
-
- if (DBG) log("setNotification: create notification " + notifyType);
- Context context = phone.getContext();
-
- mNotification = new Notification();
- mNotification.when = System.currentTimeMillis();
- mNotification.flags = Notification.FLAG_AUTO_CANCEL;
- mNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
- Intent intent = new Intent();
- mNotification.contentIntent = PendingIntent
- .getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-
- CharSequence details = "";
- CharSequence title = context.getText(com.android.internal.R.string.RestrictedChangedTitle);
- int notificationId = CS_NOTIFICATION;
-
- switch (notifyType) {
- case PS_ENABLED:
- notificationId = PS_NOTIFICATION;
- details = context.getText(com.android.internal.R.string.RestrictedOnData);;
- break;
- case PS_DISABLED:
- notificationId = PS_NOTIFICATION;
- break;
- case CS_ENABLED:
- details = context.getText(com.android.internal.R.string.RestrictedOnAllVoice);;
- break;
- case CS_NORMAL_ENABLED:
- details = context.getText(com.android.internal.R.string.RestrictedOnNormal);;
- break;
- case CS_EMERGENCY_ENABLED:
- details = context.getText(com.android.internal.R.string.RestrictedOnEmergency);;
- break;
- case CS_DISABLED:
- // do nothing and cancel the notification later
- break;
- }
-
- if (DBG) log("setNotification: put notification " + title + " / " +details);
- mNotification.tickerText = title;
- mNotification.setLatestEventInfo(context, title, details,
- mNotification.contentIntent);
-
- NotificationManager notificationManager = (NotificationManager)
- context.getSystemService(Context.NOTIFICATION_SERVICE);
-
- if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
- // cancel previous post notification
- notificationManager.cancel(notificationId);
- } else {
- // update restricted state notification
- notificationManager.notify(notificationId, mNotification);
- }
- }
-
- @Override
- protected void log(String s) {
- Log.d(LOG_TAG, "[GsmSST] " + s);
- }
-
- @Override
- protected void loge(String s) {
- Log.e(LOG_TAG, "[GsmSST] " + s);
- }
-
- private static void sloge(String s) {
- Log.e(LOG_TAG, "[GsmSST] " + s);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("GsmServiceStateTracker extends:");
- super.dump(fd, pw, args);
- pw.println(" phone=" + phone);
- pw.println(" cellLoc=" + cellLoc);
- pw.println(" newCellLoc=" + newCellLoc);
- pw.println(" mPreferredNetworkType=" + mPreferredNetworkType);
- pw.println(" gprsState=" + gprsState);
- pw.println(" newGPRSState=" + newGPRSState);
- pw.println(" mMaxDataCalls=" + mMaxDataCalls);
- pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls);
- pw.println(" mReasonDataDenied=" + mReasonDataDenied);
- pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied);
- pw.println(" mGsmRoaming=" + mGsmRoaming);
- pw.println(" mDataRoaming=" + mDataRoaming);
- pw.println(" mEmergencyOnly=" + mEmergencyOnly);
- pw.println(" mNeedFixZoneAfterNitz=" + mNeedFixZoneAfterNitz);
- pw.println(" mZoneOffset=" + mZoneOffset);
- pw.println(" mZoneDst=" + mZoneDst);
- pw.println(" mZoneTime=" + mZoneTime);
- pw.println(" mGotCountryCode=" + mGotCountryCode);
- pw.println(" mNitzUpdatedTime=" + mNitzUpdatedTime);
- pw.println(" mSavedTimeZone=" + mSavedTimeZone);
- pw.println(" mSavedTime=" + mSavedTime);
- pw.println(" mSavedAtTime=" + mSavedAtTime);
- pw.println(" mNeedToRegForSimLoaded=" + mNeedToRegForSimLoaded);
- pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck);
- pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg);
- pw.println(" mNotification=" + mNotification);
- pw.println(" mWakeLock=" + mWakeLock);
- pw.println(" curSpn=" + curSpn);
- pw.println(" curPlmn=" + curPlmn);
- pw.println(" curSpnRule=" + curSpnRule);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
deleted file mode 100644
index c163803..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsAddress.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.gsm;
-
-import android.telephony.PhoneNumberUtils;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.SmsAddress;
-
-public class GsmSmsAddress extends SmsAddress {
-
- static final int OFFSET_ADDRESS_LENGTH = 0;
-
- static final int OFFSET_TOA = 1;
-
- static final int OFFSET_ADDRESS_VALUE = 2;
-
- /**
- * New GsmSmsAddress from TS 23.040 9.1.2.5 Address Field
- *
- * @param offset the offset of the Address-Length byte
- * @param length the length in bytes rounded up, e.g. "2 +
- * (addressLength + 1) / 2"
- */
-
- public GsmSmsAddress(byte[] data, int offset, int length) {
- origBytes = new byte[length];
- System.arraycopy(data, offset, origBytes, 0, length);
-
- // addressLength is the count of semi-octets, not bytes
- int addressLength = origBytes[OFFSET_ADDRESS_LENGTH] & 0xff;
-
- int toa = origBytes[OFFSET_TOA] & 0xff;
- ton = 0x7 & (toa >> 4);
-
- // TOA must have its high bit set
- if ((toa & 0x80) != 0x80) {
- throw new RuntimeException("Invalid TOA - high bit must be set");
- }
-
- if (isAlphanumeric()) {
- // An alphanumeric address
- int countSeptets = addressLength * 4 / 7;
-
- address = GsmAlphabet.gsm7BitPackedToString(origBytes,
- OFFSET_ADDRESS_VALUE, countSeptets);
- } else {
- // TS 23.040 9.1.2.5 says
- // that "the MS shall interpret reserved values as 'Unknown'
- // but shall store them exactly as received"
-
- byte lastByte = origBytes[length - 1];
-
- if ((addressLength & 1) == 1) {
- // Make sure the final unused BCD digit is 0xf
- origBytes[length - 1] |= 0xf0;
- }
- address = PhoneNumberUtils.calledPartyBCDToString(origBytes,
- OFFSET_TOA, length - OFFSET_TOA);
-
- // And restore origBytes
- origBytes[length - 1] = lastByte;
- }
- }
-
- public String getAddressString() {
- return address;
- }
-
- /**
- * Returns true if this is an alphanumeric address
- */
- public boolean isAlphanumeric() {
- return ton == TON_ALPHANUMERIC;
- }
-
- public boolean isNetworkSpecific() {
- return ton == TON_NETWORK;
- }
-
- /**
- * Returns true of this is a valid CPHS voice message waiting indicator
- * address
- */
- public boolean isCphsVoiceMessageIndicatorAddress() {
- // CPHS-style MWI message
- // See CPHS 4.7 B.4.2.1
- //
- // Basically:
- //
- // - Originating address should be 4 bytes long and alphanumeric
- // - Decode will result with two chars:
- // - Char 1
- // 76543210
- // ^ set/clear indicator (0 = clear)
- // ^^^ type of indicator (000 = voice)
- // ^^^^ must be equal to 0001
- // - Char 2:
- // 76543210
- // ^ line number (0 = line 1)
- // ^^^^^^^ set to 0
- //
- // Remember, since the alpha address is stored in 7-bit compact form,
- // the "line number" is really the top bit of the first address value
- // byte
-
- return (origBytes[OFFSET_ADDRESS_LENGTH] & 0xff) == 4
- && isAlphanumeric() && (origBytes[OFFSET_TOA] & 0x0f) == 0;
- }
-
- /**
- * Returns true if this is a valid CPHS voice message waiting indicator
- * address indicating a "set" of "indicator 1" of type "voice message
- * waiting"
- */
- public boolean isCphsVoiceMessageSet() {
- // 0x11 means "set" "voice message waiting" "indicator 1"
- return isCphsVoiceMessageIndicatorAddress()
- && (origBytes[OFFSET_ADDRESS_VALUE] & 0xff) == 0x11;
-
- }
-
- /**
- * Returns true if this is a valid CPHS voice message waiting indicator
- * address indicating a "clear" of "indicator 1" of type "voice message
- * waiting"
- */
- public boolean isCphsVoiceMessageClear() {
- // 0x10 means "clear" "voice message waiting" "indicator 1"
- return isCphsVoiceMessageIndicatorAddress()
- && (origBytes[OFFSET_ADDRESS_VALUE] & 0xff) == 0x10;
-
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
deleted file mode 100644
index dc9554a..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.gsm;
-
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.util.Pair;
-
-import com.android.internal.telephony.GsmAlphabet;
-
-import java.io.UnsupportedEncodingException;
-
-/**
- * Parses a GSM or UMTS format SMS-CB message into an {@link SmsCbMessage} object. The class is
- * public because {@link #createSmsCbMessage(SmsCbLocation, byte[][])} is used by some test cases.
- */
-public class GsmSmsCbMessage {
-
- /**
- * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5.
- */
- private static final String[] LANGUAGE_CODES_GROUP_0 = {
- "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", "tr", "hu",
- "pl", null
- };
-
- /**
- * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5.
- */
- private static final String[] LANGUAGE_CODES_GROUP_2 = {
- "cs", "he", "ar", "ru", "is", null, null, null, null, null, null, null, null, null,
- null, null
- };
-
- private static final char CARRIAGE_RETURN = 0x0d;
-
- private static final int PDU_BODY_PAGE_LENGTH = 82;
-
- /** Utility class with only static methods. */
- private GsmSmsCbMessage() { }
-
- /**
- * Create a new SmsCbMessage object from a header object plus one or more received PDUs.
- *
- * @param pdus PDU bytes
- */
- static SmsCbMessage createSmsCbMessage(SmsCbHeader header, SmsCbLocation location,
- byte[][] pdus) throws IllegalArgumentException {
- if (header.isEtwsPrimaryNotification()) {
- return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
- header.getGeographicalScope(), header.getSerialNumber(),
- location, header.getServiceCategory(),
- null, "ETWS", SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY,
- header.getEtwsInfo(), header.getCmasInfo());
- } else {
- String language = null;
- StringBuilder sb = new StringBuilder();
- for (byte[] pdu : pdus) {
- Pair<String, String> p = parseBody(header, pdu);
- language = p.first;
- sb.append(p.second);
- }
- int priority = header.isEmergencyMessage() ? SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY
- : SmsCbMessage.MESSAGE_PRIORITY_NORMAL;
-
- return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
- header.getGeographicalScope(), header.getSerialNumber(), location,
- header.getServiceCategory(), language, sb.toString(), priority,
- header.getEtwsInfo(), header.getCmasInfo());
- }
- }
-
- /**
- * Create a new SmsCbMessage object from one or more received PDUs. This is used by some
- * CellBroadcastReceiver test cases, because SmsCbHeader is now package local.
- *
- * @param location the location (geographical scope) for the message
- * @param pdus PDU bytes
- */
- public static SmsCbMessage createSmsCbMessage(SmsCbLocation location, byte[][] pdus)
- throws IllegalArgumentException {
- SmsCbHeader header = new SmsCbHeader(pdus[0]);
- return createSmsCbMessage(header, location, pdus);
- }
-
- /**
- * Parse and unpack the body text according to the encoding in the DCS.
- * After completing successfully this method will have assigned the body
- * text into mBody, and optionally the language code into mLanguage
- *
- * @param header the message header to use
- * @param pdu the PDU to decode
- * @return a Pair of Strings containing the language and body of the message
- */
- private static Pair<String, String> parseBody(SmsCbHeader header, byte[] pdu) {
- int encoding;
- String language = null;
- boolean hasLanguageIndicator = false;
- int dataCodingScheme = header.getDataCodingScheme();
-
- // Extract encoding and language from DCS, as defined in 3gpp TS 23.038,
- // section 5.
- switch ((dataCodingScheme & 0xf0) >> 4) {
- case 0x00:
- encoding = android.telephony.SmsMessage.ENCODING_7BIT;
- language = LANGUAGE_CODES_GROUP_0[dataCodingScheme & 0x0f];
- break;
-
- case 0x01:
- hasLanguageIndicator = true;
- if ((dataCodingScheme & 0x0f) == 0x01) {
- encoding = android.telephony.SmsMessage.ENCODING_16BIT;
- } else {
- encoding = android.telephony.SmsMessage.ENCODING_7BIT;
- }
- break;
-
- case 0x02:
- encoding = android.telephony.SmsMessage.ENCODING_7BIT;
- language = LANGUAGE_CODES_GROUP_2[dataCodingScheme & 0x0f];
- break;
-
- case 0x03:
- encoding = android.telephony.SmsMessage.ENCODING_7BIT;
- break;
-
- case 0x04:
- case 0x05:
- switch ((dataCodingScheme & 0x0c) >> 2) {
- case 0x01:
- encoding = android.telephony.SmsMessage.ENCODING_8BIT;
- break;
-
- case 0x02:
- encoding = android.telephony.SmsMessage.ENCODING_16BIT;
- break;
-
- case 0x00:
- default:
- encoding = android.telephony.SmsMessage.ENCODING_7BIT;
- break;
- }
- break;
-
- case 0x06:
- case 0x07:
- // Compression not supported
- case 0x09:
- // UDH structure not supported
- case 0x0e:
- // Defined by the WAP forum not supported
- throw new IllegalArgumentException("Unsupported GSM dataCodingScheme "
- + dataCodingScheme);
-
- case 0x0f:
- if (((dataCodingScheme & 0x04) >> 2) == 0x01) {
- encoding = android.telephony.SmsMessage.ENCODING_8BIT;
- } else {
- encoding = android.telephony.SmsMessage.ENCODING_7BIT;
- }
- break;
-
- default:
- // Reserved values are to be treated as 7-bit
- encoding = android.telephony.SmsMessage.ENCODING_7BIT;
- break;
- }
-
- if (header.isUmtsFormat()) {
- // Payload may contain multiple pages
- int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH];
-
- if (pdu.length < SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1)
- * nrPages) {
- throw new IllegalArgumentException("Pdu length " + pdu.length + " does not match "
- + nrPages + " pages");
- }
-
- StringBuilder sb = new StringBuilder();
-
- for (int i = 0; i < nrPages; i++) {
- // Each page is 82 bytes followed by a length octet indicating
- // the number of useful octets within those 82
- int offset = SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) * i;
- int length = pdu[offset + PDU_BODY_PAGE_LENGTH];
-
- if (length > PDU_BODY_PAGE_LENGTH) {
- throw new IllegalArgumentException("Page length " + length
- + " exceeds maximum value " + PDU_BODY_PAGE_LENGTH);
- }
-
- Pair<String, String> p = unpackBody(pdu, encoding, offset, length,
- hasLanguageIndicator, language);
- language = p.first;
- sb.append(p.second);
- }
- return new Pair<String, String>(language, sb.toString());
- } else {
- // Payload is one single page
- int offset = SmsCbHeader.PDU_HEADER_LENGTH;
- int length = pdu.length - offset;
-
- return unpackBody(pdu, encoding, offset, length, hasLanguageIndicator, language);
- }
- }
-
- /**
- * Unpack body text from the pdu using the given encoding, position and
- * length within the pdu
- *
- * @param pdu The pdu
- * @param encoding The encoding, as derived from the DCS
- * @param offset Position of the first byte to unpack
- * @param length Number of bytes to unpack
- * @param hasLanguageIndicator true if the body text is preceded by a
- * language indicator. If so, this method will as a side-effect
- * assign the extracted language code into mLanguage
- * @param language the language to return if hasLanguageIndicator is false
- * @return a Pair of Strings containing the language and body of the message
- */
- private static Pair<String, String> unpackBody(byte[] pdu, int encoding, int offset, int length,
- boolean hasLanguageIndicator, String language) {
- String body = null;
-
- switch (encoding) {
- case android.telephony.SmsMessage.ENCODING_7BIT:
- body = GsmAlphabet.gsm7BitPackedToString(pdu, offset, length * 8 / 7);
-
- if (hasLanguageIndicator && body != null && body.length() > 2) {
- // Language is two GSM characters followed by a CR.
- // The actual body text is offset by 3 characters.
- language = body.substring(0, 2);
- body = body.substring(3);
- }
- break;
-
- case android.telephony.SmsMessage.ENCODING_16BIT:
- if (hasLanguageIndicator && pdu.length >= offset + 2) {
- // Language is two GSM characters.
- // The actual body text is offset by 2 bytes.
- language = GsmAlphabet.gsm7BitPackedToString(pdu, offset, 2);
- offset += 2;
- length -= 2;
- }
-
- try {
- body = new String(pdu, offset, (length & 0xfffe), "utf-16");
- } catch (UnsupportedEncodingException e) {
- // Apparently it wasn't valid UTF-16.
- throw new IllegalArgumentException("Error decoding UTF-16 message", e);
- }
- break;
-
- default:
- break;
- }
-
- if (body != null) {
- // Remove trailing carriage return
- for (int i = body.length() - 1; i >= 0; i--) {
- if (body.charAt(i) != CARRIAGE_RETURN) {
- body = body.substring(0, i + 1);
- break;
- }
- }
- } else {
- body = "";
- }
-
- return new Pair<String, String>(language, body);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
deleted file mode 100644
index dcc9cfd..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.gsm;
-
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCardApplication;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.PhoneBase;
-
-/**
- * {@hide}
- */
-public final class SIMFileHandler extends IccFileHandler implements IccConstants {
- static final String LOG_TAG = "GSM";
-
- //***** Instance Variables
-
- //***** Constructor
-
- public SIMFileHandler(IccCard card, String aid, CommandsInterface ci) {
- super(card, aid, ci);
- }
-
- protected void finalize() {
- Log.d(LOG_TAG, "SIMFileHandler finalized");
- }
-
- //***** Overridden from IccFileHandler
-
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- }
-
- protected String getEFPath(int efid) {
- // TODO(): DF_GSM can be 7F20 or 7F21 to handle backward compatibility.
- // Implement this after discussion with OEMs.
- switch(efid) {
- case EF_SMS:
- return MF_SIM + DF_TELECOM;
-
- case EF_EXT6:
- case EF_MWIS:
- case EF_MBI:
- case EF_SPN:
- case EF_AD:
- case EF_MBDN:
- case EF_PNN:
- case EF_SPDI:
- case EF_SST:
- case EF_CFIS:
- return MF_SIM + DF_GSM;
-
- case EF_MAILBOX_CPHS:
- case EF_VOICE_MAIL_INDICATOR_CPHS:
- case EF_CFF_CPHS:
- case EF_SPN_CPHS:
- case EF_SPN_SHORT_CPHS:
- case EF_INFO_CPHS:
- case EF_CSP_CPHS:
- return MF_SIM + DF_GSM;
-
- case EF_PBR:
- // we only support global phonebook.
- return MF_SIM + DF_TELECOM + DF_PHONEBOOK;
- }
- String path = getCommonIccEFPath(efid);
- if (path == null) {
- // The EFids in USIM phone book entries are decided by the card manufacturer.
- // So if we don't match any of the cases above and if its a USIM return
- // the phone book path.
- if (mParentCard != null
- && mParentCard.isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) {
- return MF_SIM + DF_TELECOM + DF_PHONEBOOK;
- }
- Log.e(LOG_TAG, "Error: EF Path being returned in null");
- }
- return path;
- }
-
- protected void logd(String msg) {
- Log.d(LOG_TAG, "[SIMFileHandler] " + msg);
- }
-
- protected void loge(String msg) {
- Log.e(LOG_TAG, "[SIMFileHandler] " + msg);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
deleted file mode 100755
index 52e2caf..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ /dev/null
@@ -1,1674 +0,0 @@
-/*
- * 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.gsm;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.AdnRecordCache;
-import com.android.internal.telephony.AdnRecordLoader;
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccRecords;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.IccVmFixedException;
-import com.android.internal.telephony.IccVmNotSupportedException;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.SmsMessageBase;
-import com.android.internal.telephony.IccRefreshResponse;
-
-import java.util.ArrayList;
-
-
-/**
- * {@hide}
- */
-public class SIMRecords extends IccRecords {
- protected static final String LOG_TAG = "GSM";
-
- private static final boolean CRASH_RIL = false;
-
- protected static final boolean DBG = true;
-
- // ***** Instance Variables
-
- VoiceMailConstants mVmConfig;
-
-
- SpnOverride mSpnOverride;
-
- // ***** Cached SIM State; cleared on channel close
-
- private String imsi;
- private boolean callForwardingEnabled;
-
-
- /**
- * States only used by getSpnFsm FSM
- */
- private Get_Spn_Fsm_State spnState;
-
- /** CPHS service information (See CPHS 4.2 B.3.1.1)
- * It will be set in onSimReady if reading GET_CPHS_INFO successfully
- * mCphsInfo[0] is CPHS Phase
- * mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
- */
- private byte[] mCphsInfo = null;
- boolean mCspPlmnEnabled = true;
-
- byte[] efMWIS = null;
- byte[] efCPHS_MWI =null;
- byte[] mEfCff = null;
- byte[] mEfCfis = null;
-
-
- int spnDisplayCondition;
- // Numeric network codes listed in TS 51.011 EF[SPDI]
- ArrayList<String> spdiNetworks = null;
-
- String pnnHomeName = null;
-
- UsimServiceTable mUsimServiceTable;
-
- // ***** Constants
-
- // Bitmasks for SPN display rules.
- static final int SPN_RULE_SHOW_SPN = 0x01;
- static final int SPN_RULE_SHOW_PLMN = 0x02;
-
- // From TS 51.011 EF[SPDI] section
- static final int TAG_SPDI = 0xA3;
- static final int TAG_SPDI_PLMN_LIST = 0x80;
-
- // Full Name IEI from TS 24.008
- static final int TAG_FULL_NETWORK_NAME = 0x43;
-
- // Short Name IEI from TS 24.008
- static final int TAG_SHORT_NETWORK_NAME = 0x45;
-
- // active CFF from CPHS 4.2 B.4.5
- static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
- static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
- static final int CFF_LINE1_MASK = 0x0f;
- static final int CFF_LINE1_RESET = 0xf0;
-
- // CPHS Service Table (See CPHS 4.2 B.3.1)
- private static final int CPHS_SST_MBN_MASK = 0x30;
- private static final int CPHS_SST_MBN_ENABLED = 0x30;
-
- // ***** Event Constants
-
- private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
- protected static final int EVENT_GET_IMSI_DONE = 3;
- protected static final int EVENT_GET_ICCID_DONE = 4;
- private static final int EVENT_GET_MBI_DONE = 5;
- private static final int EVENT_GET_MBDN_DONE = 6;
- private static final int EVENT_GET_MWIS_DONE = 7;
- private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8;
- protected static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM
- protected static final int EVENT_GET_MSISDN_DONE = 10;
- private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11;
- private static final int EVENT_GET_SPN_DONE = 12;
- private static final int EVENT_GET_SPDI_DONE = 13;
- private static final int EVENT_UPDATE_DONE = 14;
- private static final int EVENT_GET_PNN_DONE = 15;
- protected static final int EVENT_GET_SST_DONE = 17;
- private static final int EVENT_GET_ALL_SMS_DONE = 18;
- private static final int EVENT_MARK_SMS_READ_DONE = 19;
- private static final int EVENT_SET_MBDN_DONE = 20;
- private static final int EVENT_SMS_ON_SIM = 21;
- private static final int EVENT_GET_SMS_DONE = 22;
- private static final int EVENT_GET_CFF_DONE = 24;
- private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25;
- private static final int EVENT_GET_INFO_CPHS_DONE = 26;
- private static final int EVENT_SET_MSISDN_DONE = 30;
- private static final int EVENT_SIM_REFRESH = 31;
- private static final int EVENT_GET_CFIS_DONE = 32;
- private static final int EVENT_GET_CSP_CPHS_DONE = 33;
-
- // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
-
- private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
- "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
- "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
- "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
- "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
- "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
- "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
- "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
- "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
- "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
- "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
- "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
- "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
- "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914",
- "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922",
- "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930",
- "405931", "405932"
- };
-
- // ***** Constructor
-
- public SIMRecords(IccCard card, Context c, CommandsInterface ci) {
- super(card, c, ci);
-
- adnCache = new AdnRecordCache(mFh);
-
- mVmConfig = new VoiceMailConstants();
- mSpnOverride = new SpnOverride();
-
- recordsRequested = false; // No load request is made till SIM ready
-
- // recordsToLoad is set to 0 because no requests are made yet
- recordsToLoad = 0;
-
- mCi.registerForOffOrNotAvailable(
- this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
- mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
-
- // Start off by setting empty state
- onRadioOffOrNotAvailable();
-
- }
-
- @Override
- public void dispose() {
- if (DBG) log("Disposing SIMRecords " + this);
- //Unregister for all events
- mCi.unregisterForOffOrNotAvailable( this);
- mCi.unregisterForIccRefresh(this);
- mCi.unSetOnSmsOnSim(this);
- super.dispose();
- }
-
- protected void finalize() {
- if(DBG) log("finalized");
- }
-
- protected void onRadioOffOrNotAvailable() {
- imsi = null;
- msisdn = null;
- voiceMailNum = null;
- countVoiceMessages = 0;
- mncLength = UNINITIALIZED;
- iccid = null;
- // -1 means no EF_SPN found; treat accordingly.
- spnDisplayCondition = -1;
- efMWIS = null;
- efCPHS_MWI = null;
- spdiNetworks = null;
- pnnHomeName = null;
-
- adnCache.reset();
-
- log("SIMRecords: onRadioOffOrNotAvailable set 'gsm.sim.operator.numeric' to operator=null");
- SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, null);
- SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, null);
- SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
-
- // recordsRequested is set to false indicating that the SIM
- // read requests made so far are not valid. This is set to
- // true only when fresh set of read requests are made.
- recordsRequested = false;
- }
-
-
- //***** Public Methods
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getIMSI() {
- return imsi;
- }
-
- public String getMsisdnNumber() {
- return msisdn;
- }
-
- @Override
- public UsimServiceTable getUsimServiceTable() {
- return mUsimServiceTable;
- }
-
- /**
- * 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*/ "xxxxxxx");
-
-
- AdnRecord adn = new AdnRecord(msisdnTag, msisdn);
-
- new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null,
- obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
- }
-
- public String getMsisdnAlphaTag() {
- return msisdnTag;
- }
-
- public String getVoiceMailNumber() {
- return voiceMailNum;
- }
-
- /**
- * 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 void setVoiceMailNumber(String alphaTag, String voiceNumber,
- Message onComplete) {
- if (isVoiceMailFixed) {
- AsyncResult.forMessage((onComplete)).exception =
- new IccVmFixedException("Voicemail number is fixed by operator");
- onComplete.sendToTarget();
- return;
- }
-
- newVoiceMailNum = voiceNumber;
- newVoiceMailTag = alphaTag;
-
- AdnRecord adn = new AdnRecord(newVoiceMailTag, newVoiceMailNum);
-
- if (mailboxIndex != 0 && mailboxIndex != 0xff) {
-
- new AdnRecordLoader(mFh).updateEF(adn, EF_MBDN, EF_EXT6,
- mailboxIndex, null,
- obtainMessage(EVENT_SET_MBDN_DONE, onComplete));
-
- } else if (isCphsMailboxEnabled()) {
-
- new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS,
- EF_EXT1, 1, null,
- obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete));
-
- } else {
- AsyncResult.forMessage((onComplete)).exception =
- new IccVmNotSupportedException("Update SIM voice mailbox error");
- onComplete.sendToTarget();
- }
- }
-
- 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 void
- setVoiceMessageWaiting(int line, int countWaiting) {
- if (line != 1) {
- // only profile 1 is supported
- return;
- }
-
- // range check
- if (countWaiting < 0) {
- countWaiting = -1;
- } else if (countWaiting > 0xff) {
- // TS 23.040 9.2.3.24.2
- // "The value 255 shall be taken to mean 255 or greater"
- countWaiting = 0xff;
- }
-
- countVoiceMessages = countWaiting;
-
- mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
-
- try {
- if (efMWIS != null) {
- // TS 51.011 10.3.45
-
- // lsb of byte 0 is 'voicemail' status
- efMWIS[0] = (byte)((efMWIS[0] & 0xfe)
- | (countVoiceMessages == 0 ? 0 : 1));
-
- // byte 1 is the number of voice messages waiting
- if (countWaiting < 0) {
- // The spec does not define what this should be
- // if we don't know the count
- efMWIS[1] = 0;
- } else {
- efMWIS[1] = (byte) countWaiting;
- }
-
- mFh.updateEFLinearFixed(
- EF_MWIS, 1, efMWIS, null,
- obtainMessage (EVENT_UPDATE_DONE, EF_MWIS));
- }
-
- if (efCPHS_MWI != null) {
- // Refer CPHS4_2.WW6 B4.2.3
- efCPHS_MWI[0] = (byte)((efCPHS_MWI[0] & 0xf0)
- | (countVoiceMessages == 0 ? 0x5 : 0xa));
-
- mFh.updateEFTransparent(
- EF_VOICE_MAIL_INDICATOR_CPHS, efCPHS_MWI,
- obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS));
- }
- } catch (ArrayIndexOutOfBoundsException ex) {
- logw("Error saving voice mail state to SIM. Probably malformed SIM record", ex);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean getVoiceCallForwardingFlag() {
- return callForwardingEnabled;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setVoiceCallForwardingFlag(int line, boolean enable) {
-
- if (line != 1) return; // only line 1 is supported
-
- callForwardingEnabled = enable;
-
- mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
-
- try {
- if (mEfCfis != null) {
- // lsb is of byte 1 is voice status
- if (enable) {
- mEfCfis[1] |= 1;
- } else {
- mEfCfis[1] &= 0xfe;
- }
-
- // TODO: Should really update other fields in EF_CFIS, eg,
- // dialing number. We don't read or use it right now.
-
- mFh.updateEFLinearFixed(
- EF_CFIS, 1, mEfCfis, null,
- obtainMessage (EVENT_UPDATE_DONE, EF_CFIS));
- }
-
- if (mEfCff != null) {
- if (enable) {
- mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
- | CFF_UNCONDITIONAL_ACTIVE);
- } else {
- mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
- | CFF_UNCONDITIONAL_DEACTIVE);
- }
-
- mFh.updateEFTransparent(
- EF_CFF_CPHS, mEfCff,
- obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
- }
- } catch (ArrayIndexOutOfBoundsException ex) {
- logw("Error saving call fowarding flag to SIM. "
- + "Probably malformed SIM record", ex);
-
- }
- }
-
- /**
- * 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 void onRefresh(boolean fileChanged, int[] fileList) {
- if (fileChanged) {
- // A future optimization would be to inspect fileList and
- // only reload those files that we care about. For now,
- // just re-fetch all SIM records that we cache.
- fetchSimRecords();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getOperatorNumeric() {
- if (imsi == null) {
- log("getOperatorNumeric: IMSI == null");
- return null;
- }
- if (mncLength == UNINITIALIZED || mncLength == UNKNOWN) {
- log("getSIMOperatorNumeric: bad mncLength");
- return null;
- }
-
- // Length = length of MCC + length of MNC
- // length of mcc = 3 (TS 23.003 Section 2.2)
- return imsi.substring(0, 3 + mncLength);
- }
-
- // ***** Overridden from Handler
- public void handleMessage(Message msg) {
- AsyncResult ar;
- AdnRecord adn;
-
- byte data[];
-
- boolean isRecordLoadResponse = false;
-
- if (mDestroyed) {
- loge("Received message " + msg + "[" + msg.what + "] " +
- " while being destroyed. Ignoring.");
- return;
- }
-
- try { switch (msg.what) {
- case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
- onRadioOffOrNotAvailable();
- break;
-
- /* IO events */
- case EVENT_GET_IMSI_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- loge("Exception querying IMSI, Exception:" + ar.exception);
- break;
- }
-
- imsi = (String) ar.result;
-
- // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
- // than 15 (and usually 15).
- if (imsi != null && (imsi.length() < 6 || imsi.length() > 15)) {
- loge("invalid IMSI " + imsi);
- imsi = null;
- }
-
- log("IMSI: " + /* imsi.substring(0, 6) +*/ "xxxxxxx");
-
- if (((mncLength == UNKNOWN) || (mncLength == 2)) &&
- ((imsi != null) && (imsi.length() >= 6))) {
- String mccmncCode = imsi.substring(0, 6);
- for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
- if (mccmnc.equals(mccmncCode)) {
- mncLength = 3;
- break;
- }
- }
- }
-
- if (mncLength == UNKNOWN) {
- // the SIM has told us all it knows, but it didn't know the mnc length.
- // guess using the mcc
- try {
- int mcc = Integer.parseInt(imsi.substring(0,3));
- mncLength = MccTable.smallestDigitsMccForMnc(mcc);
- } catch (NumberFormatException e) {
- mncLength = UNKNOWN;
- loge("Corrupt IMSI!");
- }
- }
-
- if (mncLength != UNKNOWN && mncLength != UNINITIALIZED) {
- // finally have both the imsi and the mncLength and can parse the imsi properly
- MccTable.updateMccMncConfiguration(mContext, imsi.substring(0, 3 + mncLength));
- }
- mParentCard.broadcastIccStateChangedIntent(
- IccCard.INTENT_VALUE_ICC_IMSI, null);
- break;
-
- case EVENT_GET_MBI_DONE:
- boolean isValidMbdn;
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[]) ar.result;
-
- isValidMbdn = false;
- if (ar.exception == null) {
- // Refer TS 51.011 Section 10.3.44 for content details
- log("EF_MBI: " + IccUtils.bytesToHexString(data));
-
- // Voice mail record number stored first
- mailboxIndex = (int)data[0] & 0xff;
-
- // check if dailing numbe id valid
- if (mailboxIndex != 0 && mailboxIndex != 0xff) {
- log("Got valid mailbox number for MBDN");
- isValidMbdn = true;
- }
- }
-
- // one more record to load
- recordsToLoad += 1;
-
- if (isValidMbdn) {
- // Note: MBDN was not included in NUM_OF_SIM_RECORDS_LOADED
- new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
- mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
- } else {
- // If this EF not present, try mailbox as in CPHS standard
- // CPHS (CPHS4_2.WW6) is a european standard.
- new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS,
- EF_EXT1, 1,
- obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
- }
-
- break;
- case EVENT_GET_CPHS_MAILBOX_DONE:
- case EVENT_GET_MBDN_DONE:
- //Resetting the voice mail number and voice mail tag to null
- //as these should be updated from the data read from EF_MBDN.
- //If they are not reset, incase of invalid data/exception these
- //variables are retaining their previous values and are
- //causing invalid voice mailbox info display to user.
- voiceMailNum = null;
- voiceMailTag = null;
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
-
- log("Invalid or missing EF"
- + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]"));
-
- // Bug #645770 fall back to CPHS
- // FIXME should use SST to decide
-
- if (msg.what == EVENT_GET_MBDN_DONE) {
- //load CPHS on fail...
- // FIXME right now, only load line1's CPHS voice mail entry
-
- recordsToLoad += 1;
- new AdnRecordLoader(mFh).loadFromEF(
- EF_MAILBOX_CPHS, EF_EXT1, 1,
- obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
- }
- break;
- }
-
- adn = (AdnRecord)ar.result;
-
- log("VM: " + adn +
- ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
-
- if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) {
- // Bug #645770 fall back to CPHS
- // FIXME should use SST to decide
- // FIXME right now, only load line1's CPHS voice mail entry
- recordsToLoad += 1;
- new AdnRecordLoader(mFh).loadFromEF(
- EF_MAILBOX_CPHS, EF_EXT1, 1,
- obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
-
- break;
- }
-
- voiceMailNum = adn.getNumber();
- voiceMailTag = adn.getAlphaTag();
- break;
-
- case EVENT_GET_MSISDN_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- log("Invalid or missing EF[MSISDN]");
- break;
- }
-
- adn = (AdnRecord)ar.result;
-
- msisdn = adn.getNumber();
- msisdnTag = adn.getAlphaTag();
-
- log("MSISDN: " + /*msisdn*/ "xxxxxxx");
- break;
-
- case EVENT_SET_MSISDN_DONE:
- isRecordLoadResponse = false;
- ar = (AsyncResult)msg.obj;
-
- if (ar.userObj != null) {
- AsyncResult.forMessage(((Message) ar.userObj)).exception
- = ar.exception;
- ((Message) ar.userObj).sendToTarget();
- }
- break;
-
- case EVENT_GET_MWIS_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- log("EF_MWIS: " + IccUtils.bytesToHexString(data));
-
- efMWIS = data;
-
- if ((data[0] & 0xff) == 0xff) {
- log("Uninitialized record MWIS");
- break;
- }
-
- // Refer TS 51.011 Section 10.3.45 for the content description
- boolean voiceMailWaiting = ((data[0] & 0x01) != 0);
- countVoiceMessages = data[1] & 0xff;
-
- if (voiceMailWaiting && countVoiceMessages == 0) {
- // Unknown count = -1
- countVoiceMessages = -1;
- }
-
- mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
- break;
-
- case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- efCPHS_MWI = data;
-
- // Use this data if the EF[MWIS] exists and
- // has been loaded
-
- if (efMWIS == null) {
- int indicator = (int)(data[0] & 0xf);
-
- // Refer CPHS4_2.WW6 B4.2.3
- if (indicator == 0xA) {
- // Unknown count = -1
- countVoiceMessages = -1;
- } else if (indicator == 0x5) {
- countVoiceMessages = 0;
- }
-
- mRecordsEventsRegistrants.notifyResult(EVENT_MWI);
- }
- break;
-
- case EVENT_GET_ICCID_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- iccid = IccUtils.bcdToString(data, 0, data.length);
-
- log("iccid: " + iccid);
-
- break;
-
-
- case EVENT_GET_AD_DONE:
- try {
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- log("EF_AD: " + IccUtils.bytesToHexString(data));
-
- if (data.length < 3) {
- log("Corrupt AD data on SIM");
- break;
- }
-
- if (data.length == 3) {
- log("MNC length not present in EF_AD");
- break;
- }
-
- mncLength = (int)data[3] & 0xf;
-
- if (mncLength == 0xf) {
- mncLength = UNKNOWN;
- }
- } finally {
- if (((mncLength == UNINITIALIZED) || (mncLength == UNKNOWN) ||
- (mncLength == 2)) && ((imsi != null) && (imsi.length() >= 6))) {
- String mccmncCode = imsi.substring(0, 6);
- for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
- if (mccmnc.equals(mccmncCode)) {
- mncLength = 3;
- break;
- }
- }
- }
-
- if (mncLength == UNKNOWN || mncLength == UNINITIALIZED) {
- if (imsi != null) {
- try {
- int mcc = Integer.parseInt(imsi.substring(0,3));
-
- mncLength = MccTable.smallestDigitsMccForMnc(mcc);
- } catch (NumberFormatException e) {
- mncLength = UNKNOWN;
- loge("Corrupt IMSI!");
- }
- } else {
- // Indicate we got this info, but it didn't contain the length.
- mncLength = UNKNOWN;
-
- log("MNC length not present in EF_AD");
- }
- }
- if (imsi != null && mncLength != UNKNOWN) {
- // finally have both imsi and the length of the mnc and can parse
- // the imsi properly
- MccTable.updateMccMncConfiguration(mContext,
- imsi.substring(0, 3 + mncLength));
- }
- }
- break;
-
- case EVENT_GET_SPN_DONE:
- isRecordLoadResponse = true;
- ar = (AsyncResult) msg.obj;
- getSpnFsm(false, ar);
- break;
-
- case EVENT_GET_CFF_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult) msg.obj;
- data = (byte[]) ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
- mEfCff = data;
-
- if (mEfCfis == null) {
- callForwardingEnabled =
- ((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE);
-
- mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
- }
- break;
-
- case EVENT_GET_SPDI_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- parseEfSpdi(data);
- break;
-
- case EVENT_UPDATE_DONE:
- ar = (AsyncResult)msg.obj;
- if (ar.exception != null) {
- logw("update failed. ", ar.exception);
- }
- break;
-
- case EVENT_GET_PNN_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- SimTlv tlv = new SimTlv(data, 0, data.length);
-
- for ( ; tlv.isValidObject() ; tlv.nextObject()) {
- if (tlv.getTag() == TAG_FULL_NETWORK_NAME) {
- pnnHomeName
- = IccUtils.networkNameToString(
- tlv.getData(), 0, tlv.getData().length);
- break;
- }
- }
- break;
-
- case EVENT_GET_ALL_SMS_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- if (ar.exception != null)
- break;
-
- handleSmses((ArrayList) ar.result);
- break;
-
- case EVENT_MARK_SMS_READ_DONE:
- Log.i("ENF", "marked read: sms " + msg.arg1);
- break;
-
-
- case EVENT_SMS_ON_SIM:
- isRecordLoadResponse = false;
-
- ar = (AsyncResult)msg.obj;
-
- int[] index = (int[])ar.result;
-
- if (ar.exception != null || index.length != 1) {
- loge("Error on SMS_ON_SIM with exp "
- + ar.exception + " length " + index.length);
- } else {
- log("READ EF_SMS RECORD index=" + index[0]);
- mFh.loadEFLinearFixed(EF_SMS,index[0],
- obtainMessage(EVENT_GET_SMS_DONE));
- }
- break;
-
- case EVENT_GET_SMS_DONE:
- isRecordLoadResponse = false;
- ar = (AsyncResult)msg.obj;
- if (ar.exception == null) {
- handleSms((byte[])ar.result);
- } else {
- loge("Error on GET_SMS with exp " + ar.exception);
- }
- break;
- case EVENT_GET_SST_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- mUsimServiceTable = new UsimServiceTable(data);
- if (DBG) log("SST: " + mUsimServiceTable);
- break;
-
- case EVENT_GET_INFO_CPHS_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- break;
- }
-
- mCphsInfo = (byte[])ar.result;
-
- if (DBG) log("iCPHS: " + IccUtils.bytesToHexString(mCphsInfo));
- break;
-
- case EVENT_SET_MBDN_DONE:
- isRecordLoadResponse = false;
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception == null) {
- voiceMailNum = newVoiceMailNum;
- voiceMailTag = newVoiceMailTag;
- }
-
- if (isCphsMailboxEnabled()) {
- adn = new AdnRecord(voiceMailTag, voiceMailNum);
- Message onCphsCompleted = (Message) ar.userObj;
-
- /* write to cphs mailbox whenever it is available but
- * we only need notify caller once if both updating are
- * successful.
- *
- * so if set_mbdn successful, notify caller here and set
- * onCphsCompleted to null
- */
- if (ar.exception == null && ar.userObj != null) {
- AsyncResult.forMessage(((Message) ar.userObj)).exception
- = null;
- ((Message) ar.userObj).sendToTarget();
-
- if (DBG) log("Callback with MBDN successful.");
-
- onCphsCompleted = null;
- }
-
- new AdnRecordLoader(mFh).
- updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null,
- obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE,
- onCphsCompleted));
- } else {
- if (ar.userObj != null) {
- AsyncResult.forMessage(((Message) ar.userObj)).exception
- = ar.exception;
- ((Message) ar.userObj).sendToTarget();
- }
- }
- break;
- case EVENT_SET_CPHS_MAILBOX_DONE:
- isRecordLoadResponse = false;
- ar = (AsyncResult)msg.obj;
- if(ar.exception == null) {
- voiceMailNum = newVoiceMailNum;
- voiceMailTag = newVoiceMailTag;
- } else {
- if (DBG) log("Set CPHS MailBox with exception: "
- + ar.exception);
- }
- if (ar.userObj != null) {
- if (DBG) log("Callback with CPHS MB successful.");
- AsyncResult.forMessage(((Message) ar.userObj)).exception
- = ar.exception;
- ((Message) ar.userObj).sendToTarget();
- }
- break;
- case EVENT_SIM_REFRESH:
- isRecordLoadResponse = false;
- ar = (AsyncResult)msg.obj;
- if (DBG) log("Sim REFRESH with exception: " + ar.exception);
- if (ar.exception == null) {
- handleSimRefresh((IccRefreshResponse)ar.result);
- }
- break;
- case EVENT_GET_CFIS_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
- data = (byte[])ar.result;
-
- if (ar.exception != null) {
- break;
- }
-
- log("EF_CFIS: " + IccUtils.bytesToHexString(data));
-
- mEfCfis = data;
-
- // Refer TS 51.011 Section 10.3.46 for the content description
- callForwardingEnabled = ((data[1] & 0x01) != 0);
-
- mRecordsEventsRegistrants.notifyResult(EVENT_CFI);
- break;
-
- case EVENT_GET_CSP_CPHS_DONE:
- isRecordLoadResponse = true;
-
- ar = (AsyncResult)msg.obj;
-
- if (ar.exception != null) {
- loge("Exception in fetching EF_CSP data " + ar.exception);
- break;
- }
-
- data = (byte[])ar.result;
-
- log("EF_CSP: " + IccUtils.bytesToHexString(data));
- handleEfCspData(data);
- break;
-
- default:
- super.handleMessage(msg); // IccRecords handles generic record load responses
-
- }}catch (RuntimeException exc) {
- // I don't want these exceptions to be fatal
- logw("Exception parsing SIM record", exc);
- } finally {
- // Count up record load responses even if they are fails
- if (isRecordLoadResponse) {
- onRecordLoaded();
- }
- }
- }
-
- private void handleFileUpdate(int efid) {
- switch(efid) {
- case EF_MBDN:
- recordsToLoad++;
- new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
- mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
- break;
- case EF_MAILBOX_CPHS:
- recordsToLoad++;
- new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
- 1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
- break;
- case EF_CSP_CPHS:
- recordsToLoad++;
- log("[CSP] SIM Refresh for EF_CSP_CPHS");
- mFh.loadEFTransparent(EF_CSP_CPHS,
- obtainMessage(EVENT_GET_CSP_CPHS_DONE));
- break;
- default:
- // For now, fetch all records if this is not a
- // voicemail number.
- // TODO: Handle other cases, instead of fetching all.
- adnCache.reset();
- fetchSimRecords();
- break;
- }
- }
-
- private void handleSimRefresh(IccRefreshResponse refreshResponse){
- if (refreshResponse == null) {
- if (DBG) log("handleSimRefresh received without input");
- return;
- }
-
- if (refreshResponse.aid != null &&
- !refreshResponse.aid.equals(mParentCard.getAid())) {
- // This is for different app. Ignore.
- return;
- }
-
- switch (refreshResponse.refreshResult) {
- case IccRefreshResponse.REFRESH_RESULT_FILE_UPDATE:
- if (DBG) log("handleSimRefresh with SIM_FILE_UPDATED");
- handleFileUpdate(refreshResponse.efId);
- break;
- case IccRefreshResponse.REFRESH_RESULT_INIT:
- if (DBG) log("handleSimRefresh with SIM_REFRESH_INIT");
- // need to reload all files (that we care about)
- adnCache.reset();
- fetchSimRecords();
- break;
- case IccRefreshResponse.REFRESH_RESULT_RESET:
- if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET");
- mCi.setRadioPower(false, null);
- /* Note: no need to call setRadioPower(true). Assuming the desired
- * radio power state is still ON (as tracked by ServiceStateTracker),
- * ServiceStateTracker will call setRadioPower when it receives the
- * RADIO_STATE_CHANGED notification for the power off. And if the
- * desired power state has changed in the interim, we don't want to
- * override it with an unconditional power on.
- */
- break;
- default:
- // unknown refresh operation
- if (DBG) log("handleSimRefresh with unknown operation");
- break;
- }
- }
-
- /**
- * Dispatch 3GPP format message. Overridden for CDMA/LTE phones by
- * {@link com.android.internal.telephony.cdma.CdmaLteUiccRecords}
- * to send messages to the secondary 3GPP format SMS dispatcher.
- */
- protected int dispatchGsmMessage(SmsMessageBase message) {
- mNewSmsRegistrants.notifyResult(message);
- return 0;
- }
-
- private void handleSms(byte[] ba) {
- if (ba[0] != 0)
- Log.d("ENF", "status : " + ba[0]);
-
- // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3
- // 3 == "received by MS from network; message to be read"
- if (ba[0] == 3) {
- int n = ba.length;
-
- // Note: Data may include trailing FF's. That's OK; message
- // should still parse correctly.
- byte[] pdu = new byte[n - 1];
- System.arraycopy(ba, 1, pdu, 0, n - 1);
- SmsMessage message = SmsMessage.createFromPdu(pdu);
-
- dispatchGsmMessage(message);
- }
- }
-
-
- private void handleSmses(ArrayList messages) {
- int count = messages.size();
-
- for (int i = 0; i < count; i++) {
- byte[] ba = (byte[]) messages.get(i);
-
- if (ba[0] != 0)
- Log.i("ENF", "status " + i + ": " + ba[0]);
-
- // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3
- // 3 == "received by MS from network; message to be read"
-
- if (ba[0] == 3) {
- int n = ba.length;
-
- // Note: Data may include trailing FF's. That's OK; message
- // should still parse correctly.
- byte[] pdu = new byte[n - 1];
- System.arraycopy(ba, 1, pdu, 0, n - 1);
- SmsMessage message = SmsMessage.createFromPdu(pdu);
-
- dispatchGsmMessage(message);
-
- // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3
- // 1 == "received by MS from network; message read"
-
- ba[0] = 1;
-
- if (false) { // XXX writing seems to crash RdoServD
- mFh.updateEFLinearFixed(EF_SMS,
- i, ba, null, obtainMessage(EVENT_MARK_SMS_READ_DONE, i));
- }
- }
- }
- }
-
- protected void onRecordLoaded() {
- // One record loaded successfully or failed, In either case
- // we need to update the recordsToLoad count
- recordsToLoad -= 1;
- if (DBG) log("onRecordLoaded " + recordsToLoad + " requested: " + recordsRequested);
-
- if (recordsToLoad == 0 && recordsRequested == true) {
- onAllRecordsLoaded();
- } else if (recordsToLoad < 0) {
- loge("recordsToLoad <0, programmer error suspected");
- recordsToLoad = 0;
- }
- }
-
- protected void onAllRecordsLoaded() {
- String operator = getOperatorNumeric();
-
- // Some fields require more than one SIM record to set
-
- log("SIMRecords: onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
- operator + "'");
- SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
-
- if (imsi != null) {
- SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
- MccTable.countryCodeForMcc(Integer.parseInt(imsi.substring(0,3))));
- }
- else {
- loge("onAllRecordsLoaded: imsi is NULL!");
- }
-
- setVoiceMailByCountry(operator);
- setSpnFromConfig(operator);
-
- recordsLoadedRegistrants.notifyRegistrants(
- new AsyncResult(null, null, null));
- mParentCard.broadcastIccStateChangedIntent(
- IccCard.INTENT_VALUE_ICC_LOADED, null);
- }
-
- //***** Private methods
-
- private void setSpnFromConfig(String carrier) {
- if (mSpnOverride.containsCarrier(carrier)) {
- spn = mSpnOverride.getSpn(carrier);
- }
- }
-
-
- private void setVoiceMailByCountry (String spn) {
- if (mVmConfig.containsCarrier(spn)) {
- isVoiceMailFixed = true;
- voiceMailNum = mVmConfig.getVoiceMailNumber(spn);
- voiceMailTag = mVmConfig.getVoiceMailTag(spn);
- }
- }
-
- @Override
- public void onReady() {
- /* broadcast intent SIM_READY here so that we can make sure
- READY is sent before IMSI ready
- */
- mParentCard.broadcastIccStateChangedIntent(
- IccCard.INTENT_VALUE_ICC_READY, null);
-
- fetchSimRecords();
- }
-
- protected void fetchSimRecords() {
- recordsRequested = true;
-
- if (DBG) log("fetchSimRecords " + recordsToLoad);
-
- mCi.getIMSIForApp(mParentCard.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
- recordsToLoad++;
-
- // FIXME should examine EF[MSISDN]'s capability configuration
- // to determine which is the voice/data/fax line
- new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, EF_EXT1, 1,
- obtainMessage(EVENT_GET_MSISDN_DONE));
- recordsToLoad++;
-
- // Record number is subscriber profile
- mFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
- recordsToLoad++;
-
- // Record number is subscriber profile
- mFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE));
- recordsToLoad++;
-
-
- // Also load CPHS-style voice mail indicator, which stores
- // the same info as EF[MWIS]. If both exist, both are updated
- // but the EF[MWIS] data is preferred
- // Please note this must be loaded after EF[MWIS]
- mFh.loadEFTransparent(
- EF_VOICE_MAIL_INDICATOR_CPHS,
- obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));
- recordsToLoad++;
-
- // Same goes for Call Forward Status indicator: fetch both
- // EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
- mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
- recordsToLoad++;
- mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
- recordsToLoad++;
-
-
- getSpnFsm(true, null);
-
- mFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE));
- recordsToLoad++;
-
- mFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
- recordsToLoad++;
-
- mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
- recordsToLoad++;
-
- // XXX should seek instead of examining them all
- if (false) { // XXX
- mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
- recordsToLoad++;
- }
-
- if (CRASH_RIL) {
- String sms = "0107912160130310f20404d0110041007030208054832b0120"
- + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
- + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
- + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
- + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
- + "ffffffffffffffffffffffffffffff";
- byte[] ba = IccUtils.hexStringToBytes(sms);
-
- mFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
- obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
- }
- if (DBG) log("fetchSimRecords " + recordsToLoad + " requested: " + recordsRequested);
- }
-
- /**
- * 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.
- */
- @Override
- public int getDisplayRule(String plmn) {
- int rule;
- if (spn == null || spnDisplayCondition == -1) {
- // EF_SPN was not found on the SIM, or not yet loaded. Just show ONS.
- rule = SPN_RULE_SHOW_PLMN;
- } else if (isOnMatchingPlmn(plmn)) {
- rule = SPN_RULE_SHOW_SPN;
- if ((spnDisplayCondition & 0x01) == 0x01) {
- // ONS required when registered to HPLMN or PLMN in EF_SPDI
- rule |= SPN_RULE_SHOW_PLMN;
- }
- } else {
- rule = SPN_RULE_SHOW_PLMN;
- if ((spnDisplayCondition & 0x02) == 0x00) {
- // SPN required if not registered to HPLMN or PLMN in EF_SPDI
- rule |= SPN_RULE_SHOW_SPN;
- }
- }
- return rule;
- }
-
- /**
- * Checks if plmn is HPLMN or on the spdiNetworks list.
- */
- private boolean isOnMatchingPlmn(String plmn) {
- if (plmn == null) return false;
-
- if (plmn.equals(getOperatorNumeric())) {
- return true;
- }
-
- if (spdiNetworks != null) {
- for (String spdiNet : spdiNetworks) {
- if (plmn.equals(spdiNet)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * States of Get SPN Finite State Machine which only used by getSpnFsm()
- */
- private enum Get_Spn_Fsm_State {
- IDLE, // No initialized
- INIT, // Start FSM
- READ_SPN_3GPP, // Load EF_SPN firstly
- READ_SPN_CPHS, // Load EF_SPN_CPHS secondly
- READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last
- }
-
- /**
- * Finite State Machine to load Service Provider Name , which can be stored
- * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2)
- *
- * After starting, FSM will search SPN EFs in order and stop after finding
- * the first valid SPN
- *
- * If the FSM gets restart while waiting for one of
- * SPN EFs results (i.e. a SIM refresh occurs after issuing
- * read EF_CPHS_SPN), it will re-initialize only after
- * receiving and discarding the unfinished SPN EF result.
- *
- * @param start set true only for initialize loading
- * @param ar the AsyncResult from loadEFTransparent
- * ar.exception holds exception in error
- * ar.result is byte[] for data in success
- */
- private void getSpnFsm(boolean start, AsyncResult ar) {
- byte[] data;
-
- if (start) {
- // Check previous state to see if there is outstanding
- // SPN read
- if(spnState == Get_Spn_Fsm_State.READ_SPN_3GPP ||
- spnState == Get_Spn_Fsm_State.READ_SPN_CPHS ||
- spnState == Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS ||
- spnState == Get_Spn_Fsm_State.INIT) {
- // Set INIT then return so the INIT code
- // will run when the outstanding read done.
- spnState = Get_Spn_Fsm_State.INIT;
- return;
- } else {
- spnState = Get_Spn_Fsm_State.INIT;
- }
- }
-
- switch(spnState){
- case INIT:
- spn = null;
-
- mFh.loadEFTransparent(EF_SPN,
- obtainMessage(EVENT_GET_SPN_DONE));
- recordsToLoad++;
-
- spnState = Get_Spn_Fsm_State.READ_SPN_3GPP;
- break;
- case READ_SPN_3GPP:
- if (ar != null && ar.exception == null) {
- data = (byte[]) ar.result;
- spnDisplayCondition = 0xff & data[0];
- spn = IccUtils.adnStringFieldToString(data, 1, data.length - 1);
-
- if (DBG) log("Load EF_SPN: " + spn
- + " spnDisplayCondition: " + spnDisplayCondition);
- SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
-
- spnState = Get_Spn_Fsm_State.IDLE;
- } else {
- mFh.loadEFTransparent( EF_SPN_CPHS,
- obtainMessage(EVENT_GET_SPN_DONE));
- recordsToLoad++;
-
- spnState = Get_Spn_Fsm_State.READ_SPN_CPHS;
-
- // See TS 51.011 10.3.11. Basically, default to
- // show PLMN always, and SPN also if roaming.
- spnDisplayCondition = -1;
- }
- break;
- case READ_SPN_CPHS:
- if (ar != null && ar.exception == null) {
- data = (byte[]) ar.result;
- spn = IccUtils.adnStringFieldToString(
- data, 0, data.length - 1 );
-
- if (DBG) log("Load EF_SPN_CPHS: " + spn);
- SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
-
- spnState = Get_Spn_Fsm_State.IDLE;
- } else {
- mFh.loadEFTransparent(
- EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE));
- recordsToLoad++;
-
- spnState = Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS;
- }
- break;
- case READ_SPN_SHORT_CPHS:
- if (ar != null && ar.exception == null) {
- data = (byte[]) ar.result;
- spn = IccUtils.adnStringFieldToString(
- data, 0, data.length - 1);
-
- if (DBG) log("Load EF_SPN_SHORT_CPHS: " + spn);
- SystemProperties.set(PROPERTY_ICC_OPERATOR_ALPHA, spn);
- }else {
- if (DBG) log("No SPN loaded in either CHPS or 3GPP");
- }
-
- spnState = Get_Spn_Fsm_State.IDLE;
- break;
- default:
- spnState = Get_Spn_Fsm_State.IDLE;
- }
- }
-
- /**
- * Parse TS 51.011 EF[SPDI] record
- * This record contains the list of numeric network IDs that
- * are treated specially when determining SPN display
- */
- private void
- parseEfSpdi(byte[] data) {
- SimTlv tlv = new SimTlv(data, 0, data.length);
-
- byte[] plmnEntries = null;
-
- for ( ; tlv.isValidObject() ; tlv.nextObject()) {
- // Skip SPDI tag, if existant
- if (tlv.getTag() == TAG_SPDI) {
- tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
- }
- // There should only be one TAG_SPDI_PLMN_LIST
- if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
- plmnEntries = tlv.getData();
- break;
- }
- }
-
- if (plmnEntries == null) {
- return;
- }
-
- spdiNetworks = new ArrayList<String>(plmnEntries.length / 3);
-
- for (int i = 0 ; i + 2 < plmnEntries.length ; i += 3) {
- String plmnCode;
- plmnCode = IccUtils.bcdToString(plmnEntries, i, 3);
-
- // Valid operator codes are 5 or 6 digits
- if (plmnCode.length() >= 5) {
- log("EF_SPDI network: " + plmnCode);
- spdiNetworks.add(plmnCode);
- }
- }
- }
-
- /**
- * check to see if Mailbox Number is allocated and activated in CPHS SST
- */
- private boolean isCphsMailboxEnabled() {
- if (mCphsInfo == null) return false;
- return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED );
- }
-
- protected void log(String s) {
- Log.d(LOG_TAG, "[SIMRecords] " + s);
- }
-
- protected void loge(String s) {
- Log.e(LOG_TAG, "[SIMRecords] " + s);
- }
-
- protected void logw(String s, Throwable tr) {
- Log.w(LOG_TAG, "[SIMRecords] " + s, tr);
- }
-
- protected void logv(String s) {
- Log.v(LOG_TAG, "[SIMRecords] " + s);
- }
-
- /**
- * Return true if "Restriction of menu options for manual PLMN selection"
- * bit is set or EF_CSP data is unavailable, return false otherwise.
- */
- public boolean isCspPlmnEnabled() {
- return mCspPlmnEnabled;
- }
-
- /**
- * Parse EF_CSP data and check if
- * "Restriction of menu options for manual PLMN selection" is
- * Enabled/Disabled
- *
- * @param data EF_CSP hex data.
- */
- private void handleEfCspData(byte[] data) {
- // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
- // 18 bytes (i.e 9 service groups info) and additional data specific to
- // operator. The valueAddedServicesGroup is not part of standard
- // services. This is operator specific and can be programmed any where.
- // Normally this is programmed as 10th service after the standard
- // services.
- int usedCspGroups = data.length / 2;
- // This is the "Servive Group Number" of "Value Added Services Group".
- byte valueAddedServicesGroup = (byte)0xC0;
-
- mCspPlmnEnabled = true;
- for (int i = 0; i < usedCspGroups; i++) {
- if (data[2 * i] == valueAddedServicesGroup) {
- log("[CSP] found ValueAddedServicesGroup, value " + data[(2 * i) + 1]);
- if ((data[(2 * i) + 1] & 0x80) == 0x80) {
- // Bit 8 is for
- // "Restriction of menu options for manual PLMN selection".
- // Operator Selection menu should be enabled.
- mCspPlmnEnabled = true;
- } else {
- mCspPlmnEnabled = false;
- // Operator Selection menu should be disabled.
- // Operator Selection Mode should be set to Automatic.
- log("[CSP] Set Automatic Network Selection");
- mNetworkSelectionModeAutomaticRegistrants.notifyRegistrants();
- }
- return;
- }
- }
-
- log("[CSP] Value Added Service Group (0xC0), not found!");
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
deleted file mode 100644
index 35ba0d1..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-** 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
-**
-** 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.gsm;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-
-/**
- * SimPhoneBookInterfaceManager to provide an inter-process communication to
- * access ADN-like SIM records.
- */
-
-
-public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
- static final String LOG_TAG = "GSM";
-
- public SimPhoneBookInterfaceManager(GSMPhone phone) {
- super(phone);
- adnCache = phone.mIccRecords.getAdnCache();
- //NOTE service "simphonebook" added by IccSmsInterfaceManagerProxy
- }
-
- public void dispose() {
- super.dispose();
- }
-
- protected void finalize() {
- try {
- super.finalize();
- } catch (Throwable throwable) {
- Log.e(LOG_TAG, "Error while finalizing:", throwable);
- }
- if(DBG) Log.d(LOG_TAG, "SimPhoneBookInterfaceManager finalized");
- }
-
- public int[] getAdnRecordsSize(int efid) {
- if (DBG) logd("getAdnRecordsSize: efid=" + efid);
- synchronized(mLock) {
- checkThread();
- recordSize = new int[3];
-
- //Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
- AtomicBoolean status = new AtomicBoolean(false);
- Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
-
- phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
- waitForResult(status);
- }
-
- return recordSize;
- }
-
- protected void logd(String msg) {
- Log.d(LOG_TAG, "[SimPbInterfaceManager] " + msg);
- }
-
- protected void loge(String msg) {
- Log.e(LOG_TAG, "[SimPbInterfaceManager] " + msg);
- }
-}
-
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
deleted file mode 100644
index 92bf390..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-** 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
-**
-** 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.gsm;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.AsyncResult;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.IntRangeManager;
-import com.android.internal.telephony.SMSDispatcher;
-import com.android.internal.telephony.SmsRawData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
-
-/**
- * SimSmsInterfaceManager to provide an inter-process communication to
- * access Sms in Sim.
- */
-public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
- static final String LOG_TAG = "GSM";
- static final boolean DBG = true;
-
- private final Object mLock = new Object();
- private boolean mSuccess;
- private List<SmsRawData> mSms;
- private HashMap<Integer, HashSet<String>> mCellBroadcastSubscriptions =
- new HashMap<Integer, HashSet<String>>();
-
- private CellBroadcastRangeManager mCellBroadcastRangeManager =
- new CellBroadcastRangeManager();
-
- private static final int EVENT_LOAD_DONE = 1;
- private static final int EVENT_UPDATE_DONE = 2;
- private static final int EVENT_SET_BROADCAST_ACTIVATION_DONE = 3;
- private static final int EVENT_SET_BROADCAST_CONFIG_DONE = 4;
- private static final int SMS_CB_CODE_SCHEME_MIN = 0;
- private static final int SMS_CB_CODE_SCHEME_MAX = 255;
-
- Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case EVENT_UPDATE_DONE:
- ar = (AsyncResult) msg.obj;
- synchronized (mLock) {
- mSuccess = (ar.exception == null);
- mLock.notifyAll();
- }
- break;
- case EVENT_LOAD_DONE:
- ar = (AsyncResult)msg.obj;
- synchronized (mLock) {
- if (ar.exception == null) {
- mSms = buildValidRawData((ArrayList<byte[]>) ar.result);
- } else {
- if(DBG) log("Cannot load Sms records");
- if (mSms != null)
- mSms.clear();
- }
- mLock.notifyAll();
- }
- break;
- case EVENT_SET_BROADCAST_ACTIVATION_DONE:
- case EVENT_SET_BROADCAST_CONFIG_DONE:
- ar = (AsyncResult) msg.obj;
- synchronized (mLock) {
- mSuccess = (ar.exception == null);
- mLock.notifyAll();
- }
- break;
- }
- }
- };
-
- public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) {
- super(phone);
- mDispatcher = dispatcher;
- }
-
- public void dispose() {
- }
-
- @Override
- protected void finalize() {
- try {
- super.finalize();
- } catch (Throwable throwable) {
- Log.e(LOG_TAG, "Error while finalizing:", throwable);
- }
- if(DBG) Log.d(LOG_TAG, "SimSmsInterfaceManager finalized");
- }
-
- /**
- * Update the specified message on the SIM.
- *
- * @param index record index of message to update
- * @param status 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
- *
- */
- public boolean
- updateMessageOnIccEf(int index, int status, byte[] pdu) {
- if (DBG) log("updateMessageOnIccEf: index=" + index +
- " status=" + status + " ==> " +
- "("+ Arrays.toString(pdu) + ")");
- enforceReceiveAndSend("Updating message on SIM");
- synchronized(mLock) {
- mSuccess = false;
- Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
-
- if (status == STATUS_ON_ICC_FREE) {
- // Special case FREE: call deleteSmsOnSim instead of
- // manipulating the SIM record
- mPhone.mCM.deleteSmsOnSim(index, response);
- } else {
- byte[] record = makeSmsRecordData(status, pdu);
- mPhone.getIccFileHandler().updateEFLinearFixed(
- IccConstants.EF_SMS,
- index, record, null, response);
- }
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to update by index");
- }
- }
- return mSuccess;
- }
-
- /**
- * Copy a raw SMS PDU to the SIM.
- *
- * @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 success or not
- *
- */
- public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
- if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
- "pdu=("+ Arrays.toString(pdu) +
- "), smsm=(" + Arrays.toString(smsc) +")");
- enforceReceiveAndSend("Copying message to SIM");
- synchronized(mLock) {
- mSuccess = false;
- Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
-
- mPhone.mCM.writeSmsToSim(status, IccUtils.bytesToHexString(smsc),
- IccUtils.bytesToHexString(pdu), response);
-
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to update by index");
- }
- }
- return mSuccess;
- }
-
- /**
- * Retrieves all messages currently stored on ICC.
- *
- * @return list of SmsRawData of all sms on ICC
- */
- public List<SmsRawData> getAllMessagesFromIccEf() {
- if (DBG) log("getAllMessagesFromEF");
-
- Context context = mPhone.getContext();
-
- context.enforceCallingPermission(
- "android.permission.RECEIVE_SMS",
- "Reading messages from SIM");
- synchronized(mLock) {
- Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
- mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
-
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to load from the SIM");
- }
- }
- return mSms;
- }
-
- public boolean enableCellBroadcast(int messageIdentifier) {
- return enableCellBroadcastRange(messageIdentifier, messageIdentifier);
- }
-
- public boolean disableCellBroadcast(int messageIdentifier) {
- return disableCellBroadcastRange(messageIdentifier, messageIdentifier);
- }
-
- public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
- if (DBG) log("enableCellBroadcastRange");
-
- Context context = mPhone.getContext();
-
- context.enforceCallingPermission(
- "android.permission.RECEIVE_SMS",
- "Enabling cell broadcast SMS");
-
- String client = context.getPackageManager().getNameForUid(
- Binder.getCallingUid());
-
- if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) {
- log("Failed to add cell broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
- return false;
- }
-
- if (DBG)
- log("Added cell broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
-
- setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
-
- return true;
- }
-
- public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
- if (DBG) log("disableCellBroadcastRange");
-
- Context context = mPhone.getContext();
-
- context.enforceCallingPermission(
- "android.permission.RECEIVE_SMS",
- "Disabling cell broadcast SMS");
-
- String client = context.getPackageManager().getNameForUid(
- Binder.getCallingUid());
-
- if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) {
- log("Failed to remove cell broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
- return false;
- }
-
- if (DBG)
- log("Removed cell broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
-
- setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
-
- return true;
- }
-
- class CellBroadcastRangeManager extends IntRangeManager {
- private ArrayList<SmsBroadcastConfigInfo> mConfigList =
- new ArrayList<SmsBroadcastConfigInfo>();
-
- /**
- * Called when the list of enabled ranges has changed. This will be
- * followed by zero or more calls to {@link #addRange} followed by
- * a call to {@link #finishUpdate}.
- */
- protected void startUpdate() {
- mConfigList.clear();
- }
-
- /**
- * Called after {@link #startUpdate} to indicate a range of enabled
- * values.
- * @param startId the first id included in the range
- * @param endId the last id included in the range
- */
- protected void addRange(int startId, int endId, boolean selected) {
- mConfigList.add(new SmsBroadcastConfigInfo(startId, endId,
- SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected));
- }
-
- /**
- * Called to indicate the end of a range update started by the
- * previous call to {@link #startUpdate}.
- * @return true if successful, false otherwise
- */
- protected boolean finishUpdate() {
- if (mConfigList.isEmpty()) {
- return true;
- } else {
- SmsBroadcastConfigInfo[] configs =
- mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]);
- return setCellBroadcastConfig(configs);
- }
- }
- }
-
- private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) {
- if (DBG)
- log("Calling setGsmBroadcastConfig with " + configs.length + " configurations");
-
- synchronized (mLock) {
- Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE);
-
- mSuccess = false;
- mPhone.mCM.setGsmBroadcastConfig(configs, response);
-
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to set cell broadcast config");
- }
- }
-
- return mSuccess;
- }
-
- private boolean setCellBroadcastActivation(boolean activate) {
- if (DBG)
- log("Calling setCellBroadcastActivation(" + activate + ')');
-
- synchronized (mLock) {
- Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE);
-
- mSuccess = false;
- mPhone.mCM.setGsmBroadcastActivation(activate, response);
-
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- log("interrupted while trying to set cell broadcast activation");
- }
- }
-
- return mSuccess;
- }
-
- @Override
- protected void log(String msg) {
- Log.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java b/telephony/java/com/android/internal/telephony/gsm/SimTlv.java
deleted file mode 100644
index 497cf5f..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.gsm;
-
-/**
- * SIM Tag-Length-Value record
- * TS 102 223 Annex C
- *
- * {@hide}
- *
- */
-public class SimTlv
-{
- //***** Private Instance Variables
-
- byte record[];
- int tlvOffset;
- int tlvLength;
- int curOffset;
- int curDataOffset;
- int curDataLength;
- boolean hasValidTlvObject;
-
- public SimTlv(byte[] record, int offset, int length) {
- this.record = record;
-
- this.tlvOffset = offset;
- this.tlvLength = length;
- curOffset = offset;
-
- hasValidTlvObject = parseCurrentTlvObject();
- }
-
- public boolean nextObject() {
- if (!hasValidTlvObject) return false;
- curOffset = curDataOffset + curDataLength;
- hasValidTlvObject = parseCurrentTlvObject();
- return hasValidTlvObject;
- }
-
- public boolean isValidObject() {
- return hasValidTlvObject;
- }
-
- /**
- * Returns the tag for the current TLV object
- * Return 0 if !isValidObject()
- * 0 and 0xff are invalid tag values
- * valid tags range from 1 - 0xfe
- */
- public int getTag() {
- if (!hasValidTlvObject) return 0;
- return record[curOffset] & 0xff;
- }
-
- /**
- * Returns data associated with current TLV object
- * returns null if !isValidObject()
- */
-
- public byte[] getData() {
- if (!hasValidTlvObject) return null;
-
- byte[] ret = new byte[curDataLength];
- System.arraycopy(record, curDataOffset, ret, 0, curDataLength);
- return ret;
- }
-
- /**
- * Updates curDataLength and curDataOffset
- * @return false on invalid record, true on valid record
- */
-
- private boolean parseCurrentTlvObject() {
- // 0x00 and 0xff are invalid tag values
-
- try {
- if (record[curOffset] == 0 || (record[curOffset] & 0xff) == 0xff) {
- return false;
- }
-
- if ((record[curOffset + 1] & 0xff) < 0x80) {
- // one byte length 0 - 0x7f
- curDataLength = record[curOffset + 1] & 0xff;
- curDataOffset = curOffset + 2;
- } else if ((record[curOffset + 1] & 0xff) == 0x81) {
- // two byte length 0x80 - 0xff
- curDataLength = record[curOffset + 2] & 0xff;
- curDataOffset = curOffset + 3;
- } else {
- return false;
- }
- } catch (ArrayIndexOutOfBoundsException ex) {
- return false;
- }
-
- if (curDataLength + curDataOffset > tlvOffset + tlvLength) {
- return false;
- }
-
- return true;
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
deleted file mode 100644
index 66e7ce0..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2009 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.gsm;
-
-/**
- * SmsBroadcastConfigInfo defines one configuration of Cell Broadcast
- * Message (CBM) to be received by the ME
- *
- * fromServiceId - toServiceId defines a range of CBM message identifiers
- * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS
- * and 9.4.4.2.2 for UMTS. All other values can be treated as empty
- * CBM message ID.
- *
- * fromCodeScheme - toCodeScheme defines a range of CBM data coding schemes
- * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS
- * and 9.4.4.2.3 for UMTS.
- * All other values can be treated as empty CBM data coding scheme.
- *
- * selected false means message types specified in {@code <fromServiceId, toServiceId>}
- * and {@code <fromCodeScheme, toCodeScheme>} are not accepted, while true means accepted.
- *
- */
-public final class SmsBroadcastConfigInfo {
- private int fromServiceId;
- private int toServiceId;
- private int fromCodeScheme;
- private int toCodeScheme;
- private boolean selected;
-
- /**
- * Initialize the object from rssi and cid.
- */
- public SmsBroadcastConfigInfo(int fromId, int toId, int fromScheme,
- int toScheme, boolean selected) {
- fromServiceId = fromId;
- toServiceId = toId;
- fromCodeScheme = fromScheme;
- toCodeScheme = toScheme;
- this.selected = selected;
- }
-
- /**
- * @param fromServiceId the fromServiceId to set
- */
- public void setFromServiceId(int fromServiceId) {
- this.fromServiceId = fromServiceId;
- }
-
- /**
- * @return the fromServiceId
- */
- public int getFromServiceId() {
- return fromServiceId;
- }
-
- /**
- * @param toServiceId the toServiceId to set
- */
- public void setToServiceId(int toServiceId) {
- this.toServiceId = toServiceId;
- }
-
- /**
- * @return the toServiceId
- */
- public int getToServiceId() {
- return toServiceId;
- }
-
- /**
- * @param fromCodeScheme the fromCodeScheme to set
- */
- public void setFromCodeScheme(int fromCodeScheme) {
- this.fromCodeScheme = fromCodeScheme;
- }
-
- /**
- * @return the fromCodeScheme
- */
- public int getFromCodeScheme() {
- return fromCodeScheme;
- }
-
- /**
- * @param toCodeScheme the toCodeScheme to set
- */
- public void setToCodeScheme(int toCodeScheme) {
- this.toCodeScheme = toCodeScheme;
- }
-
- /**
- * @return the toCodeScheme
- */
- public int getToCodeScheme() {
- return toCodeScheme;
- }
-
- /**
- * @param selected the selected to set
- */
- public void setSelected(boolean selected) {
- this.selected = selected;
- }
-
- /**
- * @return the selected
- */
- public boolean isSelected() {
- return selected;
- }
-
- @Override
- public String toString() {
- return "SmsBroadcastConfigInfo: Id [" +
- fromServiceId + ',' + toServiceId + "] Code [" +
- fromCodeScheme + ',' + toCodeScheme + "] " +
- (selected ? "ENABLED" : "DISABLED");
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
deleted file mode 100644
index ebb4666..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.gsm;
-
-/**
- * Constants used in SMS Cell Broadcast messages (see 3GPP TS 23.041). This class is used by the
- * boot-time broadcast channel enable and database upgrade code in CellBroadcastReceiver, so it
- * is public, but should be avoided in favor of the radio technology independent constants in
- * {@link android.telephony.SmsCbMessage}, {@link android.telephony.SmsCbEtwsInfo}, and
- * {@link android.telephony.SmsCbCmasInfo} classes.
- *
- * {@hide}
- */
-public class SmsCbConstants {
-
- /** Private constructor for utility class. */
- private SmsCbConstants() { }
-
- /** Start of PWS Message Identifier range (includes ETWS and CMAS). */
- public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER = 0x1100;
-
- /** Bitmask for messages of ETWS type (including future extensions). */
- public static final int MESSAGE_ID_ETWS_TYPE_MASK = 0xFFF8;
-
- /** Value for messages of ETWS type after applying {@link #MESSAGE_ID_ETWS_TYPE_MASK}. */
- public static final int MESSAGE_ID_ETWS_TYPE = 0x1100;
-
- /** ETWS Message Identifier for earthquake warning message. */
- public static final int MESSAGE_ID_ETWS_EARTHQUAKE_WARNING = 0x1100;
-
- /** ETWS Message Identifier for tsunami warning message. */
- public static final int MESSAGE_ID_ETWS_TSUNAMI_WARNING = 0x1101;
-
- /** ETWS Message Identifier for earthquake and tsunami combined warning message. */
- public static final int MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING = 0x1102;
-
- /** ETWS Message Identifier for test message. */
- public static final int MESSAGE_ID_ETWS_TEST_MESSAGE = 0x1103;
-
- /** ETWS Message Identifier for messages related to other emergency types. */
- public static final int MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE = 0x1104;
-
- /** Start of CMAS Message Identifier range. */
- public static final int MESSAGE_ID_CMAS_FIRST_IDENTIFIER = 0x1112;
-
- /** CMAS Message Identifier for Presidential Level alerts. */
- public static final int MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL = 0x1112;
-
- /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed. */
- public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED = 0x1113;
-
- /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely. */
- public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY = 0x1114;
-
- /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed. */
- public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED = 0x1115;
-
- /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely. */
- public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY = 0x1116;
-
- /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed. */
- public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED = 0x1117;
-
- /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely. */
- public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY = 0x1118;
-
- /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed. */
- public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED = 0x1119;
-
- /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely. */
- public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY = 0x111A;
-
- /** CMAS Message Identifier for Child Abduction Emergency (Amber Alert). */
- public static final int MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY = 0x111B;
-
- /** CMAS Message Identifier for the Required Monthly Test. */
- public static final int MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST = 0x111C;
-
- /** CMAS Message Identifier for CMAS Exercise. */
- public static final int MESSAGE_ID_CMAS_ALERT_EXERCISE = 0x111D;
-
- /** CMAS Message Identifier for operator defined use. */
- public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE = 0x111E;
-
- /** End of CMAS Message Identifier range (including future extensions). */
- public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER = 0x112F;
-
- /** End of PWS Message Identifier range (includes ETWS, CMAS, and future extensions). */
- public static final int MESSAGE_ID_PWS_LAST_IDENTIFIER = 0x18FF;
-
- /** ETWS serial number flag to activate the popup display. */
- public static final int SERIAL_NUMBER_ETWS_ACTIVATE_POPUP = 0x1000;
-
- /** ETWS serial number flag to activate the emergency user alert. */
- public static final int SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT = 0x2000;
-
- /** ETWS warning type value for earthquake. */
- public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00;
-
- /** ETWS warning type value for tsunami. */
- public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01;
-
- /** ETWS warning type value for earthquake and tsunami. */
- public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02;
-
- /** ETWS warning type value for test broadcast. */
- public static final int ETWS_WARNING_TYPE_TEST = 0x03;
-
- /** ETWS warning type value for other notifications. */
- public static final int ETWS_WARNING_TYPE_OTHER = 0x04;
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
deleted file mode 100644
index 5692044..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 2010 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.gsm;
-
-import android.telephony.SmsCbCmasInfo;
-import android.telephony.SmsCbEtwsInfo;
-
-import java.util.Arrays;
-
-/**
- * Parses a 3GPP TS 23.041 cell broadcast message header. This class is public for use by
- * CellBroadcastReceiver test cases, but should not be used by applications.
- *
- * All relevant header information is now sent as a Parcelable
- * {@link android.telephony.SmsCbMessage} object in the "message" extra of the
- * {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or
- * {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent.
- * The raw PDU is no longer sent to SMS CB applications.
- */
-class SmsCbHeader {
-
- /**
- * Length of SMS-CB header
- */
- static final int PDU_HEADER_LENGTH = 6;
-
- /**
- * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1
- */
- static final int FORMAT_GSM = 1;
-
- /**
- * UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2
- */
- static final int FORMAT_UMTS = 2;
-
- /**
- * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
- */
- static final int FORMAT_ETWS_PRIMARY = 3;
-
- /**
- * Message type value as defined in 3gpp TS 25.324, section 11.1.
- */
- private static final int MESSAGE_TYPE_CBS_MESSAGE = 1;
-
- /**
- * Length of GSM pdus
- */
- private static final int PDU_LENGTH_GSM = 88;
-
- /**
- * Maximum length of ETWS primary message GSM pdus
- */
- private static final int PDU_LENGTH_ETWS = 56;
-
- private final int geographicalScope;
-
- /** The serial number combines geographical scope, message code, and update number. */
- private final int serialNumber;
-
- /** The Message Identifier in 3GPP is the same as the Service Category in CDMA. */
- private final int messageIdentifier;
-
- private final int dataCodingScheme;
-
- private final int pageIndex;
-
- private final int nrOfPages;
-
- private final int format;
-
- /** ETWS warning notification info. */
- private final SmsCbEtwsInfo mEtwsInfo;
-
- /** CMAS warning notification info. */
- private final SmsCbCmasInfo mCmasInfo;
-
- public SmsCbHeader(byte[] pdu) throws IllegalArgumentException {
- if (pdu == null || pdu.length < PDU_HEADER_LENGTH) {
- throw new IllegalArgumentException("Illegal PDU");
- }
-
- if (pdu.length <= PDU_LENGTH_ETWS) {
- format = FORMAT_ETWS_PRIMARY;
- geographicalScope = (pdu[0] & 0xc0) >> 6;
- serialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff);
- messageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff);
- dataCodingScheme = -1;
- pageIndex = -1;
- nrOfPages = -1;
- boolean emergencyUserAlert = (pdu[4] & 0x1) != 0;
- boolean activatePopup = (pdu[5] & 0x80) != 0;
- int warningType = (pdu[4] & 0xfe) >> 1;
- byte[] warningSecurityInfo;
- // copy the Warning-Security-Information, if present
- if (pdu.length > PDU_HEADER_LENGTH) {
- warningSecurityInfo = Arrays.copyOfRange(pdu, 6, pdu.length);
- } else {
- warningSecurityInfo = null;
- }
- mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup,
- warningSecurityInfo);
- mCmasInfo = null;
- return; // skip the ETWS/CMAS initialization code for regular notifications
- } else if (pdu.length <= PDU_LENGTH_GSM) {
- // GSM pdus are no more than 88 bytes
- format = FORMAT_GSM;
- geographicalScope = (pdu[0] & 0xc0) >> 6;
- serialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff);
- messageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff);
- dataCodingScheme = pdu[4] & 0xff;
-
- // Check for invalid page parameter
- int pageIndex = (pdu[5] & 0xf0) >> 4;
- int nrOfPages = pdu[5] & 0x0f;
-
- if (pageIndex == 0 || nrOfPages == 0 || pageIndex > nrOfPages) {
- pageIndex = 1;
- nrOfPages = 1;
- }
-
- this.pageIndex = pageIndex;
- this.nrOfPages = nrOfPages;
- } else {
- // UMTS pdus are always at least 90 bytes since the payload includes
- // a number-of-pages octet and also one length octet per page
- format = FORMAT_UMTS;
-
- int messageType = pdu[0];
-
- if (messageType != MESSAGE_TYPE_CBS_MESSAGE) {
- throw new IllegalArgumentException("Unsupported message type " + messageType);
- }
-
- messageIdentifier = ((pdu[1] & 0xff) << 8) | pdu[2] & 0xff;
- geographicalScope = (pdu[3] & 0xc0) >> 6;
- serialNumber = ((pdu[3] & 0xff) << 8) | (pdu[4] & 0xff);
- dataCodingScheme = pdu[5] & 0xff;
-
- // We will always consider a UMTS message as having one single page
- // since there's only one instance of the header, even though the
- // actual payload may contain several pages.
- pageIndex = 1;
- nrOfPages = 1;
- }
-
- if (isEtwsMessage()) {
- boolean emergencyUserAlert = isEtwsEmergencyUserAlert();
- boolean activatePopup = isEtwsPopupAlert();
- int warningType = getEtwsWarningType();
- mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup, null);
- mCmasInfo = null;
- } else if (isCmasMessage()) {
- int messageClass = getCmasMessageClass();
- int severity = getCmasSeverity();
- int urgency = getCmasUrgency();
- int certainty = getCmasCertainty();
- mEtwsInfo = null;
- mCmasInfo = new SmsCbCmasInfo(messageClass, SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN,
- SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, severity, urgency, certainty);
- } else {
- mEtwsInfo = null;
- mCmasInfo = null;
- }
- }
-
- int getGeographicalScope() {
- return geographicalScope;
- }
-
- int getSerialNumber() {
- return serialNumber;
- }
-
- int getServiceCategory() {
- return messageIdentifier;
- }
-
- int getDataCodingScheme() {
- return dataCodingScheme;
- }
-
- int getPageIndex() {
- return pageIndex;
- }
-
- int getNumberOfPages() {
- return nrOfPages;
- }
-
- SmsCbEtwsInfo getEtwsInfo() {
- return mEtwsInfo;
- }
-
- SmsCbCmasInfo getCmasInfo() {
- return mCmasInfo;
- }
-
- /**
- * Return whether this broadcast is an emergency (PWS) message type.
- * @return true if this message is emergency type; false otherwise
- */
- boolean isEmergencyMessage() {
- return messageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER
- && messageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER;
- }
-
- /**
- * Return whether this broadcast is an ETWS emergency message type.
- * @return true if this message is ETWS emergency type; false otherwise
- */
- private boolean isEtwsMessage() {
- return (messageIdentifier & SmsCbConstants.MESSAGE_ID_ETWS_TYPE_MASK)
- == SmsCbConstants.MESSAGE_ID_ETWS_TYPE;
- }
-
- /**
- * Return whether this broadcast is an ETWS primary notification.
- * @return true if this message is an ETWS primary notification; false otherwise
- */
- boolean isEtwsPrimaryNotification() {
- return format == FORMAT_ETWS_PRIMARY;
- }
-
- /**
- * Return whether this broadcast is in UMTS format.
- * @return true if this message is in UMTS format; false otherwise
- */
- boolean isUmtsFormat() {
- return format == FORMAT_UMTS;
- }
-
- /**
- * Return whether this message is a CMAS emergency message type.
- * @return true if this message is CMAS emergency type; false otherwise
- */
- private boolean isCmasMessage() {
- return messageIdentifier >= SmsCbConstants.MESSAGE_ID_CMAS_FIRST_IDENTIFIER
- && messageIdentifier <= SmsCbConstants.MESSAGE_ID_CMAS_LAST_IDENTIFIER;
- }
-
- /**
- * Return whether the popup alert flag is set for an ETWS warning notification.
- * This method assumes that the message ID has already been checked for ETWS type.
- *
- * @return true if the message code indicates a popup alert should be displayed
- */
- private boolean isEtwsPopupAlert() {
- return (serialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_ACTIVATE_POPUP) != 0;
- }
-
- /**
- * Return whether the emergency user alert flag is set for an ETWS warning notification.
- * This method assumes that the message ID has already been checked for ETWS type.
- *
- * @return true if the message code indicates an emergency user alert
- */
- private boolean isEtwsEmergencyUserAlert() {
- return (serialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT) != 0;
- }
-
- /**
- * Returns the warning type for an ETWS warning notification.
- * This method assumes that the message ID has already been checked for ETWS type.
- *
- * @return the ETWS warning type defined in 3GPP TS 23.041 section 9.3.24
- */
- private int getEtwsWarningType() {
- return messageIdentifier - SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING;
- }
-
- /**
- * Returns the message class for a CMAS warning notification.
- * This method assumes that the message ID has already been checked for CMAS type.
- * @return the CMAS message class as defined in {@link SmsCbCmasInfo}
- */
- private int getCmasMessageClass() {
- switch (messageIdentifier) {
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL:
- return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
- return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
- return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY:
- return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST:
- return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE:
- return SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE:
- return SmsCbCmasInfo.CMAS_CLASS_OPERATOR_DEFINED_USE;
-
- default:
- return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
- }
- }
-
- /**
- * Returns the severity for a CMAS warning notification. This is only available for extreme
- * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
- * This method assumes that the message ID has already been checked for CMAS type.
- * @return the CMAS severity as defined in {@link SmsCbCmasInfo}
- */
- private int getCmasSeverity() {
- switch (messageIdentifier) {
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
- return SmsCbCmasInfo.CMAS_SEVERITY_EXTREME;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
- return SmsCbCmasInfo.CMAS_SEVERITY_SEVERE;
-
- default:
- return SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
- }
- }
-
- /**
- * Returns the urgency for a CMAS warning notification. This is only available for extreme
- * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
- * This method assumes that the message ID has already been checked for CMAS type.
- * @return the CMAS urgency as defined in {@link SmsCbCmasInfo}
- */
- private int getCmasUrgency() {
- switch (messageIdentifier) {
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
- return SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
- return SmsCbCmasInfo.CMAS_URGENCY_EXPECTED;
-
- default:
- return SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
- }
- }
-
- /**
- * Returns the certainty for a CMAS warning notification. This is only available for extreme
- * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
- * This method assumes that the message ID has already been checked for CMAS type.
- * @return the CMAS certainty as defined in {@link SmsCbCmasInfo}
- */
- private int getCmasCertainty() {
- switch (messageIdentifier) {
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
- return SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED;
-
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
- case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
- return SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY;
-
- default:
- return SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
- }
- }
-
- @Override
- public String toString() {
- return "SmsCbHeader{GS=" + geographicalScope + ", serialNumber=0x" +
- Integer.toHexString(serialNumber) +
- ", messageIdentifier=0x" + Integer.toHexString(messageIdentifier) +
- ", DCS=0x" + Integer.toHexString(dataCodingScheme) +
- ", page " + pageIndex + " of " + nrOfPages + '}';
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
deleted file mode 100644
index da60584..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- * 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.gsm;
-
-import android.telephony.PhoneNumberUtils;
-import android.text.format.Time;
-import android.util.Log;
-
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.SmsMessageBase;
-
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-
-import static android.telephony.SmsMessage.ENCODING_16BIT;
-import static android.telephony.SmsMessage.ENCODING_7BIT;
-import static android.telephony.SmsMessage.ENCODING_8BIT;
-import static android.telephony.SmsMessage.ENCODING_KSC5601;
-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.MessageClass;
-
-/**
- * A Short Message Service message.
- *
- */
-public class SmsMessage extends SmsMessageBase {
- static final String LOG_TAG = "GSM";
-
- private MessageClass messageClass;
-
- /**
- * TP-Message-Type-Indicator
- * 9.2.3
- */
- private int mti;
-
- /** TP-Protocol-Identifier (TP-PID) */
- private int protocolIdentifier;
-
- // TP-Data-Coding-Scheme
- // see TS 23.038
- private int dataCodingScheme;
-
- // TP-Reply-Path
- // e.g. 23.040 9.2.2.1
- private boolean replyPathPresent = false;
-
- // "Message Marked for Automatic Deletion Group"
- // 23.038 Section 4
- private boolean automaticDeletion;
-
- /** True if Status Report is for SMS-SUBMIT; false for SMS-COMMAND. */
- private boolean forSubmit;
-
- /** The address of the receiver. */
- private GsmSmsAddress recipientAddress;
-
- /** Time when SMS-SUBMIT was delivered from SC to MSE. */
- private long dischargeTimeMillis;
-
- /**
- * TP-Status - status of a previously submitted SMS.
- * This field applies to SMS-STATUS-REPORT messages. 0 indicates success;
- * see TS 23.040, 9.2.3.15 for description of other possible values.
- */
- private int status;
-
- /**
- * TP-Status - status of a previously submitted SMS.
- * This field is true iff the message is a SMS-STATUS-REPORT message.
- */
- private boolean isStatusReportMessage = false;
-
- public static class SubmitPdu extends SubmitPduBase {
- }
-
- /**
- * Create an SmsMessage from a raw PDU.
- */
- public static SmsMessage createFromPdu(byte[] pdu) {
- try {
- SmsMessage msg = new SmsMessage();
- msg.parsePdu(pdu);
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
- }
- }
-
- /**
- * 3GPP TS 23.040 9.2.3.9 specifies that Type Zero messages are indicated
- * by TP_PID field set to value 0x40
- */
- public boolean isTypeZero() {
- return (protocolIdentifier == 0x40);
- }
-
- /**
- * 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: [<alpha>],<length><CR><LF><pdu>
- *
- * Only public for debugging
- *
- * {@hide}
- */
- public static SmsMessage newFromCMT(String[] lines) {
- try {
- SmsMessage msg = new SmsMessage();
- msg.parsePdu(IccUtils.hexStringToBytes(lines[1]));
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
- }
- }
-
- /** @hide */
- public static SmsMessage newFromCDS(String line) {
- try {
- SmsMessage msg = new SmsMessage();
- msg.parsePdu(IccUtils.hexStringToBytes(line));
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "CDS SMS PDU parsing failed: ", ex);
- return null;
- }
- }
-
- /**
- * 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) {
- try {
- SmsMessage msg = new SmsMessage();
-
- msg.indexOnIcc = index;
-
- // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT,
- // or STORED_UNSENT
- // See TS 51.011 10.5.3
- if ((data[0] & 1) == 0) {
- Log.w(LOG_TAG,
- "SMS parsing failed: Trying to parse a free record");
- return null;
- } else {
- msg.statusOnIcc = data[0] & 0x07;
- }
-
- int size = data.length - 1;
-
- // Note: Data may include trailing FF's. That's OK; message
- // should still parse correctly.
- byte[] pdu = new byte[size];
- System.arraycopy(data, 1, pdu, 0, size);
- msg.parsePdu(pdu);
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
- }
- }
-
- /**
- * 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 len = pdu.length() / 2;
- int smscLen = Integer.parseInt(pdu.substring(0, 2), 16);
-
- return len - smscLen - 1;
- }
-
- /**
- * 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) {
- return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, header,
- ENCODING_UNKNOWN, 0, 0);
- }
-
-
- /**
- * Get an SMS-SUBMIT PDU for a destination address and a message using the
- * specified encoding.
- *
- * @param scAddress Service Centre address. Null means use default.
- * @param encoding Encoding defined by constants in android.telephony.SmsMessage.ENCODING_*
- * @param languageTable
- * @param languageShiftTable
- * @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, int encoding,
- int languageTable, int languageShiftTable) {
-
- // Perform null parameter checks.
- if (message == null || destinationAddress == null) {
- return null;
- }
-
- if (encoding == ENCODING_UNKNOWN) {
- // Find the best encoding to use
- TextEncodingDetails ted = calculateLength(message, false);
- encoding = ted.codeUnitSize;
- languageTable = ted.languageTable;
- languageShiftTable = ted.languageShiftTable;
-
- if (encoding == ENCODING_7BIT && (languageTable != 0 || languageShiftTable != 0)) {
- if (header != null) {
- SmsHeader smsHeader = SmsHeader.fromByteArray(header);
- if (smsHeader.languageTable != languageTable
- || smsHeader.languageShiftTable != languageShiftTable) {
- Log.w(LOG_TAG, "Updating language table in SMS header: "
- + smsHeader.languageTable + " -> " + languageTable + ", "
- + smsHeader.languageShiftTable + " -> " + languageShiftTable);
- smsHeader.languageTable = languageTable;
- smsHeader.languageShiftTable = languageShiftTable;
- header = SmsHeader.toByteArray(smsHeader);
- }
- } else {
- SmsHeader smsHeader = new SmsHeader();
- smsHeader.languageTable = languageTable;
- smsHeader.languageShiftTable = languageShiftTable;
- header = SmsHeader.toByteArray(smsHeader);
- }
- }
- }
-
- SubmitPdu ret = new SubmitPdu();
- // MTI = SMS-SUBMIT, UDHI = header != null
- byte mtiByte = (byte)(0x01 | (header != null ? 0x40 : 0x00));
- ByteArrayOutputStream bo = getSubmitPduHead(
- scAddress, destinationAddress, mtiByte,
- statusReportRequested, ret);
-
- // User Data (and length)
- byte[] userData;
- try {
- if (encoding == ENCODING_7BIT) {
- userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header,
- languageTable, languageShiftTable);
- } else { //assume UCS-2
- try {
- userData = encodeUCS2(message, header);
- } catch(UnsupportedEncodingException uex) {
- Log.e(LOG_TAG,
- "Implausible UnsupportedEncodingException ",
- uex);
- return null;
- }
- }
- } catch (EncodeException ex) {
- // Encoding to the 7-bit alphabet failed. Let's see if we can
- // send it as a UCS-2 encoded message
- try {
- userData = encodeUCS2(message, header);
- encoding = ENCODING_16BIT;
- } catch(UnsupportedEncodingException uex) {
- Log.e(LOG_TAG,
- "Implausible UnsupportedEncodingException ",
- uex);
- return null;
- }
- }
-
- if (encoding == ENCODING_7BIT) {
- if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) {
- // Message too long
- Log.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " septets)");
- return null;
- }
- // TP-Data-Coding-Scheme
- // Default encoding, uncompressed
- // To test writing messages to the SIM card, change this value 0x00
- // to 0x12, which means "bits 1 and 0 contain message class, and the
- // class is 2". Note that this takes effect for the sender. In other
- // words, messages sent by the phone with this change will end up on
- // the receiver's SIM card. You can then send messages to yourself
- // (on a phone with this change) and they'll end up on the SIM card.
- bo.write(0x00);
- } else { // assume UCS-2
- if ((0xff & userData[0]) > MAX_USER_DATA_BYTES) {
- // Message too long
- Log.e(LOG_TAG, "Message too long (" + (0xff & userData[0]) + " bytes)");
- return null;
- }
- // TP-Data-Coding-Scheme
- // UCS-2 encoding, uncompressed
- bo.write(0x08);
- }
-
- // (no TP-Validity-Period)
- bo.write(userData, 0, userData.length);
- ret.encodedMessage = bo.toByteArray();
- return ret;
- }
-
- /**
- * Packs header and UCS-2 encoded message. Includes TP-UDL & TP-UDHL if necessary
- *
- * @return
- * @throws UnsupportedEncodingException
- */
- private static byte[] encodeUCS2(String message, byte[] header)
- throws UnsupportedEncodingException {
- byte[] userData, textPart;
- textPart = message.getBytes("utf-16be");
-
- if (header != null) {
- // Need 1 byte for UDHL
- userData = new byte[header.length + textPart.length + 1];
-
- userData[0] = (byte)header.length;
- System.arraycopy(header, 0, userData, 1, header.length);
- System.arraycopy(textPart, 0, userData, header.length + 1, textPart.length);
- }
- else {
- userData = textPart;
- }
- byte[] ret = new byte[userData.length+1];
- ret[0] = (byte) (userData.length & 0xff );
- System.arraycopy(userData, 0, ret, 1, userData.length);
- return ret;
- }
-
- /**
- * 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) {
-
- return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested, null);
- }
-
- /**
- * Get an SMS-SUBMIT PDU for a data message to a destination address & 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 data 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, int destinationPort, byte[] data,
- boolean statusReportRequested) {
-
- SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
- portAddrs.destPort = destinationPort;
- portAddrs.origPort = 0;
- portAddrs.areEightBits = false;
-
- SmsHeader smsHeader = new SmsHeader();
- smsHeader.portAddrs = portAddrs;
-
- byte[] smsHeaderData = SmsHeader.toByteArray(smsHeader);
-
- if ((data.length + smsHeaderData.length + 1) > MAX_USER_DATA_BYTES) {
- Log.e(LOG_TAG, "SMS data message may only contain "
- + (MAX_USER_DATA_BYTES - smsHeaderData.length - 1) + " bytes");
- return null;
- }
-
- SubmitPdu ret = new SubmitPdu();
- ByteArrayOutputStream bo = getSubmitPduHead(
- scAddress, destinationAddress, (byte) 0x41, // MTI = SMS-SUBMIT,
- // TP-UDHI = true
- statusReportRequested, ret);
-
- // TP-Data-Coding-Scheme
- // No class, 8 bit data
- bo.write(0x04);
-
- // (no TP-Validity-Period)
-
- // Total size
- bo.write(data.length + smsHeaderData.length + 1);
-
- // User data header
- bo.write(smsHeaderData.length);
- bo.write(smsHeaderData, 0, smsHeaderData.length);
-
- // User data
- bo.write(data, 0, data.length);
-
- ret.encodedMessage = bo.toByteArray();
- return ret;
- }
-
- /**
- * Create the beginning of a SUBMIT PDU. This is the part of the
- * SUBMIT PDU that is common to the two versions of {@link #getSubmitPdu},
- * one of which takes a byte array and the other of which takes a
- * <code>String</code>.
- *
- * @param scAddress Service Centre address. null == use default
- * @param destinationAddress the address of the destination for the message
- * @param mtiByte
- * @param ret <code>SubmitPdu</code> containing the encoded SC
- * address, if applicable, and the encoded message
- */
- private static ByteArrayOutputStream getSubmitPduHead(
- String scAddress, String destinationAddress, byte mtiByte,
- boolean statusReportRequested, SubmitPdu ret) {
- ByteArrayOutputStream bo = new ByteArrayOutputStream(
- MAX_USER_DATA_BYTES + 40);
-
- // SMSC address with length octet, or 0
- if (scAddress == null) {
- ret.encodedScAddress = null;
- } else {
- ret.encodedScAddress = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(
- scAddress);
- }
-
- // TP-Message-Type-Indicator (and friends)
- if (statusReportRequested) {
- // Set TP-Status-Report-Request bit.
- mtiByte |= 0x20;
- if (false) Log.d(LOG_TAG, "SMS status report requested");
- }
- bo.write(mtiByte);
-
- // space for TP-Message-Reference
- bo.write(0);
-
- byte[] daBytes;
-
- daBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(destinationAddress);
-
- // destination address length in BCD digits, ignoring TON byte and pad
- // TODO Should be better.
- bo.write((daBytes.length - 1) * 2
- - ((daBytes[daBytes.length - 1] & 0xf0) == 0xf0 ? 1 : 0));
-
- // destination address
- bo.write(daBytes, 0, daBytes.length);
-
- // TP-Protocol-Identifier
- bo.write(0);
- return bo;
- }
-
- private static class PduParser {
- byte pdu[];
- int cur;
- SmsHeader userDataHeader;
- byte[] userData;
- int mUserDataSeptetPadding;
- int mUserDataSize;
-
- PduParser(byte[] pdu) {
- this.pdu = pdu;
- cur = 0;
- mUserDataSeptetPadding = 0;
- }
-
- /**
- * Parse and return the SC address prepended to SMS messages coming via
- * the TS 27.005 / AT interface. Returns null on invalid address
- */
- String getSCAddress() {
- int len;
- String ret;
-
- // length of SC Address
- len = getByte();
-
- if (len == 0) {
- // no SC address
- ret = null;
- } else {
- // SC address
- try {
- ret = PhoneNumberUtils
- .calledPartyBCDToString(pdu, cur, len);
- } catch (RuntimeException tr) {
- Log.d(LOG_TAG, "invalid SC address: ", tr);
- ret = null;
- }
- }
-
- cur += len;
-
- return ret;
- }
-
- /**
- * returns non-sign-extended byte value
- */
- int getByte() {
- return pdu[cur++] & 0xff;
- }
-
- /**
- * Any address except the SC address (eg, originating address) See TS
- * 23.040 9.1.2.5
- */
- GsmSmsAddress getAddress() {
- GsmSmsAddress ret;
-
- // "The Address-Length field is an integer representation of
- // the number field, i.e. excludes any semi-octet containing only
- // fill bits."
- // The TOA field is not included as part of this
- int addressLength = pdu[cur] & 0xff;
- int lengthBytes = 2 + (addressLength + 1) / 2;
-
- ret = new GsmSmsAddress(pdu, cur, lengthBytes);
-
- cur += lengthBytes;
-
- return ret;
- }
-
- /**
- * Parses an SC timestamp and returns a currentTimeMillis()-style
- * timestamp
- */
-
- long getSCTimestampMillis() {
- // TP-Service-Centre-Time-Stamp
- int year = IccUtils.gsmBcdByteToInt(pdu[cur++]);
- int month = IccUtils.gsmBcdByteToInt(pdu[cur++]);
- int day = IccUtils.gsmBcdByteToInt(pdu[cur++]);
- int hour = IccUtils.gsmBcdByteToInt(pdu[cur++]);
- int minute = IccUtils.gsmBcdByteToInt(pdu[cur++]);
- int second = IccUtils.gsmBcdByteToInt(pdu[cur++]);
-
- // For the timezone, the most significant bit of the
- // least significant nibble is the sign byte
- // (meaning the max range of this field is 79 quarter-hours,
- // which is more than enough)
-
- byte tzByte = pdu[cur++];
-
- // Mask out sign bit.
- int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
-
- timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
-
- Time time = new Time(Time.TIMEZONE_UTC);
-
- // It's 2006. Should I really support years < 2000?
- time.year = year >= 90 ? year + 1900 : year + 2000;
- time.month = month - 1;
- time.monthDay = day;
- time.hour = hour;
- time.minute = minute;
- time.second = second;
-
- // Timezone offset is in quarter hours.
- return time.toMillis(true) - (timezoneOffset * 15 * 60 * 1000);
- }
-
- /**
- * Pulls the user data out of the PDU, and separates the payload from
- * the header if there is one.
- *
- * @param hasUserDataHeader true if there is a user data header
- * @param dataInSeptets true if the data payload is in septets instead
- * of octets
- * @return the number of septets or octets in the user data payload
- */
- int constructUserData(boolean hasUserDataHeader, boolean dataInSeptets) {
- int offset = cur;
- int userDataLength = pdu[offset++] & 0xff;
- int headerSeptets = 0;
- int userDataHeaderLength = 0;
-
- if (hasUserDataHeader) {
- userDataHeaderLength = pdu[offset++] & 0xff;
-
- byte[] udh = new byte[userDataHeaderLength];
- System.arraycopy(pdu, offset, udh, 0, userDataHeaderLength);
- userDataHeader = SmsHeader.fromByteArray(udh);
- offset += userDataHeaderLength;
-
- int headerBits = (userDataHeaderLength + 1) * 8;
- headerSeptets = headerBits / 7;
- headerSeptets += (headerBits % 7) > 0 ? 1 : 0;
- mUserDataSeptetPadding = (headerSeptets * 7) - headerBits;
- }
-
- int bufferLen;
- if (dataInSeptets) {
- /*
- * Here we just create the user data length to be the remainder of
- * the pdu minus the user data header, since userDataLength means
- * the number of uncompressed septets.
- */
- bufferLen = pdu.length - offset;
- } else {
- /*
- * userDataLength is the count of octets, so just subtract the
- * user data header.
- */
- bufferLen = userDataLength - (hasUserDataHeader ? (userDataHeaderLength + 1) : 0);
- if (bufferLen < 0) {
- bufferLen = 0;
- }
- }
-
- userData = new byte[bufferLen];
- System.arraycopy(pdu, offset, userData, 0, userData.length);
- cur = offset;
-
- if (dataInSeptets) {
- // Return the number of septets
- int count = userDataLength - headerSeptets;
- // If count < 0, return 0 (means UDL was probably incorrect)
- return count < 0 ? 0 : count;
- } else {
- // Return the number of octets
- return userData.length;
- }
- }
-
- /**
- * Returns the user data payload, not including the headers
- *
- * @return the user data payload, not including the headers
- */
- byte[] getUserData() {
- return userData;
- }
-
- /**
- * Returns the number of padding bits at the beginning of the user data
- * array before the start of the septets.
- *
- * @return the number of padding bits at the beginning of the user data
- * array before the start of the septets
- */
- int getUserDataSeptetPadding() {
- return mUserDataSeptetPadding;
- }
-
- /**
- * Returns an object representing the user data headers
- *
- * {@hide}
- */
- SmsHeader getUserDataHeader() {
- return userDataHeader;
- }
-
- /**
- * Interprets the user data payload as packed GSM 7bit characters, and
- * decodes them into a String.
- *
- * @param septetCount the number of septets in the user data payload
- * @return a String with the decoded characters
- */
- String getUserDataGSM7Bit(int septetCount, int languageTable,
- int languageShiftTable) {
- String ret;
-
- ret = GsmAlphabet.gsm7BitPackedToString(pdu, cur, septetCount,
- mUserDataSeptetPadding, languageTable, languageShiftTable);
-
- cur += (septetCount * 7) / 8;
-
- return ret;
- }
-
- /**
- * Interprets the user data payload as UCS2 characters, and
- * decodes them into a String.
- *
- * @param byteCount the number of bytes in the user data payload
- * @return a String with the decoded characters
- */
- String getUserDataUCS2(int byteCount) {
- String ret;
-
- try {
- ret = new String(pdu, cur, byteCount, "utf-16");
- } catch (UnsupportedEncodingException ex) {
- ret = "";
- Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex);
- }
-
- cur += byteCount;
- return ret;
- }
-
- /**
- * Interprets the user data payload as KSC-5601 characters, and
- * decodes them into a String.
- *
- * @param byteCount the number of bytes in the user data payload
- * @return a String with the decoded characters
- */
- String getUserDataKSC5601(int byteCount) {
- String ret;
-
- try {
- ret = new String(pdu, cur, byteCount, "KSC5601");
- } catch (UnsupportedEncodingException ex) {
- ret = "";
- Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex);
- }
-
- cur += byteCount;
- return ret;
- }
-
- boolean moreDataPresent() {
- return (pdu.length > cur);
- }
- }
-
- /**
- * Calculate the number of septets needed to encode the message.
- *
- * @param msgBody the message to encode
- * @param use7bitOnly ignore (but still count) illegal characters if true
- * @return TextEncodingDetails
- */
- public static TextEncodingDetails calculateLength(CharSequence msgBody,
- boolean use7bitOnly) {
- TextEncodingDetails ted = GsmAlphabet.countGsmSeptets(msgBody, use7bitOnly);
- if (ted == null) {
- ted = new TextEncodingDetails();
- int octets = msgBody.length() * 2;
- ted.codeUnitCount = msgBody.length();
- if (octets > MAX_USER_DATA_BYTES) {
- ted.msgCount = (octets + (MAX_USER_DATA_BYTES_WITH_HEADER - 1)) /
- MAX_USER_DATA_BYTES_WITH_HEADER;
- ted.codeUnitsRemaining = ((ted.msgCount *
- MAX_USER_DATA_BYTES_WITH_HEADER) - octets) / 2;
- } else {
- ted.msgCount = 1;
- ted.codeUnitsRemaining = (MAX_USER_DATA_BYTES - octets)/2;
- }
- ted.codeUnitSize = ENCODING_16BIT;
- }
- return ted;
- }
-
- /** {@inheritDoc} */
- @Override
- public int getProtocolIdentifier() {
- return protocolIdentifier;
- }
-
- /**
- * Returns the TP-Data-Coding-Scheme byte, for acknowledgement of SMS-PP download messages.
- * @return the TP-DCS field of the SMS header
- */
- int getDataCodingScheme() {
- return dataCodingScheme;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isReplace() {
- return (protocolIdentifier & 0xc0) == 0x40
- && (protocolIdentifier & 0x3f) > 0
- && (protocolIdentifier & 0x3f) < 8;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isCphsMwiMessage() {
- return ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear()
- || ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet();
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isMWIClearMessage() {
- if (isMwi && !mwiSense) {
- return true;
- }
-
- return originatingAddress != null
- && ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageClear();
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isMWISetMessage() {
- if (isMwi && mwiSense) {
- return true;
- }
-
- return originatingAddress != null
- && ((GsmSmsAddress) originatingAddress).isCphsVoiceMessageSet();
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isMwiDontStore() {
- if (isMwi && mwiDontStore) {
- return true;
- }
-
- if (isCphsMwiMessage()) {
- // See CPHS 4.2 Section B.4.2.1
- // If the user data is a single space char, do not store
- // the message. Otherwise, store and display as usual
- if (" ".equals(getMessageBody())) {
- ;
- }
- return true;
- }
-
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public int getStatus() {
- return status;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isStatusReportMessage() {
- return isStatusReportMessage;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean isReplyPathPresent() {
- return replyPathPresent;
- }
-
- /**
- * TS 27.005 3.1, <pdu> definition "In the case of SMS: 3GPP TS 24.011 [6]
- * SC address followed by 3GPP TS 23.040 [3] TPDU in hexadecimal format:
- * ME/TA converts each octet of TP data unit into two IRA character long
- * hex number (e.g. octet with integer value 42 is presented to TE as two
- * characters 2A (IRA 50 and 65))" ...in the case of cell broadcast,
- * something else...
- */
- private void parsePdu(byte[] pdu) {
- mPdu = pdu;
- // Log.d(LOG_TAG, "raw sms message:");
- // Log.d(LOG_TAG, s);
-
- PduParser p = new PduParser(pdu);
-
- scAddress = p.getSCAddress();
-
- if (scAddress != null) {
- if (false) Log.d(LOG_TAG, "SMS SC address: " + scAddress);
- }
-
- // TODO(mkf) support reply path, user data header indicator
-
- // TP-Message-Type-Indicator
- // 9.2.3
- int firstByte = p.getByte();
-
- mti = firstByte & 0x3;
- switch (mti) {
- // TP-Message-Type-Indicator
- // 9.2.3
- case 0:
- case 3: //GSM 03.40 9.2.3.1: MTI == 3 is Reserved.
- //This should be processed in the same way as MTI == 0 (Deliver)
- parseSmsDeliver(p, firstByte);
- break;
- case 2:
- parseSmsStatusReport(p, firstByte);
- break;
- default:
- // TODO(mkf) the rest of these
- throw new RuntimeException("Unsupported message type");
- }
- }
-
- /**
- * Parses a SMS-STATUS-REPORT message.
- *
- * @param p A PduParser, cued past the first byte.
- * @param firstByte The first byte of the PDU, which contains MTI, etc.
- */
- private void parseSmsStatusReport(PduParser p, int firstByte) {
- isStatusReportMessage = true;
-
- // TP-Status-Report-Qualifier bit == 0 for SUBMIT
- forSubmit = (firstByte & 0x20) == 0x00;
- // TP-Message-Reference
- messageRef = p.getByte();
- // TP-Recipient-Address
- recipientAddress = p.getAddress();
- // TP-Service-Centre-Time-Stamp
- scTimeMillis = p.getSCTimestampMillis();
- // TP-Discharge-Time
- dischargeTimeMillis = p.getSCTimestampMillis();
- // TP-Status
- status = p.getByte();
-
- // The following are optional fields that may or may not be present.
- if (p.moreDataPresent()) {
- // TP-Parameter-Indicator
- int extraParams = p.getByte();
- int moreExtraParams = extraParams;
- while ((moreExtraParams & 0x80) != 0) {
- // We only know how to parse a few extra parameters, all
- // indicated in the first TP-PI octet, so skip over any
- // additional TP-PI octets.
- moreExtraParams = p.getByte();
- }
- // TP-Protocol-Identifier
- if ((extraParams & 0x01) != 0) {
- protocolIdentifier = p.getByte();
- }
- // TP-Data-Coding-Scheme
- if ((extraParams & 0x02) != 0) {
- dataCodingScheme = p.getByte();
- }
- // TP-User-Data-Length (implies existence of TP-User-Data)
- if ((extraParams & 0x04) != 0) {
- boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;
- parseUserData(p, hasUserDataHeader);
- }
- }
- }
-
- private void parseSmsDeliver(PduParser p, int firstByte) {
- replyPathPresent = (firstByte & 0x80) == 0x80;
-
- originatingAddress = p.getAddress();
-
- if (originatingAddress != null) {
- if (false) Log.v(LOG_TAG, "SMS originating address: "
- + originatingAddress.address);
- }
-
- // TP-Protocol-Identifier (TP-PID)
- // TS 23.040 9.2.3.9
- protocolIdentifier = p.getByte();
-
- // TP-Data-Coding-Scheme
- // see TS 23.038
- dataCodingScheme = p.getByte();
-
- if (false) {
- Log.v(LOG_TAG, "SMS TP-PID:" + protocolIdentifier
- + " data coding scheme: " + dataCodingScheme);
- }
-
- scTimeMillis = p.getSCTimestampMillis();
-
- if (false) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
-
- boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;
-
- parseUserData(p, hasUserDataHeader);
- }
-
- /**
- * Parses the User Data of an SMS.
- *
- * @param p The current PduParser.
- * @param hasUserDataHeader Indicates whether a header is present in the
- * User Data.
- */
- private void parseUserData(PduParser p, boolean hasUserDataHeader) {
- boolean hasMessageClass = false;
- boolean userDataCompressed = false;
-
- int encodingType = ENCODING_UNKNOWN;
-
- // Look up the data encoding scheme
- if ((dataCodingScheme & 0x80) == 0) {
- // Bits 7..4 == 0xxx
- automaticDeletion = (0 != (dataCodingScheme & 0x40));
- userDataCompressed = (0 != (dataCodingScheme & 0x20));
- hasMessageClass = (0 != (dataCodingScheme & 0x10));
-
- if (userDataCompressed) {
- Log.w(LOG_TAG, "4 - Unsupported SMS data coding scheme "
- + "(compression) " + (dataCodingScheme & 0xff));
- } else {
- switch ((dataCodingScheme >> 2) & 0x3) {
- case 0: // GSM 7 bit default alphabet
- encodingType = ENCODING_7BIT;
- break;
-
- case 2: // UCS 2 (16bit)
- encodingType = ENCODING_16BIT;
- break;
-
- case 1: // 8 bit data
- case 3: // reserved
- Log.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
- + (dataCodingScheme & 0xff));
- encodingType = ENCODING_8BIT;
- break;
- }
- }
- } else if ((dataCodingScheme & 0xf0) == 0xf0) {
- automaticDeletion = false;
- hasMessageClass = true;
- userDataCompressed = false;
-
- if (0 == (dataCodingScheme & 0x04)) {
- // GSM 7 bit default alphabet
- encodingType = ENCODING_7BIT;
- } else {
- // 8 bit data
- encodingType = ENCODING_8BIT;
- }
- } else if ((dataCodingScheme & 0xF0) == 0xC0
- || (dataCodingScheme & 0xF0) == 0xD0
- || (dataCodingScheme & 0xF0) == 0xE0) {
- // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
-
- // 0xC0 == 7 bit, don't store
- // 0xD0 == 7 bit, store
- // 0xE0 == UCS-2, store
-
- if ((dataCodingScheme & 0xF0) == 0xE0) {
- encodingType = ENCODING_16BIT;
- } else {
- encodingType = ENCODING_7BIT;
- }
-
- userDataCompressed = false;
- boolean active = ((dataCodingScheme & 0x08) == 0x08);
-
- // bit 0x04 reserved
-
- if ((dataCodingScheme & 0x03) == 0x00) {
- isMwi = true;
- mwiSense = active;
- mwiDontStore = ((dataCodingScheme & 0xF0) == 0xC0);
- } else {
- isMwi = false;
-
- Log.w(LOG_TAG, "MWI for fax, email, or other "
- + (dataCodingScheme & 0xff));
- }
- } else if ((dataCodingScheme & 0xC0) == 0x80) {
- // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
- // 0x80..0xBF == Reserved coding groups
- if (dataCodingScheme == 0x84) {
- // This value used for KSC5601 by carriers in Korea.
- encodingType = ENCODING_KSC5601;
- } else {
- Log.w(LOG_TAG, "5 - Unsupported SMS data coding scheme "
- + (dataCodingScheme & 0xff));
- }
- } else {
- Log.w(LOG_TAG, "3 - Unsupported SMS data coding scheme "
- + (dataCodingScheme & 0xff));
- }
-
- // set both the user data and the user data header.
- int count = p.constructUserData(hasUserDataHeader,
- encodingType == ENCODING_7BIT);
- this.userData = p.getUserData();
- this.userDataHeader = p.getUserDataHeader();
-
- switch (encodingType) {
- case ENCODING_UNKNOWN:
- case ENCODING_8BIT:
- messageBody = null;
- break;
-
- case ENCODING_7BIT:
- messageBody = p.getUserDataGSM7Bit(count,
- hasUserDataHeader ? userDataHeader.languageTable : 0,
- hasUserDataHeader ? userDataHeader.languageShiftTable : 0);
- break;
-
- case ENCODING_16BIT:
- messageBody = p.getUserDataUCS2(count);
- break;
-
- case ENCODING_KSC5601:
- messageBody = p.getUserDataKSC5601(count);
- break;
- }
-
- if (false) Log.v(LOG_TAG, "SMS message body (raw): '" + messageBody + "'");
-
- if (messageBody != null) {
- parseMessageBody();
- }
-
- if (!hasMessageClass) {
- messageClass = MessageClass.UNKNOWN;
- } else {
- switch (dataCodingScheme & 0x3) {
- case 0:
- messageClass = MessageClass.CLASS_0;
- break;
- case 1:
- messageClass = MessageClass.CLASS_1;
- break;
- case 2:
- messageClass = MessageClass.CLASS_2;
- break;
- case 3:
- messageClass = MessageClass.CLASS_3;
- break;
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MessageClass getMessageClass() {
- return messageClass;
- }
-
- /**
- * Returns true if this is a (U)SIM data download type SM.
- * See 3GPP TS 31.111 section 9.1 and TS 23.040 section 9.2.3.9.
- *
- * @return true if this is a USIM data download message; false otherwise
- */
- boolean isUsimDataDownload() {
- return messageClass == MessageClass.CLASS_2 &&
- (protocolIdentifier == 0x7f || protocolIdentifier == 0x7c);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java b/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
deleted file mode 100644
index 918c2d2..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SpnOverride.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2009 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.gsm;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.os.Environment;
-import android.util.Log;
-import android.util.Xml;
-
-import com.android.internal.util.XmlUtils;
-
-public class SpnOverride {
- private HashMap<String, String> CarrierSpnMap;
-
-
- static final String LOG_TAG = "GSM";
- static final String PARTNER_SPN_OVERRIDE_PATH ="etc/spn-conf.xml";
-
- SpnOverride () {
- CarrierSpnMap = new HashMap<String, String>();
- loadSpnOverrides();
- }
-
- boolean containsCarrier(String carrier) {
- return CarrierSpnMap.containsKey(carrier);
- }
-
- String getSpn(String carrier) {
- return CarrierSpnMap.get(carrier);
- }
-
- private void loadSpnOverrides() {
- FileReader spnReader;
-
- final File spnFile = new File(Environment.getRootDirectory(),
- PARTNER_SPN_OVERRIDE_PATH);
-
- try {
- spnReader = new FileReader(spnFile);
- } catch (FileNotFoundException e) {
- Log.w(LOG_TAG, "Can't open " +
- Environment.getRootDirectory() + "/" + PARTNER_SPN_OVERRIDE_PATH);
- return;
- }
-
- try {
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(spnReader);
-
- XmlUtils.beginDocument(parser, "spnOverrides");
-
- while (true) {
- XmlUtils.nextElement(parser);
-
- String name = parser.getName();
- if (!"spnOverride".equals(name)) {
- break;
- }
-
- String numeric = parser.getAttributeValue(null, "numeric");
- String data = parser.getAttributeValue(null, "spn");
-
- CarrierSpnMap.put(numeric, data);
- }
- } catch (XmlPullParserException e) {
- Log.w(LOG_TAG, "Exception in spn-conf parser " + e);
- } catch (IOException e) {
- Log.w(LOG_TAG, "Exception in spn-conf parser " + e);
- }
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
deleted file mode 100644
index e68655e..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.gsm;
-
-import android.telephony.PhoneNumberUtils;
-
-/**
- * Represents a Supplementary Service Notification received from the network.
- *
- * {@hide}
- */
-public class SuppServiceNotification {
- /** Type of notification: 0 = MO; 1 = MT */
- public int notificationType;
- /** TS 27.007 7.17 "code1" or "code2" */
- public int code;
- /** TS 27.007 7.17 "index" */
- public int index;
- /** TS 27.007 7.17 "type" (MT only) */
- public int type;
- /** TS 27.007 7.17 "number" (MT only) */
- public String number;
-
- static public final int MO_CODE_UNCONDITIONAL_CF_ACTIVE = 0;
- static public final int MO_CODE_SOME_CF_ACTIVE = 1;
- static public final int MO_CODE_CALL_FORWARDED = 2;
- static public final int MO_CODE_CALL_IS_WAITING = 3;
- static public final int MO_CODE_CUG_CALL = 4;
- static public final int MO_CODE_OUTGOING_CALLS_BARRED = 5;
- static public final int MO_CODE_INCOMING_CALLS_BARRED = 6;
- static public final int MO_CODE_CLIR_SUPPRESSION_REJECTED = 7;
- static public final int MO_CODE_CALL_DEFLECTED = 8;
-
- static public final int MT_CODE_FORWARDED_CALL = 0;
- static public final int MT_CODE_CUG_CALL = 1;
- static public final int MT_CODE_CALL_ON_HOLD = 2;
- static public final int MT_CODE_CALL_RETRIEVED = 3;
- static public final int MT_CODE_MULTI_PARTY_CALL = 4;
- static public final int MT_CODE_ON_HOLD_CALL_RELEASED = 5;
- static public final int MT_CODE_FORWARD_CHECK_RECEIVED = 6;
- static public final int MT_CODE_CALL_CONNECTING_ECT = 7;
- static public final int MT_CODE_CALL_CONNECTED_ECT = 8;
- static public final int MT_CODE_DEFLECTED_CALL = 9;
- static public final int MT_CODE_ADDITIONAL_CALL_FORWARDED = 10;
-
- public String toString()
- {
- return super.toString() + " mobile"
- + (notificationType == 0 ? " originated " : " terminated ")
- + " code: " + code
- + " index: " + index
- + " \""
- + PhoneNumberUtils.stringFromStringAndTOA(number, type) + "\" ";
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java b/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java
deleted file mode 100644
index f47ff1b..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/UsimDataDownloadHandler.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2011 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.gsm;
-
-import android.app.Activity;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Telephony.Sms.Intents;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccIoResult;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.cat.ComprehensionTlvTag;
-
-/**
- * Handler for SMS-PP data download messages.
- * See 3GPP TS 31.111 section 7.1.1
- */
-public class UsimDataDownloadHandler extends Handler {
- private static final String TAG = "UsimDataDownloadHandler";
-
- /** BER-TLV tag for SMS-PP download. TS 31.111 section 9.1. */
- private static final int BER_SMS_PP_DOWNLOAD_TAG = 0xd1;
-
- /** Device identity value for UICC (destination). */
- private static final int DEV_ID_UICC = 0x81;
-
- /** Device identity value for network (source). */
- private static final int DEV_ID_NETWORK = 0x83;
-
- /** Message containing new SMS-PP message to process. */
- private static final int EVENT_START_DATA_DOWNLOAD = 1;
-
- /** Response to SMS-PP download envelope command. */
- private static final int EVENT_SEND_ENVELOPE_RESPONSE = 2;
-
- private final CommandsInterface mCI;
-
- public UsimDataDownloadHandler(CommandsInterface commandsInterface) {
- mCI = commandsInterface;
- }
-
- /**
- * Start an SMS-PP data download for the specified message. Can be called from a different
- * thread than this Handler is running on.
- *
- * @param smsMessage the message to process
- * @return Activity.RESULT_OK on success; Intents.RESULT_SMS_GENERIC_ERROR on failure
- */
- public int startDataDownload(SmsMessage smsMessage) {
- if (sendMessage(obtainMessage(EVENT_START_DATA_DOWNLOAD, smsMessage))) {
- return Activity.RESULT_OK; // we will send SMS ACK/ERROR based on UICC response
- } else {
- Log.e(TAG, "startDataDownload failed to send message to start data download.");
- return Intents.RESULT_SMS_GENERIC_ERROR;
- }
- }
-
- private void handleDataDownload(SmsMessage smsMessage) {
- int dcs = smsMessage.getDataCodingScheme();
- int pid = smsMessage.getProtocolIdentifier();
- byte[] pdu = smsMessage.getPdu(); // includes SC address
-
- int scAddressLength = pdu[0] & 0xff;
- int tpduIndex = scAddressLength + 1; // start of TPDU
- int tpduLength = pdu.length - tpduIndex;
-
- int bodyLength = getEnvelopeBodyLength(scAddressLength, tpduLength);
-
- // Add 1 byte for SMS-PP download tag and 1-2 bytes for BER-TLV length.
- // See ETSI TS 102 223 Annex C for encoding of length and tags.
- int totalLength = bodyLength + 1 + (bodyLength > 127 ? 2 : 1);
-
- byte[] envelope = new byte[totalLength];
- int index = 0;
-
- // SMS-PP download tag and length (assumed to be < 256 bytes).
- envelope[index++] = (byte) BER_SMS_PP_DOWNLOAD_TAG;
- if (bodyLength > 127) {
- envelope[index++] = (byte) 0x81; // length 128-255 encoded as 0x81 + length
- }
- envelope[index++] = (byte) bodyLength;
-
- // Device identities TLV
- envelope[index++] = (byte) (0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value());
- envelope[index++] = (byte) 2;
- envelope[index++] = (byte) DEV_ID_NETWORK;
- envelope[index++] = (byte) DEV_ID_UICC;
-
- // Address TLV (if present). Encoded length is assumed to be < 127 bytes.
- if (scAddressLength != 0) {
- envelope[index++] = (byte) ComprehensionTlvTag.ADDRESS.value();
- envelope[index++] = (byte) scAddressLength;
- System.arraycopy(pdu, 1, envelope, index, scAddressLength);
- index += scAddressLength;
- }
-
- // SMS TPDU TLV. Length is assumed to be < 256 bytes.
- envelope[index++] = (byte) (0x80 | ComprehensionTlvTag.SMS_TPDU.value());
- if (tpduLength > 127) {
- envelope[index++] = (byte) 0x81; // length 128-255 encoded as 0x81 + length
- }
- envelope[index++] = (byte) tpduLength;
- System.arraycopy(pdu, tpduIndex, envelope, index, tpduLength);
- index += tpduLength;
-
- // Verify that we calculated the payload size correctly.
- if (index != envelope.length) {
- Log.e(TAG, "startDataDownload() calculated incorrect envelope length, aborting.");
- acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_UNSPECIFIED_ERROR);
- return;
- }
-
- String encodedEnvelope = IccUtils.bytesToHexString(envelope);
- mCI.sendEnvelopeWithStatus(encodedEnvelope, obtainMessage(
- EVENT_SEND_ENVELOPE_RESPONSE, new int[]{ dcs, pid }));
- }
-
- /**
- * Return the size in bytes of the envelope to send to the UICC, excluding the
- * SMS-PP download tag byte and length byte(s). If the size returned is <= 127,
- * the BER-TLV length will be encoded in 1 byte, otherwise 2 bytes are required.
- *
- * @param scAddressLength the length of the SMSC address, or zero if not present
- * @param tpduLength the length of the TPDU from the SMS-PP message
- * @return the number of bytes to allocate for the envelope command
- */
- private static int getEnvelopeBodyLength(int scAddressLength, int tpduLength) {
- // Add 4 bytes for device identities TLV + 1 byte for SMS TPDU tag byte
- int length = tpduLength + 5;
- // Add 1 byte for TPDU length, or 2 bytes if length > 127
- length += (tpduLength > 127 ? 2 : 1);
- // Add length of address tag, if present (+ 2 bytes for tag and length)
- if (scAddressLength != 0) {
- length = length + 2 + scAddressLength;
- }
- return length;
- }
-
- /**
- * Handle the response to the ENVELOPE command.
- * @param response UICC response encoded as hexadecimal digits. First two bytes are the
- * UICC SW1 and SW2 status bytes.
- */
- private void sendSmsAckForEnvelopeResponse(IccIoResult response, int dcs, int pid) {
- int sw1 = response.sw1;
- int sw2 = response.sw2;
-
- boolean success;
- if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
- Log.d(TAG, "USIM data download succeeded: " + response.toString());
- success = true;
- } else if (sw1 == 0x93 && sw2 == 0x00) {
- Log.e(TAG, "USIM data download failed: Toolkit busy");
- acknowledgeSmsWithError(CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_APP_TOOLKIT_BUSY);
- return;
- } else if (sw1 == 0x62 || sw1 == 0x63) {
- Log.e(TAG, "USIM data download failed: " + response.toString());
- success = false;
- } else {
- Log.e(TAG, "Unexpected SW1/SW2 response from UICC: " + response.toString());
- success = false;
- }
-
- byte[] responseBytes = response.payload;
- if (responseBytes == null || responseBytes.length == 0) {
- if (success) {
- mCI.acknowledgeLastIncomingGsmSms(true, 0, null);
- } else {
- acknowledgeSmsWithError(
- CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR);
- }
- return;
- }
-
- byte[] smsAckPdu;
- int index = 0;
- if (success) {
- smsAckPdu = new byte[responseBytes.length + 5];
- smsAckPdu[index++] = 0x00; // TP-MTI, TP-UDHI
- smsAckPdu[index++] = 0x07; // TP-PI: TP-PID, TP-DCS, TP-UDL present
- } else {
- smsAckPdu = new byte[responseBytes.length + 6];
- smsAckPdu[index++] = 0x00; // TP-MTI, TP-UDHI
- smsAckPdu[index++] = (byte)
- CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR; // TP-FCS
- smsAckPdu[index++] = 0x07; // TP-PI: TP-PID, TP-DCS, TP-UDL present
- }
-
- smsAckPdu[index++] = (byte) pid;
- smsAckPdu[index++] = (byte) dcs;
-
- if (is7bitDcs(dcs)) {
- int septetCount = responseBytes.length * 8 / 7;
- smsAckPdu[index++] = (byte) septetCount;
- } else {
- smsAckPdu[index++] = (byte) responseBytes.length;
- }
-
- System.arraycopy(responseBytes, 0, smsAckPdu, index, responseBytes.length);
-
- mCI.acknowledgeIncomingGsmSmsWithPdu(success,
- IccUtils.bytesToHexString(smsAckPdu), null);
- }
-
- private void acknowledgeSmsWithError(int cause) {
- mCI.acknowledgeLastIncomingGsmSms(false, cause, null);
- }
-
- /**
- * Returns whether the DCS is 7 bit. If so, set TP-UDL to the septet count of TP-UD;
- * otherwise, set TP-UDL to the octet count of TP-UD.
- * @param dcs the TP-Data-Coding-Scheme field from the original download SMS
- * @return true if the DCS specifies 7 bit encoding; false otherwise
- */
- private static boolean is7bitDcs(int dcs) {
- // See 3GPP TS 23.038 section 4
- return ((dcs & 0x8C) == 0x00) || ((dcs & 0xF4) == 0xF0);
- }
-
- /**
- * Handle UICC envelope response and send SMS acknowledgement.
- *
- * @param msg the message to handle
- */
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_START_DATA_DOWNLOAD:
- handleDataDownload((SmsMessage) msg.obj);
- break;
-
- case EVENT_SEND_ENVELOPE_RESPONSE:
- AsyncResult ar = (AsyncResult) msg.obj;
-
- if (ar.exception != null) {
- Log.e(TAG, "UICC Send Envelope failure, exception: " + ar.exception);
- acknowledgeSmsWithError(
- CommandsInterface.GSM_SMS_FAIL_CAUSE_USIM_DATA_DOWNLOAD_ERROR);
- return;
- }
-
- int[] dcsPid = (int[]) ar.userObj;
- sendSmsAckForEnvelopeResponse((IccIoResult) ar.result, dcsPid[0], dcsPid[1]);
- break;
-
- default:
- Log.e(TAG, "Ignoring unexpected message, what=" + msg.what);
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
deleted file mode 100755
index 8f5a420..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2009 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.gsm;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.AdnRecord;
-import com.android.internal.telephony.AdnRecordCache;
-import com.android.internal.telephony.IccConstants;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.PhoneBase;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * This class implements reading and parsing USIM records.
- * Refer to Spec 3GPP TS 31.102 for more details.
- *
- * {@hide}
- */
-public class UsimPhoneBookManager extends Handler implements IccConstants {
- private static final String LOG_TAG = "GSM";
- private static final boolean DBG = true;
- private PbrFile mPbrFile;
- private Boolean mIsPbrPresent;
- private IccFileHandler mFh;
- private AdnRecordCache mAdnCache;
- private Object mLock = new Object();
- private ArrayList<AdnRecord> mPhoneBookRecords;
- private boolean mEmailPresentInIap = false;
- private int mEmailTagNumberInIap = 0;
- private ArrayList<byte[]> mIapFileRecord;
- private ArrayList<byte[]> mEmailFileRecord;
- private Map<Integer, ArrayList<String>> mEmailsForAdnRec;
- private boolean mRefreshCache = false;
-
- private static final int EVENT_PBR_LOAD_DONE = 1;
- private static final int EVENT_USIM_ADN_LOAD_DONE = 2;
- private static final int EVENT_IAP_LOAD_DONE = 3;
- private static final int EVENT_EMAIL_LOAD_DONE = 4;
-
- private static final int USIM_TYPE1_TAG = 0xA8;
- private static final int USIM_TYPE2_TAG = 0xA9;
- private static final int USIM_TYPE3_TAG = 0xAA;
- private static final int USIM_EFADN_TAG = 0xC0;
- private static final int USIM_EFIAP_TAG = 0xC1;
- private static final int USIM_EFEXT1_TAG = 0xC2;
- private static final int USIM_EFSNE_TAG = 0xC3;
- private static final int USIM_EFANR_TAG = 0xC4;
- private static final int USIM_EFPBC_TAG = 0xC5;
- private static final int USIM_EFGRP_TAG = 0xC6;
- private static final int USIM_EFAAS_TAG = 0xC7;
- private static final int USIM_EFGSD_TAG = 0xC8;
- private static final int USIM_EFUID_TAG = 0xC9;
- private static final int USIM_EFEMAIL_TAG = 0xCA;
- private static final int USIM_EFCCP1_TAG = 0xCB;
-
- public UsimPhoneBookManager(IccFileHandler fh, AdnRecordCache cache) {
- mFh = fh;
- mPhoneBookRecords = new ArrayList<AdnRecord>();
- mPbrFile = null;
- // We assume its present, after the first read this is updated.
- // So we don't have to read from UICC if its not present on subsequent reads.
- mIsPbrPresent = true;
- mAdnCache = cache;
- }
-
- public void reset() {
- mPhoneBookRecords.clear();
- mIapFileRecord = null;
- mEmailFileRecord = null;
- mPbrFile = null;
- mIsPbrPresent = true;
- mRefreshCache = false;
- }
-
- public ArrayList<AdnRecord> loadEfFilesFromUsim() {
- synchronized (mLock) {
- if (!mPhoneBookRecords.isEmpty()) {
- if (mRefreshCache) {
- mRefreshCache = false;
- refreshCache();
- }
- return mPhoneBookRecords;
- }
-
- if (!mIsPbrPresent) return null;
-
- // Check if the PBR file is present in the cache, if not read it
- // from the USIM.
- if (mPbrFile == null) {
- readPbrFileAndWait();
- }
-
- if (mPbrFile == null) return null;
-
- int numRecs = mPbrFile.mFileIds.size();
- for (int i = 0; i < numRecs; i++) {
- readAdnFileAndWait(i);
- readEmailFileAndWait(i);
- }
- // All EF files are loaded, post the response.
- }
- return mPhoneBookRecords;
- }
-
- private void refreshCache() {
- if (mPbrFile == null) return;
- mPhoneBookRecords.clear();
-
- int numRecs = mPbrFile.mFileIds.size();
- for (int i = 0; i < numRecs; i++) {
- readAdnFileAndWait(i);
- }
- }
-
- public void invalidateCache() {
- mRefreshCache = true;
- }
-
- private void readPbrFileAndWait() {
- mFh.loadEFLinearFixedAll(EF_PBR, obtainMessage(EVENT_PBR_LOAD_DONE));
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- Log.e(LOG_TAG, "Interrupted Exception in readAdnFileAndWait");
- }
- }
-
- private void readEmailFileAndWait(int recNum) {
- Map <Integer,Integer> fileIds;
- fileIds = mPbrFile.mFileIds.get(recNum);
- if (fileIds == null) return;
-
- if (fileIds.containsKey(USIM_EFEMAIL_TAG)) {
- int efid = fileIds.get(USIM_EFEMAIL_TAG);
- // Check if the EFEmail is a Type 1 file or a type 2 file.
- // If mEmailPresentInIap is true, its a type 2 file.
- // So we read the IAP file and then read the email records.
- // instead of reading directly.
- if (mEmailPresentInIap) {
- readIapFileAndWait(fileIds.get(USIM_EFIAP_TAG));
- if (mIapFileRecord == null) {
- Log.e(LOG_TAG, "Error: IAP file is empty");
- return;
- }
- }
- // Read the EFEmail file.
- mFh.loadEFLinearFixedAll(fileIds.get(USIM_EFEMAIL_TAG),
- obtainMessage(EVENT_EMAIL_LOAD_DONE));
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- Log.e(LOG_TAG, "Interrupted Exception in readEmailFileAndWait");
- }
-
- if (mEmailFileRecord == null) {
- Log.e(LOG_TAG, "Error: Email file is empty");
- return;
- }
- updatePhoneAdnRecord();
- }
-
- }
-
- private void readIapFileAndWait(int efid) {
- mFh.loadEFLinearFixedAll(efid, obtainMessage(EVENT_IAP_LOAD_DONE));
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- Log.e(LOG_TAG, "Interrupted Exception in readIapFileAndWait");
- }
- }
-
- private void updatePhoneAdnRecord() {
- if (mEmailFileRecord == null) return;
- int numAdnRecs = mPhoneBookRecords.size();
- if (mIapFileRecord != null) {
- // The number of records in the IAP file is same as the number of records in ADN file.
- // The order of the pointers in an EFIAP shall be the same as the order of file IDs
- // that appear in the TLV object indicated by Tag 'A9' in the reference file record.
- // i.e value of mEmailTagNumberInIap
-
- for (int i = 0; i < numAdnRecs; i++) {
- byte[] record = null;
- try {
- record = mIapFileRecord.get(i);
- } catch (IndexOutOfBoundsException e) {
- Log.e(LOG_TAG, "Error: Improper ICC card: No IAP record for ADN, continuing");
- break;
- }
- int recNum = record[mEmailTagNumberInIap];
-
- if (recNum != -1) {
- String[] emails = new String[1];
- // SIM record numbers are 1 based
- emails[0] = readEmailRecord(recNum - 1);
- AdnRecord rec = mPhoneBookRecords.get(i);
- if (rec != null) {
- rec.setEmails(emails);
- } else {
- // might be a record with only email
- rec = new AdnRecord("", "", emails);
- }
- mPhoneBookRecords.set(i, rec);
- }
- }
- }
-
- // ICC cards can be made such that they have an IAP file but all
- // records are empty. So we read both type 1 and type 2 file
- // email records, just to be sure.
-
- int len = mPhoneBookRecords.size();
- // Type 1 file, the number of records is the same as the number of
- // records in the ADN file.
- if (mEmailsForAdnRec == null) {
- parseType1EmailFile(len);
- }
- for (int i = 0; i < numAdnRecs; i++) {
- ArrayList<String> emailList = null;
- try {
- emailList = mEmailsForAdnRec.get(i);
- } catch (IndexOutOfBoundsException e) {
- break;
- }
- if (emailList == null) continue;
-
- AdnRecord rec = mPhoneBookRecords.get(i);
-
- String[] emails = new String[emailList.size()];
- System.arraycopy(emailList.toArray(), 0, emails, 0, emailList.size());
- rec.setEmails(emails);
- mPhoneBookRecords.set(i, rec);
- }
- }
-
- void parseType1EmailFile(int numRecs) {
- mEmailsForAdnRec = new HashMap<Integer, ArrayList<String>>();
- byte[] emailRec = null;
- for (int i = 0; i < numRecs; i++) {
- try {
- emailRec = mEmailFileRecord.get(i);
- } catch (IndexOutOfBoundsException e) {
- Log.e(LOG_TAG, "Error: Improper ICC card: No email record for ADN, continuing");
- break;
- }
- int adnRecNum = emailRec[emailRec.length - 1];
-
- if (adnRecNum == -1) {
- continue;
- }
-
- String email = readEmailRecord(i);
-
- if (email == null || email.equals("")) {
- continue;
- }
-
- // SIM record numbers are 1 based.
- ArrayList<String> val = mEmailsForAdnRec.get(adnRecNum - 1);
- if (val == null) {
- val = new ArrayList<String>();
- }
- val.add(email);
- // SIM record numbers are 1 based.
- mEmailsForAdnRec.put(adnRecNum - 1, val);
- }
- }
-
- private String readEmailRecord(int recNum) {
- byte[] emailRec = null;
- try {
- emailRec = mEmailFileRecord.get(recNum);
- } catch (IndexOutOfBoundsException e) {
- return null;
- }
-
- // The length of the record is X+2 byte, where X bytes is the email address
- String email = IccUtils.adnStringFieldToString(emailRec, 0, emailRec.length - 2);
- return email;
- }
-
- private void readAdnFileAndWait(int recNum) {
- Map <Integer,Integer> fileIds;
- fileIds = mPbrFile.mFileIds.get(recNum);
- if (fileIds == null || fileIds.isEmpty()) return;
-
-
- int extEf = 0;
- // Only call fileIds.get while EFEXT1_TAG is available
- if (fileIds.containsKey(USIM_EFEXT1_TAG)) {
- extEf = fileIds.get(USIM_EFEXT1_TAG);
- }
-
- mAdnCache.requestLoadAllAdnLike(fileIds.get(USIM_EFADN_TAG),
- extEf, obtainMessage(EVENT_USIM_ADN_LOAD_DONE));
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- Log.e(LOG_TAG, "Interrupted Exception in readAdnFileAndWait");
- }
- }
-
- private void createPbrFile(ArrayList<byte[]> records) {
- if (records == null) {
- mPbrFile = null;
- mIsPbrPresent = false;
- return;
- }
- mPbrFile = new PbrFile(records);
- }
-
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch(msg.what) {
- case EVENT_PBR_LOAD_DONE:
- ar = (AsyncResult) msg.obj;
- if (ar.exception == null) {
- createPbrFile((ArrayList<byte[]>)ar.result);
- }
- synchronized (mLock) {
- mLock.notify();
- }
- break;
- case EVENT_USIM_ADN_LOAD_DONE:
- log("Loading USIM ADN records done");
- ar = (AsyncResult) msg.obj;
- if (ar.exception == null) {
- mPhoneBookRecords.addAll((ArrayList<AdnRecord>)ar.result);
- }
- synchronized (mLock) {
- mLock.notify();
- }
- break;
- case EVENT_IAP_LOAD_DONE:
- log("Loading USIM IAP records done");
- ar = (AsyncResult) msg.obj;
- if (ar.exception == null) {
- mIapFileRecord = ((ArrayList<byte[]>)ar.result);
- }
- synchronized (mLock) {
- mLock.notify();
- }
- break;
- case EVENT_EMAIL_LOAD_DONE:
- log("Loading USIM Email records done");
- ar = (AsyncResult) msg.obj;
- if (ar.exception == null) {
- mEmailFileRecord = ((ArrayList<byte[]>)ar.result);
- }
-
- synchronized (mLock) {
- mLock.notify();
- }
- break;
- }
- }
-
- private class PbrFile {
- // RecNum <EF Tag, efid>
- HashMap<Integer,Map<Integer,Integer>> mFileIds;
-
- PbrFile(ArrayList<byte[]> records) {
- mFileIds = new HashMap<Integer, Map<Integer, Integer>>();
- SimTlv recTlv;
- int recNum = 0;
- for (byte[] record: records) {
- recTlv = new SimTlv(record, 0, record.length);
- parseTag(recTlv, recNum);
- recNum ++;
- }
- }
-
- void parseTag(SimTlv tlv, int recNum) {
- SimTlv tlvEf;
- int tag;
- byte[] data;
- Map<Integer, Integer> val = new HashMap<Integer, Integer>();
- do {
- tag = tlv.getTag();
- switch(tag) {
- case USIM_TYPE1_TAG: // A8
- case USIM_TYPE3_TAG: // AA
- case USIM_TYPE2_TAG: // A9
- data = tlv.getData();
- tlvEf = new SimTlv(data, 0, data.length);
- parseEf(tlvEf, val, tag);
- break;
- }
- } while (tlv.nextObject());
- mFileIds.put(recNum, val);
- }
-
- void parseEf(SimTlv tlv, Map<Integer, Integer> val, int parentTag) {
- int tag;
- byte[] data;
- int tagNumberWithinParentTag = 0;
- do {
- tag = tlv.getTag();
- if (parentTag == USIM_TYPE2_TAG && tag == USIM_EFEMAIL_TAG) {
- mEmailPresentInIap = true;
- mEmailTagNumberInIap = tagNumberWithinParentTag;
- }
- switch(tag) {
- case USIM_EFEMAIL_TAG:
- case USIM_EFADN_TAG:
- case USIM_EFEXT1_TAG:
- case USIM_EFANR_TAG:
- case USIM_EFPBC_TAG:
- case USIM_EFGRP_TAG:
- case USIM_EFAAS_TAG:
- case USIM_EFGSD_TAG:
- case USIM_EFUID_TAG:
- case USIM_EFCCP1_TAG:
- case USIM_EFIAP_TAG:
- case USIM_EFSNE_TAG:
- data = tlv.getData();
- int efid = ((data[0] & 0xFF) << 8) | (data[1] & 0xFF);
- val.put(tag, efid);
- break;
- }
- tagNumberWithinParentTag ++;
- } while(tlv.nextObject());
- }
- }
-
- private void log(String msg) {
- if(DBG) Log.d(LOG_TAG, msg);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java b/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java
deleted file mode 100644
index 3fe200b..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/UsimServiceTable.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2011 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.gsm;
-
-import com.android.internal.telephony.IccServiceTable;
-
-/**
- * Wrapper class for the USIM Service Table EF.
- * See 3GPP TS 31.102 Release 10 section 4.2.8
- */
-public final class UsimServiceTable extends IccServiceTable {
- public enum UsimService {
- PHONEBOOK,
- FDN, // Fixed Dialing Numbers
- FDN_EXTENSION, // FDN extension data in EF_EXT2
- SDN, // Service Dialing Numbers
- SDN_EXTENSION, // SDN extension data in EF_EXT3
- BDN, // Barred Dialing Numbers
- BDN_EXTENSION, // BDN extension data in EF_EXT4
- OUTGOING_CALL_INFO,
- INCOMING_CALL_INFO,
- SM_STORAGE,
- SM_STATUS_REPORTS,
- SM_SERVICE_PARAMS,
- ADVICE_OF_CHARGE,
- CAP_CONFIG_PARAMS_2,
- CB_MESSAGE_ID,
- CB_MESSAGE_ID_RANGES,
- GROUP_ID_LEVEL_1,
- GROUP_ID_LEVEL_2,
- SPN, // Service Provider Name
- USER_PLMN_SELECT,
- MSISDN,
- IMAGE,
- LOCALISED_SERVICE_AREAS,
- EMLPP, // Enhanced Multi-Level Precedence and Preemption
- EMLPP_AUTO_ANSWER,
- RFU,
- GSM_ACCESS,
- DATA_DL_VIA_SMS_PP,
- DATA_DL_VIA_SMS_CB,
- CALL_CONTROL_BY_USIM,
- MO_SMS_CONTROL_BY_USIM,
- RUN_AT_COMMAND,
- IGNORED_1,
- ENABLED_SERVICES_TABLE,
- APN_CONTROL_LIST,
- DEPERSONALISATION_CONTROL_KEYS,
- COOPERATIVE_NETWORK_LIST,
- GSM_SECURITY_CONTEXT,
- CPBCCH_INFO,
- INVESTIGATION_SCAN,
- MEXE,
- OPERATOR_PLMN_SELECT,
- HPLMN_SELECT,
- EXTENSION_5, // Extension data for ICI, OCI, MSISDN in EF_EXT5
- PLMN_NETWORK_NAME,
- OPERATOR_PLMN_LIST,
- MBDN, // Mailbox Dialing Numbers
- MWI_STATUS, // Message Waiting Indication status
- CFI_STATUS, // Call Forwarding Indication status
- IGNORED_2,
- SERVICE_PROVIDER_DISPLAY_INFO,
- MMS_NOTIFICATION,
- MMS_NOTIFICATION_EXTENSION, // MMS Notification extension data in EF_EXT8
- GPRS_CALL_CONTROL_BY_USIM,
- MMS_CONNECTIVITY_PARAMS,
- NETWORK_INDICATION_OF_ALERTING,
- VGCS_GROUP_ID_LIST,
- VBS_GROUP_ID_LIST,
- PSEUDONYM,
- IWLAN_USER_PLMN_SELECT,
- IWLAN_OPERATOR_PLMN_SELECT,
- USER_WSID_LIST,
- OPERATOR_WSID_LIST,
- VGCS_SECURITY,
- VBS_SECURITY,
- WLAN_REAUTH_IDENTITY,
- MM_STORAGE,
- GBA, // Generic Bootstrapping Architecture
- MBMS_SECURITY,
- DATA_DL_VIA_USSD,
- EQUIVALENT_HPLMN,
- TERMINAL_PROFILE_AFTER_UICC_ACTIVATION,
- EQUIVALENT_HPLMN_PRESENTATION,
- LAST_RPLMN_SELECTION_INDICATION,
- OMA_BCAST_PROFILE,
- GBA_LOCAL_KEY_ESTABLISHMENT,
- TERMINAL_APPLICATIONS,
- SPN_ICON,
- PLMN_NETWORK_NAME_ICON,
- USIM_IP_CONNECTION_PARAMS,
- IWLAN_HOME_ID_LIST,
- IWLAN_EQUIVALENT_HPLMN_PRESENTATION,
- IWLAN_HPLMN_PRIORITY_INDICATION,
- IWLAN_LAST_REGISTERED_PLMN,
- EPS_MOBILITY_MANAGEMENT_INFO,
- ALLOWED_CSG_LISTS_AND_INDICATIONS,
- CALL_CONTROL_ON_EPS_PDN_CONNECTION_BY_USIM,
- HPLMN_DIRECT_ACCESS,
- ECALL_DATA,
- OPERATOR_CSG_LISTS_AND_INDICATIONS,
- SM_OVER_IP,
- CSG_DISPLAY_CONTROL,
- IMS_COMMUNICATION_CONTROL_BY_USIM,
- EXTENDED_TERMINAL_APPLICATIONS,
- UICC_ACCESS_TO_IMS,
- NAS_CONFIG_BY_USIM
- }
-
- public UsimServiceTable(byte[] table) {
- super(table);
- }
-
- public boolean isAvailable(UsimService service) {
- return super.isAvailable(service.ordinal());
- }
-
- @Override
- protected String getTag() {
- return "UsimServiceTable";
- }
-
- @Override
- protected Object[] getValues() {
- return UsimService.values();
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java b/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
deleted file mode 100644
index 0e49e35..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.gsm;
-
-import android.os.Environment;
-import android.util.Xml;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.io.FileReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import com.android.internal.util.XmlUtils;
-
-/**
- * {@hide}
- */
-class VoiceMailConstants {
- private HashMap<String, String[]> CarrierVmMap;
-
-
- static final String LOG_TAG = "GSM";
- static final String PARTNER_VOICEMAIL_PATH ="etc/voicemail-conf.xml";
-
- static final int NAME = 0;
- static final int NUMBER = 1;
- static final int TAG = 2;
- static final int SIZE = 3;
-
- VoiceMailConstants () {
- CarrierVmMap = new HashMap<String, String[]>();
- loadVoiceMail();
- }
-
- boolean containsCarrier(String carrier) {
- return CarrierVmMap.containsKey(carrier);
- }
-
- String getCarrierName(String carrier) {
- String[] data = CarrierVmMap.get(carrier);
- return data[NAME];
- }
-
- String getVoiceMailNumber(String carrier) {
- String[] data = CarrierVmMap.get(carrier);
- return data[NUMBER];
- }
-
- String getVoiceMailTag(String carrier) {
- String[] data = CarrierVmMap.get(carrier);
- return data[TAG];
- }
-
- private void loadVoiceMail() {
- FileReader vmReader;
-
- final File vmFile = new File(Environment.getRootDirectory(),
- PARTNER_VOICEMAIL_PATH);
-
- try {
- vmReader = new FileReader(vmFile);
- } catch (FileNotFoundException e) {
- Log.w(LOG_TAG, "Can't open " +
- Environment.getRootDirectory() + "/" + PARTNER_VOICEMAIL_PATH);
- return;
- }
-
- try {
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(vmReader);
-
- XmlUtils.beginDocument(parser, "voicemail");
-
- while (true) {
- XmlUtils.nextElement(parser);
-
- String name = parser.getName();
- if (!"voicemail".equals(name)) {
- break;
- }
-
- String[] data = new String[SIZE];
- String numeric = parser.getAttributeValue(null, "numeric");
- data[NAME] = parser.getAttributeValue(null, "carrier");
- data[NUMBER] = parser.getAttributeValue(null, "vmnumber");
- data[TAG] = parser.getAttributeValue(null, "vmtag");
-
- CarrierVmMap.put(numeric, data);
- }
- } catch (XmlPullParserException e) {
- Log.w(LOG_TAG, "Exception in Voicemail parser " + e);
- } catch (IOException e) {
- Log.w(LOG_TAG, "Exception in Voicemail parser " + e);
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/gsm/package.html b/telephony/java/com/android/internal/telephony/gsm/package.html
deleted file mode 100755
index fed8399..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Provides classes to control or read data from GSM phones.
-@hide
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/ims/IsimRecords.java b/telephony/java/com/android/internal/telephony/ims/IsimRecords.java
deleted file mode 100644
index b8b98b9..0000000
--- a/telephony/java/com/android/internal/telephony/ims/IsimRecords.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 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.ims;
-
-/**
- * {@hide}
- */
-public interface IsimRecords {
-
- /**
- * Return the IMS private user identity (IMPI).
- * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM.
- * @return the IMS private user identity string, or null if not available
- */
- String getIsimImpi();
-
- /**
- * Return the IMS home network domain name.
- * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM.
- * @return the IMS home network domain name, or null if not available
- */
- String getIsimDomain();
-
- /**
- * Return an array of IMS public user identities (IMPU).
- * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM.
- * @return an array of IMS public user identity strings, or null if not available
- */
- String[] getIsimImpu();
-}
diff --git a/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java b/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java
deleted file mode 100644
index ee1a42d..0000000
--- a/telephony/java/com/android/internal/telephony/ims/IsimUiccRecords.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2011 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.ims;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.util.Log;
-
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccRecords;
-import com.android.internal.telephony.gsm.SimTlv;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-
-import static com.android.internal.telephony.IccConstants.EF_DOMAIN;
-import static com.android.internal.telephony.IccConstants.EF_IMPI;
-import static com.android.internal.telephony.IccConstants.EF_IMPU;
-
-/**
- * {@hide}
- */
-public final class IsimUiccRecords implements IsimRecords {
- protected static final String LOG_TAG = "GSM";
-
- private static final boolean DBG = true;
- private static final boolean DUMP_RECORDS = false; // Note: PII is logged when this is true
-
- // ISIM EF records (see 3GPP TS 31.103)
- private String mIsimImpi; // IMS private user identity
- private String mIsimDomain; // IMS home network domain name
- private String[] mIsimImpu; // IMS public user identity(s)
-
- private static final int TAG_ISIM_VALUE = 0x80; // From 3GPP TS 31.103
-
- private class EfIsimImpiLoaded implements IccRecords.IccRecordLoaded {
- public String getEfName() {
- return "EF_ISIM_IMPI";
- }
- public void onRecordLoaded(AsyncResult ar) {
- byte[] data = (byte[]) ar.result;
- mIsimImpi = isimTlvToString(data);
- if (DUMP_RECORDS) log("EF_IMPI=" + mIsimImpi);
- }
- }
-
- private class EfIsimImpuLoaded implements IccRecords.IccRecordLoaded {
- public String getEfName() {
- return "EF_ISIM_IMPU";
- }
- public void onRecordLoaded(AsyncResult ar) {
- ArrayList<byte[]> impuList = (ArrayList<byte[]>) ar.result;
- if (DBG) log("EF_IMPU record count: " + impuList.size());
- mIsimImpu = new String[impuList.size()];
- int i = 0;
- for (byte[] identity : impuList) {
- String impu = isimTlvToString(identity);
- if (DUMP_RECORDS) log("EF_IMPU[" + i + "]=" + impu);
- mIsimImpu[i++] = impu;
- }
- }
- }
-
- private class EfIsimDomainLoaded implements IccRecords.IccRecordLoaded {
- public String getEfName() {
- return "EF_ISIM_DOMAIN";
- }
- public void onRecordLoaded(AsyncResult ar) {
- byte[] data = (byte[]) ar.result;
- mIsimDomain = isimTlvToString(data);
- if (DUMP_RECORDS) log("EF_DOMAIN=" + mIsimDomain);
- }
- }
-
- /**
- * Request the ISIM records to load.
- * @param iccFh the IccFileHandler to load the records from
- * @param h the Handler to which the response message will be sent
- * @return the number of EF record requests that were added
- */
- public int fetchIsimRecords(IccFileHandler iccFh, Handler h) {
- iccFh.loadEFTransparent(EF_IMPI, h.obtainMessage(
- IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpiLoaded()));
- iccFh.loadEFLinearFixedAll(EF_IMPU, h.obtainMessage(
- IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimImpuLoaded()));
- iccFh.loadEFTransparent(EF_DOMAIN, h.obtainMessage(
- IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimDomainLoaded()));
- return 3; // number of EF record load requests
- }
-
- /**
- * ISIM records for IMS are stored inside a Tag-Length-Value record as a UTF-8 string
- * with tag value 0x80.
- * @param record the byte array containing the IMS data string
- * @return the decoded String value, or null if the record can't be decoded
- */
- private static String isimTlvToString(byte[] record) {
- SimTlv tlv = new SimTlv(record, 0, record.length);
- do {
- if (tlv.getTag() == TAG_ISIM_VALUE) {
- return new String(tlv.getData(), Charset.forName("UTF-8"));
- }
- } while (tlv.nextObject());
-
- Log.e(LOG_TAG, "[ISIM] can't find TLV tag in ISIM record, returning null");
- return null;
- }
-
- void log(String s) {
- if (DBG) Log.d(LOG_TAG, "[ISIM] " + s);
- }
-
- void loge(String s) {
- if (DBG) Log.e(LOG_TAG, "[ISIM] " + s);
- }
-
- /**
- * Return the IMS private user identity (IMPI).
- * Returns null if the IMPI hasn't been loaded or isn't present on the ISIM.
- * @return the IMS private user identity string, or null if not available
- */
- public String getIsimImpi() {
- return mIsimImpi;
- }
-
- /**
- * Return the IMS home network domain name.
- * Returns null if the IMS domain hasn't been loaded or isn't present on the ISIM.
- * @return the IMS home network domain name, or null if not available
- */
- public String getIsimDomain() {
- return mIsimDomain;
- }
-
- /**
- * Return an array of IMS public user identities (IMPU).
- * Returns null if the IMPU hasn't been loaded or isn't present on the ISIM.
- * @return an array of IMS public user identity strings, or null if not available
- */
- public String[] getIsimImpu() {
- return (mIsimImpu != null) ? mIsimImpu.clone() : null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipCallBase.java b/telephony/java/com/android/internal/telephony/sip/SipCallBase.java
deleted file mode 100644
index 9050a43..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipCallBase.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 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.sip;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-
-import android.net.sip.SipManager;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-abstract class SipCallBase extends Call {
- protected List<Connection> connections = new ArrayList<Connection>();
-
- protected abstract void setState(State newState);
-
- public List<Connection> getConnections() {
- // FIXME should return Collections.unmodifiableList();
- return connections;
- }
-
- public boolean isMultiparty() {
- return connections.size() > 1;
- }
-
- public String toString() {
- return state.toString() + ":" + super.toString();
- }
-
- void clearDisconnected() {
- for (Iterator<Connection> it = connections.iterator(); it.hasNext(); ) {
- Connection c = it.next();
- if (c.getState() == State.DISCONNECTED) it.remove();
- }
-
- if (connections.isEmpty()) setState(State.IDLE);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
deleted file mode 100644
index 99f4e0f..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (C) 2010 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.sip;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
-
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-/**
- * SIP doesn't need CommandsInterface. The class does nothing but made to work
- * with PhoneBase's constructor.
- */
-class SipCommandInterface extends BaseCommands implements CommandsInterface {
- SipCommandInterface(Context context) {
- super(context);
- }
-
- @Override public void setOnNITZTime(Handler h, int what, Object obj) {
- }
-
- public void getIccCardStatus(Message result) {
- }
-
- public void supplyIccPin(String pin, Message result) {
- }
-
- public void supplyIccPuk(String puk, String newPin, Message result) {
- }
-
- public void supplyIccPin2(String pin, Message result) {
- }
-
- public void supplyIccPuk2(String puk, String newPin2, Message result) {
- }
-
- public void changeIccPin(String oldPin, String newPin, Message result) {
- }
-
- public void changeIccPin2(String oldPin2, String newPin2, Message result) {
- }
-
- public void changeBarringPassword(String facility, String oldPwd,
- String newPwd, Message result) {
- }
-
- public void supplyNetworkDepersonalization(String netpin, Message result) {
- }
-
- public void getCurrentCalls(Message result) {
- }
-
- @Deprecated public void getPDPContextList(Message result) {
- }
-
- public void getDataCallList(Message result) {
- }
-
- public void dial(String address, int clirMode, Message result) {
- }
-
- public void dial(String address, int clirMode, UUSInfo uusInfo,
- Message result) {
- }
-
- public void getIMSI(Message result) {
- }
-
- public void getIMSIForApp(String aid, Message result) {
- }
-
- public void getIMEI(Message result) {
- }
-
- public void getIMEISV(Message result) {
- }
-
-
- public void hangupConnection (int gsmIndex, Message result) {
- }
-
- public void hangupWaitingOrBackground (Message result) {
- }
-
- public void hangupForegroundResumeBackground (Message result) {
- }
-
- public void switchWaitingOrHoldingAndActive (Message result) {
- }
-
- public void conference (Message result) {
- }
-
-
- public void setPreferredVoicePrivacy(boolean enable, Message result) {
- }
-
- public void getPreferredVoicePrivacy(Message result) {
- }
-
- public void separateConnection (int gsmIndex, Message result) {
- }
-
- public void acceptCall (Message result) {
- }
-
- public void rejectCall (Message result) {
- }
-
- public void explicitCallTransfer (Message result) {
- }
-
- public void getLastCallFailCause (Message result) {
- }
-
- /** @deprecated */
- public void getLastPdpFailCause (Message result) {
- }
-
- public void getLastDataCallFailCause (Message result) {
- }
-
- public void setMute (boolean enableMute, Message response) {
- }
-
- public void getMute (Message response) {
- }
-
- public void getSignalStrength (Message result) {
- }
-
- public void getVoiceRegistrationState (Message result) {
- }
-
- public void getDataRegistrationState (Message result) {
- }
-
- public void getOperator(Message result) {
- }
-
- public void sendDtmf(char c, Message result) {
- }
-
- public void startDtmf(char c, Message result) {
- }
-
- public void stopDtmf(Message result) {
- }
-
- public void sendBurstDtmf(String dtmfString, int on, int off,
- Message result) {
- }
-
- public void sendSMS (String smscPDU, String pdu, Message result) {
- }
-
- public void sendCdmaSms(byte[] pdu, Message result) {
- }
-
- public void deleteSmsOnSim(int index, Message response) {
- }
-
- public void deleteSmsOnRuim(int index, Message response) {
- }
-
- public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
- }
-
- public void writeSmsToRuim(int status, String pdu, Message response) {
- }
-
- public void setupDataCall(String radioTechnology, String profile,
- String apn, String user, String password, String authType,
- String protocol, Message result) {
- }
-
- public void deactivateDataCall(int cid, int reason, Message result) {
- }
-
- public void setRadioPower(boolean on, Message result) {
- }
-
- public void setSuppServiceNotifications(boolean enable, Message result) {
- }
-
- public void acknowledgeLastIncomingGsmSms(boolean success, int cause,
- Message result) {
- }
-
- public void acknowledgeLastIncomingCdmaSms(boolean success, int cause,
- Message result) {
- }
-
- public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
- Message result) {
- }
-
- public void iccIO (int command, int fileid, String path, int p1, int p2,
- int p3, String data, String pin2, Message result) {
- }
- public void iccIOForApp (int command, int fileid, String path, int p1, int p2,
- int p3, String data, String pin2, String aid, Message result) {
- }
-
- public void getCLIR(Message result) {
- }
-
- public void setCLIR(int clirMode, Message result) {
- }
-
- public void queryCallWaiting(int serviceClass, Message response) {
- }
-
- public void setCallWaiting(boolean enable, int serviceClass,
- Message response) {
- }
-
- public void setNetworkSelectionModeAutomatic(Message response) {
- }
-
- public void setNetworkSelectionModeManual(
- String operatorNumeric, Message response) {
- }
-
- public void getNetworkSelectionMode(Message response) {
- }
-
- public void getAvailableNetworks(Message response) {
- }
-
- public void setCallForward(int action, int cfReason, int serviceClass,
- String number, int timeSeconds, Message response) {
- }
-
- public void queryCallForwardStatus(int cfReason, int serviceClass,
- String number, Message response) {
- }
-
- public void queryCLIP(Message response) {
- }
-
- public void getBasebandVersion (Message response) {
- }
-
- @Override
- public void queryFacilityLock(String facility, String password,
- int serviceClass, Message response) {
- }
-
- @Override
- public void queryFacilityLockForApp(String facility, String password,
- int serviceClass, String appId, Message response) {
- }
-
- @Override
- public void setFacilityLock(String facility, boolean lockState,
- String password, int serviceClass, Message response) {
- }
-
- @Override
- public void setFacilityLockForApp(String facility, boolean lockState,
- String password, int serviceClass, String appId, Message response) {
- }
-
- public void sendUSSD (String ussdString, Message response) {
- }
-
- public void cancelPendingUssd (Message response) {
- }
-
- public void resetRadio(Message result) {
- }
-
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- }
-
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- }
-
- public void setBandMode (int bandMode, Message response) {
- }
-
- public void queryAvailableBandMode (Message response) {
- }
-
- public void sendTerminalResponse(String contents, Message response) {
- }
-
- public void sendEnvelope(String contents, Message response) {
- }
-
- public void sendEnvelopeWithStatus(String contents, Message response) {
- }
-
- public void handleCallSetupRequestFromSim(
- boolean accept, Message response) {
- }
-
- public void setPreferredNetworkType(int networkType , Message response) {
- }
-
- public void getPreferredNetworkType(Message response) {
- }
-
- public void getNeighboringCids(Message response) {
- }
-
- public void setLocationUpdates(boolean enable, Message response) {
- }
-
- public void getSmscAddress(Message result) {
- }
-
- public void setSmscAddress(String address, Message result) {
- }
-
- public void reportSmsMemoryStatus(boolean available, Message result) {
- }
-
- public void reportStkServiceIsRunning(Message result) {
- }
-
- @Override
- public void getCdmaSubscriptionSource(Message response) {
- }
-
- public void getGsmBroadcastConfig(Message response) {
- }
-
- public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
- }
-
- public void setGsmBroadcastActivation(boolean activate, Message response) {
- }
-
- // ***** Methods for CDMA support
- public void getDeviceIdentity(Message response) {
- }
-
- public void getCDMASubscription(Message response) {
- }
-
- public void setPhoneType(int phoneType) { //Set by CDMAPhone and GSMPhone constructor
- }
-
- public void queryCdmaRoamingPreference(Message response) {
- }
-
- public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
- }
-
- public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
- }
-
- public void queryTTYMode(Message response) {
- }
-
- public void setTTYMode(int ttyMode, Message response) {
- }
-
- public void sendCDMAFeatureCode(String FeatureCode, Message response) {
- }
-
- public void getCdmaBroadcastConfig(Message response) {
- }
-
- public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
- }
-
- public void setCdmaBroadcastActivation(boolean activate, Message response) {
- }
-
- public void exitEmergencyCallbackMode(Message response) {
- }
-
- @Override
- public void supplyIccPinForApp(String pin, String aid, Message response) {
- }
-
- @Override
- public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
- }
-
- @Override
- public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
- }
-
- @Override
- public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
- }
-
- @Override
- public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
- }
-
- @Override
- public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
- Message response) {
- }
-
- public void requestIsimAuthentication(String nonce, Message response) {
- }
-
- public void getVoiceRadioTechnology(Message result) {
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java b/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
deleted file mode 100644
index c83f696..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipConnectionBase.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2010 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.sip;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.UUSInfo;
-
-import android.net.sip.SipAudioCall;
-import android.os.SystemClock;
-import android.util.Log;
-import android.telephony.PhoneNumberUtils;
-
-abstract class SipConnectionBase extends Connection {
- private static final String LOG_TAG = "SIP_CONN";
-
- private SipAudioCall mSipAudioCall;
-
- private String dialString; // outgoing calls only
- private String postDialString; // outgoing calls only
- private int nextPostDialChar; // index into postDialString
- private boolean isIncoming;
-
- /*
- * These time/timespan values are based on System.currentTimeMillis(),
- * i.e., "wall clock" time.
- */
- private long createTime;
- private long connectTime;
- private long disconnectTime;
-
- /*
- * These time/timespan values are based on SystemClock.elapsedRealTime(),
- * i.e., time since boot. They are appropriate for comparison and
- * calculating deltas.
- */
- private long connectTimeReal;
- private long duration = -1L;
- private long holdingStartTime; // The time when the Connection last transitioned
- // into HOLDING
-
- private DisconnectCause mCause = DisconnectCause.NOT_DISCONNECTED;
- private PostDialState postDialState = PostDialState.NOT_STARTED;
-
- SipConnectionBase(String dialString) {
- this.dialString = dialString;
-
- postDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
-
- isIncoming = false;
- createTime = System.currentTimeMillis();
- }
-
- protected void setState(Call.State state) {
- switch (state) {
- case ACTIVE:
- if (connectTime == 0) {
- connectTimeReal = SystemClock.elapsedRealtime();
- connectTime = System.currentTimeMillis();
- }
- break;
- case DISCONNECTED:
- duration = getDurationMillis();
- disconnectTime = System.currentTimeMillis();
- break;
- case HOLDING:
- holdingStartTime = SystemClock.elapsedRealtime();
- break;
- }
- }
-
- @Override
- public long getCreateTime() {
- return createTime;
- }
-
- @Override
- public long getConnectTime() {
- return connectTime;
- }
-
- @Override
- public long getDisconnectTime() {
- return disconnectTime;
- }
-
- @Override
- public long getDurationMillis() {
- if (connectTimeReal == 0) {
- return 0;
- } else if (duration < 0) {
- return SystemClock.elapsedRealtime() - connectTimeReal;
- } else {
- return duration;
- }
- }
-
- @Override
- public long getHoldDurationMillis() {
- if (getState() != Call.State.HOLDING) {
- // If not holding, return 0
- return 0;
- } else {
- return SystemClock.elapsedRealtime() - holdingStartTime;
- }
- }
-
- @Override
- public DisconnectCause getDisconnectCause() {
- return mCause;
- }
-
- void setDisconnectCause(DisconnectCause cause) {
- mCause = cause;
- }
-
- @Override
- public PostDialState getPostDialState() {
- return postDialState;
- }
-
- @Override
- public void proceedAfterWaitChar() {
- // TODO
- }
-
- @Override
- public void proceedAfterWildChar(String str) {
- // TODO
- }
-
- @Override
- public void cancelPostDial() {
- // TODO
- }
-
- protected abstract Phone getPhone();
-
- @Override
- public String getRemainingPostDialString() {
- if (postDialState == PostDialState.CANCELLED
- || postDialState == PostDialState.COMPLETE
- || postDialString == null
- || postDialString.length() <= nextPostDialChar) {
- return "";
- }
-
- return postDialString.substring(nextPostDialChar);
- }
-
- private void log(String msg) {
- Log.d(LOG_TAG, "[SipConn] " + msg);
- }
-
- @Override
- public int getNumberPresentation() {
- // TODO: add PRESENTATION_URL
- return Connection.PRESENTATION_ALLOWED;
- }
-
- @Override
- public UUSInfo getUUSInfo() {
- // FIXME: what's this for SIP?
- return null;
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
deleted file mode 100644
index 5471289..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * Copyright (C) 2010 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.sip;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.net.rtp.AudioGroup;
-import android.net.sip.SipAudioCall;
-import android.net.sip.SipErrorCode;
-import android.net.sip.SipException;
-import android.net.sip.SipManager;
-import android.net.sip.SipProfile;
-import android.net.sip.SipSession;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneNotifier;
-
-import java.text.ParseException;
-import java.util.List;
-import java.util.regex.Pattern;
-
-/**
- * {@hide}
- */
-public class SipPhone extends SipPhoneBase {
- private static final String LOG_TAG = "SipPhone";
- private static final boolean DEBUG = true;
- private static final int TIMEOUT_MAKE_CALL = 15; // in seconds
- private static final int TIMEOUT_ANSWER_CALL = 8; // in seconds
- private static final int TIMEOUT_HOLD_CALL = 15; // in seconds
-
- // A call that is ringing or (call) waiting
- private SipCall ringingCall = new SipCall();
- private SipCall foregroundCall = new SipCall();
- private SipCall backgroundCall = new SipCall();
-
- private SipManager mSipManager;
- private SipProfile mProfile;
-
- SipPhone (Context context, PhoneNotifier notifier, SipProfile profile) {
- super(context, notifier);
-
- if (DEBUG) Log.d(LOG_TAG, "new SipPhone: " + profile.getUriString());
- ringingCall = new SipCall();
- foregroundCall = new SipCall();
- backgroundCall = new SipCall();
- mProfile = profile;
- mSipManager = SipManager.newInstance(context);
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) return true;
- if (!(o instanceof SipPhone)) return false;
- SipPhone that = (SipPhone) o;
- return mProfile.getUriString().equals(that.mProfile.getUriString());
- }
-
- public String getPhoneName() {
- return "SIP:" + getUriString(mProfile);
- }
-
- public String getSipUri() {
- return mProfile.getUriString();
- }
-
- public boolean equals(SipPhone phone) {
- return getSipUri().equals(phone.getSipUri());
- }
-
- public boolean canTake(Object incomingCall) {
- synchronized (SipPhone.class) {
- if (!(incomingCall instanceof SipAudioCall)) return false;
- if (ringingCall.getState().isAlive()) return false;
-
- // FIXME: is it true that we cannot take any incoming call if
- // both foreground and background are active
- if (foregroundCall.getState().isAlive()
- && backgroundCall.getState().isAlive()) {
- return false;
- }
-
- try {
- SipAudioCall sipAudioCall = (SipAudioCall) incomingCall;
- if (DEBUG) Log.d(LOG_TAG, "+++ taking call from: "
- + sipAudioCall.getPeerProfile().getUriString());
- String localUri = sipAudioCall.getLocalProfile().getUriString();
- if (localUri.equals(mProfile.getUriString())) {
- boolean makeCallWait = foregroundCall.getState().isAlive();
- ringingCall.initIncomingCall(sipAudioCall, makeCallWait);
- if (sipAudioCall.getState()
- != SipSession.State.INCOMING_CALL) {
- // Peer cancelled the call!
- if (DEBUG) Log.d(LOG_TAG, " call cancelled !!");
- ringingCall.reset();
- }
- return true;
- }
- } catch (Exception e) {
- // Peer may cancel the call at any time during the time we hook
- // up ringingCall with sipAudioCall. Clean up ringingCall when
- // that happens.
- ringingCall.reset();
- }
- return false;
- }
- }
-
- public void acceptCall() throws CallStateException {
- synchronized (SipPhone.class) {
- if ((ringingCall.getState() == Call.State.INCOMING) ||
- (ringingCall.getState() == Call.State.WAITING)) {
- if (DEBUG) Log.d(LOG_TAG, "acceptCall");
- // Always unmute when answering a new call
- ringingCall.setMute(false);
- ringingCall.acceptCall();
- } else {
- throw new CallStateException("phone not ringing");
- }
- }
- }
-
- public void rejectCall() throws CallStateException {
- synchronized (SipPhone.class) {
- if (ringingCall.getState().isRinging()) {
- if (DEBUG) Log.d(LOG_TAG, "rejectCall");
- ringingCall.rejectCall();
- } else {
- throw new CallStateException("phone not ringing");
- }
- }
- }
-
- public Connection dial(String dialString) throws CallStateException {
- synchronized (SipPhone.class) {
- return dialInternal(dialString);
- }
- }
-
- private Connection dialInternal(String dialString)
- throws CallStateException {
- clearDisconnected();
-
- if (!canDial()) {
- throw new CallStateException("cannot dial in current state");
- }
- if (foregroundCall.getState() == SipCall.State.ACTIVE) {
- switchHoldingAndActive();
- }
- if (foregroundCall.getState() != SipCall.State.IDLE) {
- //we should have failed in !canDial() above before we get here
- throw new CallStateException("cannot dial in current state");
- }
-
- foregroundCall.setMute(false);
- try {
- Connection c = foregroundCall.dial(dialString);
- return c;
- } catch (SipException e) {
- Log.e(LOG_TAG, "dial()", e);
- throw new CallStateException("dial error: " + e);
- }
- }
-
- public void switchHoldingAndActive() throws CallStateException {
- if (DEBUG) Log.d(LOG_TAG, " ~~~~~~ switch fg and bg");
- synchronized (SipPhone.class) {
- foregroundCall.switchWith(backgroundCall);
- if (backgroundCall.getState().isAlive()) backgroundCall.hold();
- if (foregroundCall.getState().isAlive()) foregroundCall.unhold();
- }
- }
-
- public boolean canConference() {
- return true;
- }
-
- public void conference() throws CallStateException {
- synchronized (SipPhone.class) {
- if ((foregroundCall.getState() != SipCall.State.ACTIVE)
- || (foregroundCall.getState() != SipCall.State.ACTIVE)) {
- throw new CallStateException("wrong state to merge calls: fg="
- + foregroundCall.getState() + ", bg="
- + backgroundCall.getState());
- }
- foregroundCall.merge(backgroundCall);
- }
- }
-
- public void conference(Call that) throws CallStateException {
- synchronized (SipPhone.class) {
- if (!(that instanceof SipCall)) {
- throw new CallStateException("expect " + SipCall.class
- + ", cannot merge with " + that.getClass());
- }
- foregroundCall.merge((SipCall) that);
- }
- }
-
- public boolean canTransfer() {
- return false;
- }
-
- public void explicitCallTransfer() throws CallStateException {
- //mCT.explicitCallTransfer();
- }
-
- public void clearDisconnected() {
- synchronized (SipPhone.class) {
- ringingCall.clearDisconnected();
- foregroundCall.clearDisconnected();
- backgroundCall.clearDisconnected();
-
- updatePhoneState();
- notifyPreciseCallStateChanged();
- }
- }
-
- public void sendDtmf(char c) {
- if (!PhoneNumberUtils.is12Key(c)) {
- Log.e(LOG_TAG,
- "sendDtmf called with invalid character '" + c + "'");
- } else if (foregroundCall.getState().isAlive()) {
- synchronized (SipPhone.class) {
- foregroundCall.sendDtmf(c);
- }
- }
- }
-
- public void startDtmf(char c) {
- if (!PhoneNumberUtils.is12Key(c)) {
- Log.e(LOG_TAG,
- "startDtmf called with invalid character '" + c + "'");
- } else {
- sendDtmf(c);
- }
- }
-
- public void stopDtmf() {
- // no op
- }
-
- public void sendBurstDtmf(String dtmfString) {
- Log.e(LOG_TAG, "[SipPhone] sendBurstDtmf() is a CDMA method");
- }
-
- public void getOutgoingCallerIdDisplay(Message onComplete) {
- // FIXME: what to reply?
- AsyncResult.forMessage(onComplete, null, null);
- onComplete.sendToTarget();
- }
-
- public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
- Message onComplete) {
- // FIXME: what's this for SIP?
- AsyncResult.forMessage(onComplete, null, null);
- onComplete.sendToTarget();
- }
-
- public void getCallWaiting(Message onComplete) {
- // FIXME: what to reply?
- AsyncResult.forMessage(onComplete, null, null);
- onComplete.sendToTarget();
- }
-
- public void setCallWaiting(boolean enable, Message onComplete) {
- // FIXME: what to reply?
- Log.e(LOG_TAG, "call waiting not supported");
- }
-
- @Override
- public void setEchoSuppressionEnabled(boolean enabled) {
- // TODO: Remove the enabled argument. We should check the speakerphone
- // state with AudioManager instead of keeping a state here so the
- // method with a state argument is redundant. Also rename the method
- // to something like onSpeaerphoneStateChanged(). Echo suppression may
- // not be available on every device.
- synchronized (SipPhone.class) {
- foregroundCall.setAudioGroupMode();
- }
- }
-
- public void setMute(boolean muted) {
- synchronized (SipPhone.class) {
- foregroundCall.setMute(muted);
- }
- }
-
- public boolean getMute() {
- return (foregroundCall.getState().isAlive()
- ? foregroundCall.getMute()
- : backgroundCall.getMute());
- }
-
- public Call getForegroundCall() {
- return foregroundCall;
- }
-
- public Call getBackgroundCall() {
- return backgroundCall;
- }
-
- public Call getRingingCall() {
- return ringingCall;
- }
-
- public ServiceState getServiceState() {
- // FIXME: we may need to provide this when data connectivity is lost
- // or when server is down
- return super.getServiceState();
- }
-
- private String getUriString(SipProfile p) {
- // SipProfile.getUriString() may contain "SIP:" and port
- return p.getUserName() + "@" + getSipDomain(p);
- }
-
- private String getSipDomain(SipProfile p) {
- String domain = p.getSipDomain();
- // TODO: move this to SipProfile
- if (domain.endsWith(":5060")) {
- return domain.substring(0, domain.length() - 5);
- } else {
- return domain;
- }
- }
-
- private class SipCall extends SipCallBase {
- void reset() {
- connections.clear();
- setState(Call.State.IDLE);
- }
-
- void switchWith(SipCall that) {
- synchronized (SipPhone.class) {
- SipCall tmp = new SipCall();
- tmp.takeOver(this);
- this.takeOver(that);
- that.takeOver(tmp);
- }
- }
-
- private void takeOver(SipCall that) {
- connections = that.connections;
- state = that.state;
- for (Connection c : connections) {
- ((SipConnection) c).changeOwner(this);
- }
- }
-
- @Override
- public Phone getPhone() {
- return SipPhone.this;
- }
-
- @Override
- public List<Connection> getConnections() {
- synchronized (SipPhone.class) {
- // FIXME should return Collections.unmodifiableList();
- return connections;
- }
- }
-
- Connection dial(String originalNumber) throws SipException {
- String calleeSipUri = originalNumber;
- if (!calleeSipUri.contains("@")) {
- String replaceStr = Pattern.quote(mProfile.getUserName() + "@");
- calleeSipUri = mProfile.getUriString().replaceFirst(replaceStr,
- calleeSipUri + "@");
- }
- try {
- SipProfile callee =
- new SipProfile.Builder(calleeSipUri).build();
- SipConnection c = new SipConnection(this, callee,
- originalNumber);
- c.dial();
- connections.add(c);
- setState(Call.State.DIALING);
- return c;
- } catch (ParseException e) {
- throw new SipException("dial", e);
- }
- }
-
- @Override
- public void hangup() throws CallStateException {
- synchronized (SipPhone.class) {
- if (state.isAlive()) {
- if (DEBUG) Log.d(LOG_TAG, "hang up call: " + getState()
- + ": " + this + " on phone " + getPhone());
- setState(State.DISCONNECTING);
- CallStateException excp = null;
- for (Connection c : connections) {
- try {
- c.hangup();
- } catch (CallStateException e) {
- excp = e;
- }
- }
- if (excp != null) throw excp;
- } else {
- if (DEBUG) Log.d(LOG_TAG, "hang up dead call: " + getState()
- + ": " + this + " on phone " + getPhone());
- }
- }
- }
-
- void initIncomingCall(SipAudioCall sipAudioCall, boolean makeCallWait) {
- SipProfile callee = sipAudioCall.getPeerProfile();
- SipConnection c = new SipConnection(this, callee);
- connections.add(c);
-
- Call.State newState = makeCallWait ? State.WAITING : State.INCOMING;
- c.initIncomingCall(sipAudioCall, newState);
-
- setState(newState);
- notifyNewRingingConnectionP(c);
- }
-
- void rejectCall() throws CallStateException {
- hangup();
- }
-
- void acceptCall() throws CallStateException {
- if (this != ringingCall) {
- throw new CallStateException("acceptCall() in a non-ringing call");
- }
- if (connections.size() != 1) {
- throw new CallStateException("acceptCall() in a conf call");
- }
- ((SipConnection) connections.get(0)).acceptCall();
- }
-
- private boolean isSpeakerOn() {
- return ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE))
- .isSpeakerphoneOn();
- }
-
- void setAudioGroupMode() {
- AudioGroup audioGroup = getAudioGroup();
- if (audioGroup == null) return;
- int mode = audioGroup.getMode();
- if (state == State.HOLDING) {
- audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
- } else if (getMute()) {
- audioGroup.setMode(AudioGroup.MODE_MUTED);
- } else if (isSpeakerOn()) {
- audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
- } else {
- audioGroup.setMode(AudioGroup.MODE_NORMAL);
- }
- if (DEBUG) Log.d(LOG_TAG, String.format(
- "audioGroup mode change: %d --> %d", mode,
- audioGroup.getMode()));
- }
-
- void hold() throws CallStateException {
- setState(State.HOLDING);
- for (Connection c : connections) ((SipConnection) c).hold();
- setAudioGroupMode();
- }
-
- void unhold() throws CallStateException {
- setState(State.ACTIVE);
- AudioGroup audioGroup = new AudioGroup();
- for (Connection c : connections) {
- ((SipConnection) c).unhold(audioGroup);
- }
- setAudioGroupMode();
- }
-
- void setMute(boolean muted) {
- for (Connection c : connections) {
- ((SipConnection) c).setMute(muted);
- }
- }
-
- boolean getMute() {
- return connections.isEmpty()
- ? false
- : ((SipConnection) connections.get(0)).getMute();
- }
-
- void merge(SipCall that) throws CallStateException {
- AudioGroup audioGroup = getAudioGroup();
-
- // copy to an array to avoid concurrent modification as connections
- // in that.connections will be removed in add(SipConnection).
- Connection[] cc = that.connections.toArray(
- new Connection[that.connections.size()]);
- for (Connection c : cc) {
- SipConnection conn = (SipConnection) c;
- add(conn);
- if (conn.getState() == Call.State.HOLDING) {
- conn.unhold(audioGroup);
- }
- }
- that.setState(Call.State.IDLE);
- }
-
- private void add(SipConnection conn) {
- SipCall call = conn.getCall();
- if (call == this) return;
- if (call != null) call.connections.remove(conn);
-
- connections.add(conn);
- conn.changeOwner(this);
- }
-
- void sendDtmf(char c) {
- AudioGroup audioGroup = getAudioGroup();
- if (audioGroup == null) return;
- audioGroup.sendDtmf(convertDtmf(c));
- }
-
- private int convertDtmf(char c) {
- int code = c - '0';
- if ((code < 0) || (code > 9)) {
- switch (c) {
- case '*': return 10;
- case '#': return 11;
- case 'A': return 12;
- case 'B': return 13;
- case 'C': return 14;
- case 'D': return 15;
- default:
- throw new IllegalArgumentException(
- "invalid DTMF char: " + (int) c);
- }
- }
- return code;
- }
-
- @Override
- protected void setState(State newState) {
- if (state != newState) {
- if (DEBUG) Log.v(LOG_TAG, "+***+ call state changed: " + state
- + " --> " + newState + ": " + this + ": on phone "
- + getPhone() + " " + connections.size());
-
- if (newState == Call.State.ALERTING) {
- state = newState; // need in ALERTING to enable ringback
- SipPhone.this.startRingbackTone();
- } else if (state == Call.State.ALERTING) {
- SipPhone.this.stopRingbackTone();
- }
- state = newState;
- updatePhoneState();
- notifyPreciseCallStateChanged();
- }
- }
-
- void onConnectionStateChanged(SipConnection conn) {
- // this can be called back when a conf call is formed
- if (state != State.ACTIVE) {
- setState(conn.getState());
- }
- }
-
- void onConnectionEnded(SipConnection conn) {
- // set state to DISCONNECTED only when all conns are disconnected
- if (state != State.DISCONNECTED) {
- boolean allConnectionsDisconnected = true;
- if (DEBUG) Log.d(LOG_TAG, "---check connections: "
- + connections.size());
- for (Connection c : connections) {
- if (DEBUG) Log.d(LOG_TAG, " state=" + c.getState() + ": "
- + c);
- if (c.getState() != State.DISCONNECTED) {
- allConnectionsDisconnected = false;
- break;
- }
- }
- if (allConnectionsDisconnected) setState(State.DISCONNECTED);
- }
- notifyDisconnectP(conn);
- }
-
- private AudioGroup getAudioGroup() {
- if (connections.isEmpty()) return null;
- return ((SipConnection) connections.get(0)).getAudioGroup();
- }
- }
-
- private class SipConnection extends SipConnectionBase {
- private SipCall mOwner;
- private SipAudioCall mSipAudioCall;
- private Call.State mState = Call.State.IDLE;
- private SipProfile mPeer;
- private String mOriginalNumber; // may be a PSTN number
- private boolean mIncoming = false;
-
- private SipAudioCallAdapter mAdapter = new SipAudioCallAdapter() {
- @Override
- protected void onCallEnded(DisconnectCause cause) {
- if (getDisconnectCause() != DisconnectCause.LOCAL) {
- setDisconnectCause(cause);
- }
- synchronized (SipPhone.class) {
- setState(Call.State.DISCONNECTED);
- SipAudioCall sipAudioCall = mSipAudioCall;
- mSipAudioCall = null;
- String sessionState = (sipAudioCall == null)
- ? ""
- : (sipAudioCall.getState() + ", ");
- if (DEBUG) Log.d(LOG_TAG, "--- connection ended: "
- + mPeer.getUriString() + ": " + sessionState
- + "cause: " + getDisconnectCause() + ", on phone "
- + getPhone());
- if (sipAudioCall != null) {
- sipAudioCall.setListener(null);
- sipAudioCall.close();
- }
- mOwner.onConnectionEnded(SipConnection.this);
- }
- }
-
- @Override
- public void onCallEstablished(SipAudioCall call) {
- onChanged(call);
- if (mState == Call.State.ACTIVE) call.startAudio();
- }
-
- @Override
- public void onCallHeld(SipAudioCall call) {
- onChanged(call);
- if (mState == Call.State.HOLDING) call.startAudio();
- }
-
- @Override
- public void onChanged(SipAudioCall call) {
- synchronized (SipPhone.class) {
- Call.State newState = getCallStateFrom(call);
- if (mState == newState) return;
- if (newState == Call.State.INCOMING) {
- setState(mOwner.getState()); // INCOMING or WAITING
- } else {
- if (mOwner == ringingCall) {
- if (ringingCall.getState() == Call.State.WAITING) {
- try {
- switchHoldingAndActive();
- } catch (CallStateException e) {
- // disconnect the call.
- onCallEnded(DisconnectCause.LOCAL);
- return;
- }
- }
- foregroundCall.switchWith(ringingCall);
- }
- setState(newState);
- }
- mOwner.onConnectionStateChanged(SipConnection.this);
- if (DEBUG) Log.v(LOG_TAG, "+***+ connection state changed: "
- + mPeer.getUriString() + ": " + mState
- + " on phone " + getPhone());
- }
- }
-
- @Override
- protected void onError(DisconnectCause cause) {
- if (DEBUG) Log.d(LOG_TAG, "SIP error: " + cause);
- onCallEnded(cause);
- }
- };
-
- public SipConnection(SipCall owner, SipProfile callee,
- String originalNumber) {
- super(originalNumber);
- mOwner = owner;
- mPeer = callee;
- mOriginalNumber = originalNumber;
- }
-
- public SipConnection(SipCall owner, SipProfile callee) {
- this(owner, callee, getUriString(callee));
- }
-
- @Override
- public String getCnapName() {
- String displayName = mPeer.getDisplayName();
- return TextUtils.isEmpty(displayName) ? null
- : displayName;
- }
-
- @Override
- public int getNumberPresentation() {
- return Connection.PRESENTATION_ALLOWED;
- }
-
- void initIncomingCall(SipAudioCall sipAudioCall, Call.State newState) {
- setState(newState);
- mSipAudioCall = sipAudioCall;
- sipAudioCall.setListener(mAdapter); // call back to set state
- mIncoming = true;
- }
-
- void acceptCall() throws CallStateException {
- try {
- mSipAudioCall.answerCall(TIMEOUT_ANSWER_CALL);
- } catch (SipException e) {
- throw new CallStateException("acceptCall(): " + e);
- }
- }
-
- void changeOwner(SipCall owner) {
- mOwner = owner;
- }
-
- AudioGroup getAudioGroup() {
- if (mSipAudioCall == null) return null;
- return mSipAudioCall.getAudioGroup();
- }
-
- void dial() throws SipException {
- setState(Call.State.DIALING);
- mSipAudioCall = mSipManager.makeAudioCall(mProfile, mPeer, null,
- TIMEOUT_MAKE_CALL);
- mSipAudioCall.setListener(mAdapter);
- }
-
- void hold() throws CallStateException {
- setState(Call.State.HOLDING);
- try {
- mSipAudioCall.holdCall(TIMEOUT_HOLD_CALL);
- } catch (SipException e) {
- throw new CallStateException("hold(): " + e);
- }
- }
-
- void unhold(AudioGroup audioGroup) throws CallStateException {
- mSipAudioCall.setAudioGroup(audioGroup);
- setState(Call.State.ACTIVE);
- try {
- mSipAudioCall.continueCall(TIMEOUT_HOLD_CALL);
- } catch (SipException e) {
- throw new CallStateException("unhold(): " + e);
- }
- }
-
- void setMute(boolean muted) {
- if ((mSipAudioCall != null) && (muted != mSipAudioCall.isMuted())) {
- mSipAudioCall.toggleMute();
- }
- }
-
- boolean getMute() {
- return (mSipAudioCall == null) ? false
- : mSipAudioCall.isMuted();
- }
-
- @Override
- protected void setState(Call.State state) {
- if (state == mState) return;
- super.setState(state);
- mState = state;
- }
-
- @Override
- public Call.State getState() {
- return mState;
- }
-
- @Override
- public boolean isIncoming() {
- return mIncoming;
- }
-
- @Override
- public String getAddress() {
- // Phone app uses this to query caller ID. Return the original dial
- // number (which may be a PSTN number) instead of the peer's SIP
- // URI.
- return mOriginalNumber;
- }
-
- @Override
- public SipCall getCall() {
- return mOwner;
- }
-
- @Override
- protected Phone getPhone() {
- return mOwner.getPhone();
- }
-
- @Override
- public void hangup() throws CallStateException {
- synchronized (SipPhone.class) {
- if (DEBUG) Log.d(LOG_TAG, "hangup conn: " + mPeer.getUriString()
- + ": " + mState + ": on phone "
- + getPhone().getPhoneName());
- if (!mState.isAlive()) return;
- try {
- SipAudioCall sipAudioCall = mSipAudioCall;
- if (sipAudioCall != null) {
- sipAudioCall.setListener(null);
- sipAudioCall.endCall();
- }
- } catch (SipException e) {
- throw new CallStateException("hangup(): " + e);
- } finally {
- mAdapter.onCallEnded(((mState == Call.State.INCOMING)
- || (mState == Call.State.WAITING))
- ? DisconnectCause.INCOMING_REJECTED
- : DisconnectCause.LOCAL);
- }
- }
- }
-
- @Override
- public void separate() throws CallStateException {
- synchronized (SipPhone.class) {
- SipCall call = (getPhone() == SipPhone.this)
- ? (SipCall) SipPhone.this.getBackgroundCall()
- : (SipCall) SipPhone.this.getForegroundCall();
- if (call.getState() != Call.State.IDLE) {
- throw new CallStateException(
- "cannot put conn back to a call in non-idle state: "
- + call.getState());
- }
- if (DEBUG) Log.d(LOG_TAG, "separate conn: "
- + mPeer.getUriString() + " from " + mOwner + " back to "
- + call);
-
- // separate the AudioGroup and connection from the original call
- Phone originalPhone = getPhone();
- AudioGroup audioGroup = call.getAudioGroup(); // may be null
- call.add(this);
- mSipAudioCall.setAudioGroup(audioGroup);
-
- // put the original call to bg; and the separated call becomes
- // fg if it was in bg
- originalPhone.switchHoldingAndActive();
-
- // start audio and notify the phone app of the state change
- call = (SipCall) SipPhone.this.getForegroundCall();
- mSipAudioCall.startAudio();
- call.onConnectionStateChanged(this);
- }
- }
-
- }
-
- private static Call.State getCallStateFrom(SipAudioCall sipAudioCall) {
- if (sipAudioCall.isOnHold()) return Call.State.HOLDING;
- int sessionState = sipAudioCall.getState();
- switch (sessionState) {
- case SipSession.State.READY_TO_CALL: return Call.State.IDLE;
- case SipSession.State.INCOMING_CALL:
- case SipSession.State.INCOMING_CALL_ANSWERING: return Call.State.INCOMING;
- case SipSession.State.OUTGOING_CALL: return Call.State.DIALING;
- case SipSession.State.OUTGOING_CALL_RING_BACK: return Call.State.ALERTING;
- case SipSession.State.OUTGOING_CALL_CANCELING: return Call.State.DISCONNECTING;
- case SipSession.State.IN_CALL: return Call.State.ACTIVE;
- default:
- Log.w(LOG_TAG, "illegal connection state: " + sessionState);
- return Call.State.DISCONNECTED;
- }
- }
-
- private abstract class SipAudioCallAdapter extends SipAudioCall.Listener {
- protected abstract void onCallEnded(Connection.DisconnectCause cause);
- protected abstract void onError(Connection.DisconnectCause cause);
-
- @Override
- public void onCallEnded(SipAudioCall call) {
- onCallEnded(call.isInCall()
- ? Connection.DisconnectCause.NORMAL
- : Connection.DisconnectCause.INCOMING_MISSED);
- }
-
- @Override
- public void onCallBusy(SipAudioCall call) {
- onCallEnded(Connection.DisconnectCause.BUSY);
- }
-
- @Override
- public void onError(SipAudioCall call, int errorCode,
- String errorMessage) {
- switch (errorCode) {
- case SipErrorCode.SERVER_UNREACHABLE:
- onError(Connection.DisconnectCause.SERVER_UNREACHABLE);
- break;
- case SipErrorCode.PEER_NOT_REACHABLE:
- onError(Connection.DisconnectCause.NUMBER_UNREACHABLE);
- break;
- case SipErrorCode.INVALID_REMOTE_URI:
- onError(Connection.DisconnectCause.INVALID_NUMBER);
- break;
- case SipErrorCode.TIME_OUT:
- case SipErrorCode.TRANSACTION_TERMINTED:
- onError(Connection.DisconnectCause.TIMED_OUT);
- break;
- case SipErrorCode.DATA_CONNECTION_LOST:
- onError(Connection.DisconnectCause.LOST_SIGNAL);
- break;
- case SipErrorCode.INVALID_CREDENTIALS:
- onError(Connection.DisconnectCause.INVALID_CREDENTIALS);
- break;
- case SipErrorCode.CROSS_DOMAIN_AUTHENTICATION:
- onError(Connection.DisconnectCause.OUT_OF_NETWORK);
- break;
- case SipErrorCode.SERVER_ERROR:
- onError(Connection.DisconnectCause.SERVER_ERROR);
- break;
- case SipErrorCode.SOCKET_ERROR:
- case SipErrorCode.CLIENT_ERROR:
- default:
- Log.w(LOG_TAG, "error: " + SipErrorCode.toString(errorCode)
- + ": " + errorMessage);
- onError(Connection.DisconnectCause.ERROR_UNSPECIFIED);
- }
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
deleted file mode 100755
index 5c4b446..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright (C) 2010 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.sip;
-
-import android.content.Context;
-import android.net.LinkProperties;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.telephony.CellLocation;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.IccPhoneBookInterfaceManager;
-import com.android.internal.telephony.IccSmsInterfaceManager;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.OperatorInfo;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.PhoneSubInfo;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.UUSInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-abstract class SipPhoneBase extends PhoneBase {
- private static final String LOG_TAG = "SipPhone";
-
- private RegistrantList mRingbackRegistrants = new RegistrantList();
- private State state = State.IDLE;
-
- public SipPhoneBase(Context context, PhoneNotifier notifier) {
- super(notifier, context, new SipCommandInterface(context), false);
- }
-
- public abstract Call getForegroundCall();
-
- public abstract Call getBackgroundCall();
-
- public abstract Call getRingingCall();
-
- public Connection dial(String dialString, UUSInfo uusInfo)
- throws CallStateException {
- // ignore UUSInfo
- return dial(dialString);
- }
-
- void migrateFrom(SipPhoneBase from) {
- migrate(mRingbackRegistrants, from.mRingbackRegistrants);
- migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
- migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
- migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
- migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
- migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
- migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
- migrate(mMmiRegistrants, from.mMmiRegistrants);
- migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
- migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
- }
-
- static void migrate(RegistrantList to, RegistrantList from) {
- from.removeCleared();
- for (int i = 0, n = from.size(); i < n; i++) {
- to.add((Registrant) from.get(i));
- }
- }
-
- @Override
- public void registerForRingbackTone(Handler h, int what, Object obj) {
- mRingbackRegistrants.addUnique(h, what, obj);
- }
-
- @Override
- public void unregisterForRingbackTone(Handler h) {
- mRingbackRegistrants.remove(h);
- }
-
- protected void startRingbackTone() {
- AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
- mRingbackRegistrants.notifyRegistrants(result);
- }
-
- protected void stopRingbackTone() {
- AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
- mRingbackRegistrants.notifyRegistrants(result);
- }
-
- public ServiceState getServiceState() {
- // FIXME: we may need to provide this when data connectivity is lost
- // or when server is down
- ServiceState s = new ServiceState();
- s.setState(ServiceState.STATE_IN_SERVICE);
- return s;
- }
-
- public CellLocation getCellLocation() {
- return null;
- }
-
- public State getState() {
- return state;
- }
-
- public int getPhoneType() {
- return Phone.PHONE_TYPE_SIP;
- }
-
- public SignalStrength getSignalStrength() {
- return new SignalStrength();
- }
-
- public boolean getMessageWaitingIndicator() {
- return false;
- }
-
- public boolean getCallForwardingIndicator() {
- return false;
- }
-
- public List<? extends MmiCode> getPendingMmiCodes() {
- return new ArrayList<MmiCode>(0);
- }
-
- public DataState getDataConnectionState() {
- return DataState.DISCONNECTED;
- }
-
- public DataState getDataConnectionState(String apnType) {
- return DataState.DISCONNECTED;
- }
-
- public DataActivityState getDataActivityState() {
- return DataActivityState.NONE;
- }
-
- /**
- * Notify any interested party of a Phone state change {@link Phone.State}
- */
- void notifyPhoneStateChanged() {
- mNotifier.notifyPhoneState(this);
- }
-
- /**
- * Notify registrants of a change in the call state. This notifies changes in {@link Call.State}
- * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged.
- */
- void notifyPreciseCallStateChanged() {
- /* we'd love it if this was package-scoped*/
- super.notifyPreciseCallStateChangedP();
- }
-
- void notifyNewRingingConnection(Connection c) {
- super.notifyNewRingingConnectionP(c);
- }
-
- void notifyDisconnect(Connection cn) {
- mDisconnectRegistrants.notifyResult(cn);
- }
-
- void notifyUnknownConnection() {
- mUnknownConnectionRegistrants.notifyResult(this);
- }
-
- void notifySuppServiceFailed(SuppService code) {
- mSuppServiceFailedRegistrants.notifyResult(code);
- }
-
- void notifyServiceStateChanged(ServiceState ss) {
- super.notifyServiceStateChangedP(ss);
- }
-
- public void notifyCallForwardingIndicator() {
- mNotifier.notifyCallForwardingChanged(this);
- }
-
- public boolean canDial() {
- int serviceState = getServiceState().getState();
- Log.v(LOG_TAG, "canDial(): serviceState = " + serviceState);
- if (serviceState == ServiceState.STATE_POWER_OFF) return false;
-
- String disableCall = SystemProperties.get(
- TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
- Log.v(LOG_TAG, "canDial(): disableCall = " + disableCall);
- if (disableCall.equals("true")) return false;
-
- Log.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState());
- Log.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState());
- Log.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState());
- return !getRingingCall().isRinging()
- && (!getForegroundCall().getState().isAlive()
- || !getBackgroundCall().getState().isAlive());
- }
-
- public boolean handleInCallMmiCommands(String dialString)
- throws CallStateException {
- return false;
- }
-
- boolean isInCall() {
- Call.State foregroundCallState = getForegroundCall().getState();
- Call.State backgroundCallState = getBackgroundCall().getState();
- Call.State ringingCallState = getRingingCall().getState();
-
- return (foregroundCallState.isAlive() || backgroundCallState.isAlive()
- || ringingCallState.isAlive());
- }
-
- public boolean handlePinMmi(String dialString) {
- return false;
- }
-
- public void sendUssdResponse(String ussdMessge) {
- }
-
- public void registerForSuppServiceNotification(
- Handler h, int what, Object obj) {
- }
-
- public void unregisterForSuppServiceNotification(Handler h) {
- }
-
- public void setRadioPower(boolean power) {
- }
-
- public String getVoiceMailNumber() {
- return null;
- }
-
- public String getVoiceMailAlphaTag() {
- return null;
- }
-
- public String getDeviceId() {
- return null;
- }
-
- public String getDeviceSvn() {
- return null;
- }
-
- public String getImei() {
- return null;
- }
-
- public String getEsn() {
- Log.e(LOG_TAG, "[SipPhone] getEsn() is a CDMA method");
- return "0";
- }
-
- public String getMeid() {
- Log.e(LOG_TAG, "[SipPhone] getMeid() is a CDMA method");
- return "0";
- }
-
- public String getSubscriberId() {
- return null;
- }
-
- public String getIccSerialNumber() {
- return null;
- }
-
- public String getLine1Number() {
- return null;
- }
-
- public String getLine1AlphaTag() {
- return null;
- }
-
- public void setLine1Number(String alphaTag, String number, Message onComplete) {
- // FIXME: what to reply for SIP?
- AsyncResult.forMessage(onComplete, null, null);
- onComplete.sendToTarget();
- }
-
- public void setVoiceMailNumber(String alphaTag, String voiceMailNumber,
- Message onComplete) {
- // FIXME: what to reply for SIP?
- AsyncResult.forMessage(onComplete, null, null);
- onComplete.sendToTarget();
- }
-
- public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
- }
-
- public void setCallForwardingOption(int commandInterfaceCFAction,
- int commandInterfaceCFReason, String dialingNumber,
- int timerSeconds, Message onComplete) {
- }
-
- public void getOutgoingCallerIdDisplay(Message onComplete) {
- // FIXME: what to reply?
- AsyncResult.forMessage(onComplete, null, null);
- onComplete.sendToTarget();
- }
-
- public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
- Message onComplete) {
- // FIXME: what's this for SIP?
- AsyncResult.forMessage(onComplete, null, null);
- onComplete.sendToTarget();
- }
-
- public void getCallWaiting(Message onComplete) {
- AsyncResult.forMessage(onComplete, null, null);
- onComplete.sendToTarget();
- }
-
- public void setCallWaiting(boolean enable, Message onComplete) {
- Log.e(LOG_TAG, "call waiting not supported");
- }
-
- public boolean getIccRecordsLoaded() {
- return false;
- }
-
- public IccCard getIccCard() {
- return null;
- }
-
- public void getAvailableNetworks(Message response) {
- }
-
- public void setNetworkSelectionModeAutomatic(Message response) {
- }
-
- public void selectNetworkManually(
- OperatorInfo network,
- Message response) {
- }
-
- public void getNeighboringCids(Message response) {
- }
-
- public void setOnPostDialCharacter(Handler h, int what, Object obj) {
- }
-
- public void getDataCallList(Message response) {
- }
-
- public List<DataConnection> getCurrentDataConnectionList () {
- return null;
- }
-
- public void updateServiceLocation() {
- }
-
- public void enableLocationUpdates() {
- }
-
- public void disableLocationUpdates() {
- }
-
- public boolean getDataRoamingEnabled() {
- return false;
- }
-
- public void setDataRoamingEnabled(boolean enable) {
- }
-
- public boolean enableDataConnectivity() {
- return false;
- }
-
- public boolean disableDataConnectivity() {
- return false;
- }
-
- public boolean isDataConnectivityPossible() {
- return false;
- }
-
- boolean updateCurrentCarrierInProvider() {
- return false;
- }
-
- public void saveClirSetting(int commandInterfaceCLIRMode) {
- }
-
- public PhoneSubInfo getPhoneSubInfo(){
- return null;
- }
-
- public IccSmsInterfaceManager getIccSmsInterfaceManager(){
- return null;
- }
-
- public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
- return null;
- }
-
- public IccFileHandler getIccFileHandler(){
- return null;
- }
-
- public void activateCellBroadcastSms(int activate, Message response) {
- Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
- }
-
- public void getCellBroadcastSmsConfig(Message response) {
- Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
- }
-
- public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
- Log.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
- }
-
- //@Override
- public boolean needsOtaServiceProvisioning() {
- // FIXME: what's this for SIP?
- return false;
- }
-
- //@Override
- public LinkProperties getLinkProperties(String apnType) {
- // FIXME: what's this for SIP?
- return null;
- }
-
- void updatePhoneState() {
- State oldState = state;
-
- if (getRingingCall().isRinging()) {
- state = State.RINGING;
- } else if (getForegroundCall().isIdle()
- && getBackgroundCall().isIdle()) {
- state = State.IDLE;
- } else {
- state = State.OFFHOOK;
- }
-
- if (state != oldState) {
- Log.d(LOG_TAG, " ^^^ new phone state: " + state);
- notifyPhoneStateChanged();
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java b/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
deleted file mode 100644
index 611e3ea..0000000
--- a/telephony/java/com/android/internal/telephony/sip/SipPhoneFactory.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 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.sip;
-
-import com.android.internal.telephony.PhoneNotifier;
-
-import android.content.Context;
-import android.net.sip.SipProfile;
-import android.util.Log;
-
-import java.text.ParseException;
-
-/**
- * {@hide}
- */
-public class SipPhoneFactory {
- /**
- * Makes a {@link SipPhone} object.
- * @param sipUri the local SIP URI the phone runs on
- * @param context {@code Context} needed to create a Phone object
- * @param phoneNotifier {@code PhoneNotifier} needed to create a Phone
- * object
- * @return the {@code SipPhone} object or null if the SIP URI is not valid
- */
- public static SipPhone makePhone(String sipUri, Context context,
- PhoneNotifier phoneNotifier) {
- try {
- SipProfile profile = new SipProfile.Builder(sipUri).build();
- return new SipPhone(context, phoneNotifier, profile);
- } catch (ParseException e) {
- Log.w("SipPhoneFactory", "makePhone", e);
- return null;
- }
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java b/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
deleted file mode 100644
index b116c35..0000000
--- a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * 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.test;
-
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.List;
-
-// Also in ATChannel.java
-class LineReader
-{
- /**
- * Not threadsafe
- * Assumes input is ASCII
- */
-
- //***** Constants
-
- // For what it's worth, this is also the size of an
- // OMAP CSMI mailbox
- static final int BUFFER_SIZE = 0x1000;
-
- // just to prevent constant allocations
- byte buffer[] = new byte[BUFFER_SIZE];
-
- //***** Instance Variables
-
- InputStream inStream;
-
- LineReader (InputStream s)
- {
- inStream = s;
- }
-
- String
- getNextLine()
- {
- return getNextLine(false);
- }
-
- String
- getNextLineCtrlZ()
- {
- return getNextLine(true);
- }
-
- /**
- * Note: doesn't return the last incomplete line read on EOF, since
- * it doesn't typically matter anyway
- *
- * Returns NULL on EOF
- */
-
- String
- getNextLine(boolean ctrlZ)
- {
- int i = 0;
-
- try {
- for (;;) {
- int result;
-
- result = inStream.read();
-
- if (result < 0) {
- return null;
- }
-
- if (ctrlZ && result == 0x1a) {
- break;
- } else if (result == '\r' || result == '\n') {
- if (i == 0) {
- // Skip leading cr/lf
- continue;
- } else {
- break;
- }
- }
-
- buffer[i++] = (byte)result;
- }
- } catch (IOException ex) {
- return null;
- } catch (IndexOutOfBoundsException ex) {
- System.err.println("ATChannel: buffer overflow");
- }
-
- try {
- return new String(buffer, 0, i, "US-ASCII");
- } catch (UnsupportedEncodingException ex) {
- System.err.println("ATChannel: implausable UnsupportedEncodingException");
- return null;
- }
- }
-}
-
-
-
-class InterpreterEx extends Exception
-{
- public
- InterpreterEx (String result)
- {
- this.result = result;
- }
-
- String result;
-}
-
-public class ModelInterpreter
- implements Runnable, SimulatedRadioControl
-{
- static final int MAX_CALLS = 6;
-
- /** number of msec between dialing -> alerting and alerting->active */
- static final int CONNECTING_PAUSE_MSEC = 5 * 100;
-
- static final String LOG_TAG = "ModelInterpreter";
-
- //***** Instance Variables
-
- InputStream in;
- OutputStream out;
- LineReader lineReader;
- ServerSocket ss;
-
- private String finalResponse;
-
- SimulatedGsmCallState simulatedCallState;
-
- HandlerThread mHandlerThread;
-
- int pausedResponseCount;
- Object pausedResponseMonitor = new Object();
-
- //***** Events
-
- static final int PROGRESS_CALL_STATE = 1;
-
- //***** Constructor
-
- public
- ModelInterpreter (InputStream in, OutputStream out)
- {
- this.in = in;
- this.out = out;
-
- init();
- }
-
- public
- ModelInterpreter (InetSocketAddress sa) throws java.io.IOException
- {
- ss = new ServerSocket();
-
- ss.setReuseAddress(true);
- ss.bind(sa);
-
- init();
- }
-
- private void
- init()
- {
- new Thread(this, "ModelInterpreter").start();
- mHandlerThread = new HandlerThread("ModelInterpreter");
- mHandlerThread.start();
- Looper looper = mHandlerThread.getLooper();
- simulatedCallState = new SimulatedGsmCallState(looper);
- }
-
- //***** Runnable Implementation
-
- public void run()
- {
- for (;;) {
- if (ss != null) {
- Socket s;
-
- try {
- s = ss.accept();
- } catch (java.io.IOException ex) {
- Log.w(LOG_TAG,
- "IOException on socket.accept(); stopping", ex);
- return;
- }
-
- try {
- in = s.getInputStream();
- out = s.getOutputStream();
- } catch (java.io.IOException ex) {
- Log.w(LOG_TAG,
- "IOException on accepted socket(); re-listening", ex);
- continue;
- }
-
- Log.i(LOG_TAG, "New connection accepted");
- }
-
-
- lineReader = new LineReader (in);
-
- println ("Welcome");
-
- for (;;) {
- String line;
-
- line = lineReader.getNextLine();
-
- //System.out.println("MI<< " + line);
-
- if (line == null) {
- break;
- }
-
- synchronized(pausedResponseMonitor) {
- while (pausedResponseCount > 0) {
- try {
- pausedResponseMonitor.wait();
- } catch (InterruptedException ex) {
- }
- }
- }
-
- synchronized (this) {
- try {
- finalResponse = "OK";
- processLine(line);
- println(finalResponse);
- } catch (InterpreterEx ex) {
- println(ex.result);
- } catch (RuntimeException ex) {
- ex.printStackTrace();
- println("ERROR");
- }
- }
- }
-
- Log.i(LOG_TAG, "Disconnected");
-
- if (ss == null) {
- // no reconnect in this case
- break;
- }
- }
- }
-
-
- //***** Instance Methods
-
- /** Start the simulated phone ringing */
- public void
- triggerRing(String number)
- {
- synchronized (this) {
- boolean success;
-
- success = simulatedCallState.triggerRing(number);
-
- if (success) {
- println ("RING");
- }
- }
- }
-
- /** If a call is DIALING or ALERTING, progress it to the next state */
- public void
- progressConnectingCallState()
- {
- simulatedCallState.progressConnectingCallState();
- }
-
-
- /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
- public void
- progressConnectingToActive()
- {
- simulatedCallState.progressConnectingToActive();
- }
-
- /** automatically progress mobile originated calls to ACTIVE.
- * default to true
- */
- public void
- setAutoProgressConnectingCall(boolean b)
- {
- simulatedCallState.setAutoProgressConnectingCall(b);
- }
-
- public void
- setNextDialFailImmediately(boolean b)
- {
- simulatedCallState.setNextDialFailImmediately(b);
- }
-
- public void setNextCallFailCause(int gsmCause)
- {
- //FIXME implement
- }
-
-
- /** hangup ringing, dialing, or actuve calls */
- public void
- triggerHangupForeground()
- {
- boolean success;
-
- success = simulatedCallState.triggerHangupForeground();
-
- if (success) {
- println ("NO CARRIER");
- }
- }
-
- /** hangup holding calls */
- public void
- triggerHangupBackground()
- {
- boolean success;
-
- success = simulatedCallState.triggerHangupBackground();
-
- if (success) {
- println ("NO CARRIER");
- }
- }
-
- /** hangup all */
-
- public void
- triggerHangupAll()
- {
- boolean success;
-
- success = simulatedCallState.triggerHangupAll();
-
- if (success) {
- println ("NO CARRIER");
- }
- }
-
- public void
- sendUnsolicited (String unsol)
- {
- synchronized (this) {
- println(unsol);
- }
- }
-
- public void triggerSsn(int a, int b) {}
- public void triggerIncomingUssd(String statusCode, String message) {}
-
- public void
- triggerIncomingSMS(String message)
- {
-/**************
- StringBuilder pdu = new StringBuilder();
-
- pdu.append ("00"); //SMSC address - 0 bytes
-
- pdu.append ("04"); // Message type indicator
-
- // source address: +18005551212
- pdu.append("918100551521F0");
-
- // protocol ID and data coding scheme
- pdu.append("0000");
-
- Calendar c = Calendar.getInstance();
-
- pdu.append (c.
-
-
-
- synchronized (this) {
- println("+CMT: ,1\r" + pdu.toString());
- }
-
-**************/
- }
-
- public void
- pauseResponses()
- {
- synchronized(pausedResponseMonitor) {
- pausedResponseCount++;
- }
- }
-
- public void
- resumeResponses()
- {
- synchronized(pausedResponseMonitor) {
- pausedResponseCount--;
-
- if (pausedResponseCount == 0) {
- pausedResponseMonitor.notifyAll();
- }
- }
- }
-
- //***** Private Instance Methods
-
- private void
- onAnswer() throws InterpreterEx
- {
- boolean success;
-
- success = simulatedCallState.onAnswer();
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
- }
-
- private void
- onHangup() throws InterpreterEx
- {
- boolean success = false;
-
- success = simulatedCallState.onAnswer();
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
-
- finalResponse = "NO CARRIER";
- }
-
- private void
- onCHLD(String command) throws InterpreterEx
- {
- // command starts with "+CHLD="
- char c0;
- char c1 = 0;
- boolean success;
-
- c0 = command.charAt(6);
-
- if (command.length() >= 8) {
- c1 = command.charAt(7);
- }
-
- success = simulatedCallState.onChld(c0, c1);
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
- }
-
- private void
- releaseHeldOrUDUB() throws InterpreterEx
- {
- boolean success;
-
- success = simulatedCallState.releaseHeldOrUDUB();
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
- }
-
- private void
- releaseActiveAcceptHeldOrWaiting() throws InterpreterEx
- {
- boolean success;
-
- success = simulatedCallState.releaseActiveAcceptHeldOrWaiting();
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
- }
-
- private void
- switchActiveAndHeldOrWaiting() throws InterpreterEx
- {
- boolean success;
-
- success = simulatedCallState.switchActiveAndHeldOrWaiting();
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
- }
-
- private void
- separateCall(int index) throws InterpreterEx
- {
- boolean success;
-
- success = simulatedCallState.separateCall(index);
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
- }
-
- private void
- conference() throws InterpreterEx
- {
- boolean success;
-
- success = simulatedCallState.conference();
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
- }
-
- private void
- onDial(String command) throws InterpreterEx
- {
- boolean success;
-
- success = simulatedCallState.onDial(command.substring(1));
-
- if (!success) {
- throw new InterpreterEx("ERROR");
- }
- }
-
- private void
- onCLCC() throws InterpreterEx
- {
- List<String> lines;
-
- lines = simulatedCallState.getClccLines();
-
- for (int i = 0, s = lines.size() ; i < s ; i++) {
- println (lines.get(i));
- }
- }
-
- private void
- onSMSSend(String command) throws InterpreterEx
- {
- String pdu;
-
- print ("> ");
- pdu = lineReader.getNextLineCtrlZ();
-
- println("+CMGS: 1");
- }
-
- void
- processLine (String line) throws InterpreterEx
- {
- String[] commands;
-
- commands = splitCommands(line);
-
- for (int i = 0; i < commands.length ; i++) {
- String command = commands[i];
-
- if (command.equals("A")) {
- onAnswer();
- } else if (command.equals("H")) {
- onHangup();
- } else if (command.startsWith("+CHLD=")) {
- onCHLD(command);
- } else if (command.equals("+CLCC")) {
- onCLCC();
- } else if (command.startsWith("D")) {
- onDial(command);
- } else if (command.startsWith("+CMGS=")) {
- onSMSSend(command);
- } else {
- boolean found = false;
-
- for (int j = 0; j < sDefaultResponses.length ; j++) {
- if (command.equals(sDefaultResponses[j][0])) {
- String r = sDefaultResponses[j][1];
- if (r != null) {
- println(r);
- }
- found = true;
- break;
- }
- }
-
- if (!found) {
- throw new InterpreterEx ("ERROR");
- }
- }
- }
- }
-
-
- String[]
- splitCommands(String line) throws InterpreterEx
- {
- if (!line.startsWith ("AT")) {
- throw new InterpreterEx("ERROR");
- }
-
- if (line.length() == 2) {
- // Just AT by itself
- return new String[0];
- }
-
- String ret[] = new String[1];
-
- //TODO fix case here too
- ret[0] = line.substring(2);
-
- return ret;
-/****
- try {
- // i = 2 to skip over AT
- for (int i = 2, s = line.length() ; i < s ; i++) {
- // r"|([A-RT-Z]\d?)" # Normal commands eg ATA or I0
- // r"|(&[A-Z]\d*)" # & commands eg &C
- // r"|(S\d+(=\d+)?)" # S registers
- // r"((\+|%)\w+(\?|=([^;]+(;|$)))?)" # extended command eg +CREG=2
-
-
- }
- } catch (StringIndexOutOfBoundsException ex) {
- throw new InterpreterEx ("ERROR");
- }
-***/
- }
-
- void
- println (String s)
- {
- synchronized(this) {
- try {
- byte[] bytes = s.getBytes("US-ASCII");
-
- //System.out.println("MI>> " + s);
-
- out.write(bytes);
- out.write('\r');
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
-
- void
- print (String s)
- {
- synchronized(this) {
- try {
- byte[] bytes = s.getBytes("US-ASCII");
-
- //System.out.println("MI>> " + s + " (no <cr>)");
-
- out.write(bytes);
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
-
-
- public void
- shutdown()
- {
- Looper looper = mHandlerThread.getLooper();
- if (looper != null) {
- looper.quit();
- }
-
- try {
- in.close();
- } catch (IOException ex) {
- }
- try {
- out.close();
- } catch (IOException ex) {
- }
- }
-
-
- static final String [][] sDefaultResponses = {
- {"E0Q0V1", null},
- {"+CMEE=2", null},
- {"+CREG=2", null},
- {"+CGREG=2", null},
- {"+CCWA=1", null},
- {"+COPS=0", null},
- {"+CFUN=1", null},
- {"+CGMI", "+CGMI: Android Model AT Interpreter\r"},
- {"+CGMM", "+CGMM: Android Model AT Interpreter\r"},
- {"+CGMR", "+CGMR: 1.0\r"},
- {"+CGSN", "000000000000000\r"},
- {"+CIMI", "320720000000000\r"},
- {"+CSCS=?", "+CSCS: (\"HEX\",\"UCS2\")\r"},
- {"+CFUN?", "+CFUN: 1\r"},
- {"+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
- "+COPS: 0,0,\"Android\"\r"
- + "+COPS: 0,1,\"Android\"\r"
- + "+COPS: 0,2,\"310995\"\r"},
- {"+CREG?", "+CREG: 2,5, \"0113\", \"6614\"\r"},
- {"+CGREG?", "+CGREG: 2,0\r"},
- {"+CSQ", "+CSQ: 16,99\r"},
- {"+CNMI?", "+CNMI: 1,2,2,1,1\r"},
- {"+CLIR?", "+CLIR: 1,3\r"},
- {"%CPVWI=2", "%CPVWI: 0\r"},
- {"+CUSD=1,\"#646#\"", "+CUSD=0,\"You have used 23 minutes\"\r"},
- {"+CRSM=176,12258,0,0,10", "+CRSM: 144,0,981062200050259429F6\r"},
- {"+CRSM=192,12258,0,0,15", "+CRSM: 144,0,0000000A2FE204000FF55501020000\r"},
-
- /* EF[ADN] */
- {"+CRSM=192,28474,0,0,15", "+CRSM: 144,0,0000005a6f3a040011f5220102011e\r"},
- {"+CRSM=178,28474,1,4,30", "+CRSM: 144,0,437573746f6d65722043617265ffffff07818100398799f7ffffffffffff\r"},
- {"+CRSM=178,28474,2,4,30", "+CRSM: 144,0,566f696365204d61696cffffffffffff07918150367742f3ffffffffffff\r"},
- {"+CRSM=178,28474,3,4,30", "+CRSM: 144,0,4164676a6dffffffffffffffffffffff0b918188551512c221436587ff01\r"},
- {"+CRSM=178,28474,4,4,30", "+CRSM: 144,0,810101c1ffffffffffffffffffffffff068114455245f8ffffffffffffff\r"},
- /* EF[EXT1] */
- {"+CRSM=192,28490,0,0,15", "+CRSM: 144,0,000000416f4a040011f5550102010d\r"},
- {"+CRSM=178,28490,1,4,13", "+CRSM: 144,0,0206092143658709ffffffffff\r"}
- };
-}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
deleted file mode 100644
index 4f61509..0000000
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ /dev/null
@@ -1,1525 +0,0 @@
-/*
- * 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.test;
-
-import android.os.AsyncResult;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.DataCallState;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-
-import java.util.ArrayList;
-
-public final class SimulatedCommands extends BaseCommands
- implements CommandsInterface, SimulatedRadioControl {
- private final static String LOG_TAG = "SIM";
-
- private enum SimLockState {
- NONE,
- REQUIRE_PIN,
- REQUIRE_PUK,
- SIM_PERM_LOCKED
- }
-
- private enum SimFdnState {
- NONE,
- REQUIRE_PIN2,
- REQUIRE_PUK2,
- SIM_PERM_LOCKED
- }
-
- private final static SimLockState INITIAL_LOCK_STATE = SimLockState.NONE;
- private final static String DEFAULT_SIM_PIN_CODE = "1234";
- private final static String SIM_PUK_CODE = "12345678";
- private final static SimFdnState INITIAL_FDN_STATE = SimFdnState.NONE;
- private final static String DEFAULT_SIM_PIN2_CODE = "5678";
- private final static String SIM_PUK2_CODE = "87654321";
-
- //***** Instance Variables
-
- SimulatedGsmCallState simulatedCallState;
- HandlerThread mHandlerThread;
- SimLockState mSimLockedState;
- boolean mSimLockEnabled;
- int mPinUnlockAttempts;
- int mPukUnlockAttempts;
- String mPinCode;
- SimFdnState mSimFdnEnabledState;
- boolean mSimFdnEnabled;
- int mPin2UnlockAttempts;
- int mPuk2UnlockAttempts;
- int mNetworkType;
- String mPin2Code;
- boolean mSsnNotifyOn = false;
-
- int pausedResponseCount;
- ArrayList<Message> pausedResponses = new ArrayList<Message>();
-
- int nextCallFailCause = CallFailCause.NORMAL_CLEARING;
-
- //***** Constructor
-
- public
- SimulatedCommands() {
- super(null); // Don't log statistics
- mHandlerThread = new HandlerThread("SimulatedCommands");
- mHandlerThread.start();
- Looper looper = mHandlerThread.getLooper();
-
- simulatedCallState = new SimulatedGsmCallState(looper);
-
- setRadioState(RadioState.RADIO_OFF);
- mSimLockedState = INITIAL_LOCK_STATE;
- mSimLockEnabled = (mSimLockedState != SimLockState.NONE);
- mPinCode = DEFAULT_SIM_PIN_CODE;
- mSimFdnEnabledState = INITIAL_FDN_STATE;
- mSimFdnEnabled = (mSimFdnEnabledState != SimFdnState.NONE);
- mPin2Code = DEFAULT_SIM_PIN2_CODE;
- }
-
- //***** CommandsInterface implementation
-
- public void getIccCardStatus(Message result) {
- unimplemented(result);
- }
-
- public void supplyIccPin(String pin, Message result) {
- if (mSimLockedState != SimLockState.REQUIRE_PIN) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPin: wrong state, state=" +
- mSimLockedState);
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- return;
- }
-
- if (pin != null && pin.equals(mPinCode)) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPin: success!");
- mPinUnlockAttempts = 0;
- mSimLockedState = SimLockState.NONE;
- mIccStatusChangedRegistrants.notifyRegistrants();
-
- if (result != null) {
- AsyncResult.forMessage(result, null, null);
- result.sendToTarget();
- }
-
- return;
- }
-
- if (result != null) {
- mPinUnlockAttempts ++;
-
- Log.i(LOG_TAG, "[SimCmd] supplyIccPin: failed! attempt=" +
- mPinUnlockAttempts);
- if (mPinUnlockAttempts >= 3) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPin: set state to REQUIRE_PUK");
- mSimLockedState = SimLockState.REQUIRE_PUK;
- }
-
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- }
- }
-
- public void supplyIccPuk(String puk, String newPin, Message result) {
- if (mSimLockedState != SimLockState.REQUIRE_PUK) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: wrong state, state=" +
- mSimLockedState);
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- return;
- }
-
- if (puk != null && puk.equals(SIM_PUK_CODE)) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: success!");
- mSimLockedState = SimLockState.NONE;
- mPukUnlockAttempts = 0;
- mIccStatusChangedRegistrants.notifyRegistrants();
-
- if (result != null) {
- AsyncResult.forMessage(result, null, null);
- result.sendToTarget();
- }
-
- return;
- }
-
- if (result != null) {
- mPukUnlockAttempts ++;
-
- Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: failed! attempt=" +
- mPukUnlockAttempts);
- if (mPukUnlockAttempts >= 10) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPuk: set state to SIM_PERM_LOCKED");
- mSimLockedState = SimLockState.SIM_PERM_LOCKED;
- }
-
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- }
- }
-
- public void supplyIccPin2(String pin2, Message result) {
- if (mSimFdnEnabledState != SimFdnState.REQUIRE_PIN2) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: wrong state, state=" +
- mSimFdnEnabledState);
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- return;
- }
-
- if (pin2 != null && pin2.equals(mPin2Code)) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: success!");
- mPin2UnlockAttempts = 0;
- mSimFdnEnabledState = SimFdnState.NONE;
-
- if (result != null) {
- AsyncResult.forMessage(result, null, null);
- result.sendToTarget();
- }
-
- return;
- }
-
- if (result != null) {
- mPin2UnlockAttempts ++;
-
- Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: failed! attempt=" +
- mPin2UnlockAttempts);
- if (mPin2UnlockAttempts >= 3) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPin2: set state to REQUIRE_PUK2");
- mSimFdnEnabledState = SimFdnState.REQUIRE_PUK2;
- }
-
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- }
- }
-
- public void supplyIccPuk2(String puk2, String newPin2, Message result) {
- if (mSimFdnEnabledState != SimFdnState.REQUIRE_PUK2) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: wrong state, state=" +
- mSimLockedState);
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- return;
- }
-
- if (puk2 != null && puk2.equals(SIM_PUK2_CODE)) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: success!");
- mSimFdnEnabledState = SimFdnState.NONE;
- mPuk2UnlockAttempts = 0;
-
- if (result != null) {
- AsyncResult.forMessage(result, null, null);
- result.sendToTarget();
- }
-
- return;
- }
-
- if (result != null) {
- mPuk2UnlockAttempts ++;
-
- Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: failed! attempt=" +
- mPuk2UnlockAttempts);
- if (mPuk2UnlockAttempts >= 10) {
- Log.i(LOG_TAG, "[SimCmd] supplyIccPuk2: set state to SIM_PERM_LOCKED");
- mSimFdnEnabledState = SimFdnState.SIM_PERM_LOCKED;
- }
-
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- }
- }
-
- public void changeIccPin(String oldPin, String newPin, Message result) {
- if (oldPin != null && oldPin.equals(mPinCode)) {
- mPinCode = newPin;
- if (result != null) {
- AsyncResult.forMessage(result, null, null);
- result.sendToTarget();
- }
-
- return;
- }
-
- if (result != null) {
- Log.i(LOG_TAG, "[SimCmd] changeIccPin: pin failed!");
-
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- }
- }
-
- public void changeIccPin2(String oldPin2, String newPin2, Message result) {
- if (oldPin2 != null && oldPin2.equals(mPin2Code)) {
- mPin2Code = newPin2;
- if (result != null) {
- AsyncResult.forMessage(result, null, null);
- result.sendToTarget();
- }
-
- return;
- }
-
- if (result != null) {
- Log.i(LOG_TAG, "[SimCmd] changeIccPin2: pin2 failed!");
-
- CommandException ex = new CommandException(
- CommandException.Error.PASSWORD_INCORRECT);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- }
- }
-
- public void
- changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) {
- unimplemented(result);
- }
-
- public void
- setSuppServiceNotifications(boolean enable, Message result) {
- resultSuccess(result, null);
-
- if (enable && mSsnNotifyOn) {
- Log.w(LOG_TAG, "Supp Service Notifications already enabled!");
- }
-
- mSsnNotifyOn = enable;
- }
-
- @Override
- public void queryFacilityLock(String facility, String pin,
- int serviceClass, Message result) {
- queryFacilityLockForApp(facility, pin, serviceClass, null, result);
- }
-
- @Override
- public void queryFacilityLockForApp(String facility, String pin, int serviceClass,
- String appId, Message result) {
- if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) {
- if (result != null) {
- int[] r = new int[1];
- r[0] = (mSimLockEnabled ? 1 : 0);
- Log.i(LOG_TAG, "[SimCmd] queryFacilityLock: SIM is "
- + (r[0] == 0 ? "unlocked" : "locked"));
- AsyncResult.forMessage(result, r, null);
- result.sendToTarget();
- }
- return;
- } else if (facility != null && facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) {
- if (result != null) {
- int[] r = new int[1];
- r[0] = (mSimFdnEnabled ? 1 : 0);
- Log.i(LOG_TAG, "[SimCmd] queryFacilityLock: FDN is "
- + (r[0] == 0 ? "disabled" : "enabled"));
- AsyncResult.forMessage(result, r, null);
- result.sendToTarget();
- }
- return;
- }
-
- unimplemented(result);
- }
-
- @Override
- public void setFacilityLock(String facility, boolean lockEnabled, String pin, int serviceClass,
- Message result) {
- setFacilityLockForApp(facility, lockEnabled, pin, serviceClass, null, result);
- }
-
- @Override
- public void setFacilityLockForApp(String facility, boolean lockEnabled,
- String pin, int serviceClass, String appId,
- Message result) {
- if (facility != null &&
- facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) {
- if (pin != null && pin.equals(mPinCode)) {
- Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin is valid");
- mSimLockEnabled = lockEnabled;
-
- if (result != null) {
- AsyncResult.forMessage(result, null, null);
- result.sendToTarget();
- }
-
- return;
- }
-
- if (result != null) {
- Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin failed!");
-
- CommandException ex = new CommandException(
- CommandException.Error.GENERIC_FAILURE);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- }
-
- return;
- } else if (facility != null &&
- facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) {
- if (pin != null && pin.equals(mPin2Code)) {
- Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 is valid");
- mSimFdnEnabled = lockEnabled;
-
- if (result != null) {
- AsyncResult.forMessage(result, null, null);
- result.sendToTarget();
- }
-
- return;
- }
-
- if (result != null) {
- Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 failed!");
-
- CommandException ex = new CommandException(
- CommandException.Error.GENERIC_FAILURE);
- AsyncResult.forMessage(result, null, ex);
- result.sendToTarget();
- }
-
- return;
- }
-
- unimplemented(result);
- }
-
- public void supplyNetworkDepersonalization(String netpin, Message result) {
- unimplemented(result);
- }
-
- /**
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result contains a List of DriverCall
- * The ar.result List is sorted by DriverCall.index
- */
- public void getCurrentCalls (Message result) {
- if ((mState == RadioState.RADIO_ON) && !isSimLocked()) {
- //Log.i("GSM", "[SimCmds] getCurrentCalls");
- resultSuccess(result, simulatedCallState.getDriverCalls());
- } else {
- //Log.i("GSM", "[SimCmds] getCurrentCalls: RADIO_OFF or SIM not ready!");
- resultFail(result,
- new CommandException(
- CommandException.Error.RADIO_NOT_AVAILABLE));
- }
- }
-
- /**
- * @deprecated
- */
- public void getPDPContextList(Message result) {
- getDataCallList(result);
- }
-
- /**
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result contains a List of DataCallState
- */
- public void getDataCallList(Message result) {
- resultSuccess(result, new ArrayList<DataCallState>(0));
- }
-
- /**
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- *
- * CLIR_DEFAULT == on "use subscription default value"
- * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
- * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation)
- */
- public void dial (String address, int clirMode, Message result) {
- simulatedCallState.onDial(address);
-
- resultSuccess(result, null);
- }
-
- /**
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- *
- * CLIR_DEFAULT == on "use subscription default value"
- * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
- * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation)
- */
- public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
- simulatedCallState.onDial(address);
-
- resultSuccess(result, null);
- }
-
- public void getIMSI(Message result) {
- getIMSIForApp(null, result);
- }
- /**
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is String containing IMSI on success
- */
- public void getIMSIForApp(String aid, Message result) {
- resultSuccess(result, "012345678901234");
- }
-
- /**
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is String containing IMEI on success
- */
- public void getIMEI(Message result) {
- resultSuccess(result, "012345678901234");
- }
-
- /**
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is String containing IMEISV on success
- */
- public void getIMEISV(Message result) {
- resultSuccess(result, "99");
- }
-
- /**
- * Hang up one individual connection.
- * returned message
- * retMsg.obj = AsyncResult ar
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- *
- * 3GPP 22.030 6.5.5
- * "Releases a specific active call X"
- */
- public void hangupConnection (int gsmIndex, Message result) {
- boolean success;
-
- success = simulatedCallState.onChld('1', (char)('0'+gsmIndex));
-
- if (!success){
- Log.i("GSM", "[SimCmd] hangupConnection: resultFail");
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- Log.i("GSM", "[SimCmd] hangupConnection: resultSuccess");
- resultSuccess(result, null);
- }
- }
-
- /**
- * 3GPP 22.030 6.5.5
- * "Releases all held calls or sets User Determined User Busy (UDUB)
- * for a waiting call."
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void hangupWaitingOrBackground (Message result) {
- boolean success;
-
- success = simulatedCallState.onChld('0', '\0');
-
- if (!success){
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- resultSuccess(result, null);
- }
- }
-
- /**
- * 3GPP 22.030 6.5.5
- * "Releases all active calls (if any exist) and accepts
- * the other (held or waiting) call."
- *
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void hangupForegroundResumeBackground (Message result) {
- boolean success;
-
- success = simulatedCallState.onChld('1', '\0');
-
- if (!success){
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- resultSuccess(result, null);
- }
- }
-
- /**
- * 3GPP 22.030 6.5.5
- * "Places all active calls (if any exist) on hold and accepts
- * the other (held or waiting) call."
- *
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void switchWaitingOrHoldingAndActive (Message result) {
- boolean success;
-
- success = simulatedCallState.onChld('2', '\0');
-
- if (!success){
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- resultSuccess(result, null);
- }
- }
-
- /**
- * 3GPP 22.030 6.5.5
- * "Adds a held call to the conversation"
- *
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void conference (Message result) {
- boolean success;
-
- success = simulatedCallState.onChld('3', '\0');
-
- if (!success){
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- resultSuccess(result, null);
- }
- }
-
- /**
- * 3GPP 22.030 6.5.5
- * "Connects the two calls and disconnects the subscriber from both calls"
- *
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void explicitCallTransfer (Message result) {
- boolean success;
-
- success = simulatedCallState.onChld('4', '\0');
-
- if (!success){
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- resultSuccess(result, null);
- }
- }
-
- /**
- * 3GPP 22.030 6.5.5
- * "Places all active calls on hold except call X with which
- * communication shall be supported."
- */
- public void separateConnection (int gsmIndex, Message result) {
- boolean success;
-
- char ch = (char)(gsmIndex + '0');
- success = simulatedCallState.onChld('2', ch);
-
- if (!success){
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- resultSuccess(result, null);
- }
- }
-
- /**
- *
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void acceptCall (Message result) {
- boolean success;
-
- success = simulatedCallState.onAnswer();
-
- if (!success){
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- resultSuccess(result, null);
- }
- }
-
- /**
- * also known as UDUB
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void rejectCall (Message result) {
- boolean success;
-
- success = simulatedCallState.onChld('0', '\0');
-
- if (!success){
- resultFail(result, new RuntimeException("Hangup Error"));
- } else {
- resultSuccess(result, null);
- }
- }
-
- /**
- * cause code returned as Integer in Message.obj.response
- * Returns integer cause code defined in TS 24.008
- * Annex H or closest approximation.
- * Most significant codes:
- * - Any defined in 22.001 F.4 (for generating busy/congestion)
- * - Cause 68: ACM >= ACMMax
- */
- public void getLastCallFailCause (Message result) {
- int[] ret = new int[1];
-
- ret[0] = nextCallFailCause;
- resultSuccess(result, ret);
- }
-
- /**
- * @deprecated
- */
- public void getLastPdpFailCause (Message result) {
- unimplemented(result);
- }
-
- public void getLastDataCallFailCause(Message result) {
- //
- unimplemented(result);
- }
-
- public void setMute (boolean enableMute, Message result) {unimplemented(result);}
-
- public void getMute (Message result) {unimplemented(result);}
-
- /**
- * 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)
- * as defined in TS 27.007 8.5
- */
- public void getSignalStrength (Message result) {
- int ret[] = new int[2];
-
- ret[0] = 23;
- ret[1] = 0;
-
- resultSuccess(result, ret);
- }
-
- /**
- * Assign a specified band for RF configuration.
- *
- * @param bandMode one of BM_*_BAND
- * @param result is callback message
- */
- public void setBandMode (int bandMode, Message result) {
- resultSuccess(result, null);
- }
-
- /**
- * Query the list of band mode supported by RF.
- *
- * @param result is callback message
- * ((AsyncResult)response.obj).result is an int[] with every
- * element representing one available BM_*_BAND
- */
- public void queryAvailableBandMode (Message result) {
- int ret[] = new int [4];
-
- ret[0] = 4;
- ret[1] = Phone.BM_US_BAND;
- ret[2] = Phone.BM_JPN_BAND;
- ret[3] = Phone.BM_AUS_BAND;
-
- resultSuccess(result, ret);
- }
-
- /**
- * {@inheritDoc}
- */
- public void sendTerminalResponse(String contents, Message response) {
- resultSuccess(response, null);
- }
-
- /**
- * {@inheritDoc}
- */
- public void sendEnvelope(String contents, Message response) {
- resultSuccess(response, null);
- }
-
- /**
- * {@inheritDoc}
- */
- public void sendEnvelopeWithStatus(String contents, Message response) {
- resultSuccess(response, null);
- }
-
- /**
- * {@inheritDoc}
- */
- public void handleCallSetupRequestFromSim(
- boolean accept, Message response) {
- resultSuccess(response, null);
- }
-
- /**
- * response.obj.result is an String[14]
- * See ril.h for details
- *
- * Please note that registration state 4 ("unknown") is treated
- * as "out of service" above
- */
- public void getVoiceRegistrationState (Message result) {
- String ret[] = new String[14];
-
- ret[0] = "5"; // registered roam
- ret[1] = null;
- ret[2] = null;
- ret[3] = null;
- ret[4] = null;
- ret[5] = null;
- ret[6] = null;
- ret[7] = null;
- ret[8] = null;
- ret[9] = null;
- ret[10] = null;
- ret[11] = null;
- ret[12] = null;
- ret[13] = null;
-
- resultSuccess(result, ret);
- }
-
- /**
- * response.obj.result is an String[4]
- * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2
- * response.obj.result[1] is LAC if registered or NULL if not
- * response.obj.result[2] is CID if registered or NULL if not
- * response.obj.result[3] indicates the available radio technology, where:
- * 0 == unknown
- * 1 == GPRS only
- * 2 == EDGE
- * 3 == UMTS
- *
- * valid LAC are 0x0000 - 0xffff
- * valid CID are 0x00000000 - 0xffffffff
- *
- * Please note that registration state 4 ("unknown") is treated
- * as "out of service" in the Android telephony system
- */
- public void getDataRegistrationState (Message result) {
- String ret[] = new String[4];
-
- ret[0] = "5"; // registered roam
- ret[1] = null;
- ret[2] = null;
- ret[3] = "2";
-
- resultSuccess(result, ret);
- }
-
- /**
- * response.obj.result is a String[3]
- * 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
- */
- public void getOperator(Message result) {
- String[] ret = new String[3];
-
- ret[0] = "El Telco Loco";
- ret[1] = "Telco Loco";
- ret[2] = "001001";
-
- resultSuccess(result, ret);
- }
-
- /**
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void sendDtmf(char c, Message result) {
- resultSuccess(result, null);
- }
-
- /**
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void startDtmf(char c, Message result) {
- resultSuccess(result, null);
- }
-
- /**
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void stopDtmf(Message result) {
- resultSuccess(result, null);
- }
-
- /**
- * ar.exception carries exception on failure
- * ar.userObject contains the original value of result.obj
- * ar.result is null on success and failure
- */
- public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
- resultSuccess(result, null);
- }
-
- /**
- * 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
- */
- public void sendSMS (String smscPDU, String pdu, Message result) {unimplemented(result);}
-
- public void deleteSmsOnSim(int index, Message response) {
- Log.d(LOG_TAG, "Delete message at index " + index);
- unimplemented(response);
- }
-
- public void deleteSmsOnRuim(int index, Message response) {
- Log.d(LOG_TAG, "Delete RUIM message at index " + index);
- unimplemented(response);
- }
-
- public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
- Log.d(LOG_TAG, "Write SMS to SIM with status " + status);
- unimplemented(response);
- }
-
- public void writeSmsToRuim(int status, String pdu, Message response) {
- Log.d(LOG_TAG, "Write SMS to RUIM with status " + status);
- unimplemented(response);
- }
-
- public void setupDataCall(String radioTechnology, String profile,
- String apn, String user, String password, String authType,
- String protocol, Message result) {
- unimplemented(result);
- }
-
- public void deactivateDataCall(int cid, int reason, Message result) {unimplemented(result);}
-
- public void setPreferredNetworkType(int networkType , Message result) {
- mNetworkType = networkType;
- resultSuccess(result, null);
- }
-
- public void getPreferredNetworkType(Message result) {
- int ret[] = new int[1];
-
- ret[0] = mNetworkType;
- resultSuccess(result, ret);
- }
-
- public void getNeighboringCids(Message result) {
- int ret[] = new int[7];
-
- ret[0] = 6;
- for (int i = 1; i<7; i++) {
- ret[i] = i;
- }
- resultSuccess(result, ret);
- }
-
- public void setLocationUpdates(boolean enable, Message response) {
- unimplemented(response);
- }
-
- public void getSmscAddress(Message result) {
- unimplemented(result);
- }
-
- public void setSmscAddress(String address, Message result) {
- unimplemented(result);
- }
-
- public void reportSmsMemoryStatus(boolean available, Message result) {
- unimplemented(result);
- }
-
- public void reportStkServiceIsRunning(Message result) {
- resultSuccess(result, null);
- }
-
- @Override
- public void getCdmaSubscriptionSource(Message result) {
- unimplemented(result);
- }
-
- private boolean isSimLocked() {
- if (mSimLockedState != SimLockState.NONE) {
- return true;
- }
- return false;
- }
-
- public void setRadioPower(boolean on, Message result) {
- if(on) {
- setRadioState(RadioState.RADIO_ON);
- } else {
- setRadioState(RadioState.RADIO_OFF);
- }
- }
-
-
- public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
- unimplemented(result);
- }
-
- public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
- unimplemented(result);
- }
-
- public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
- Message result) {
- unimplemented(result);
- }
-
- public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data,
- String pin2, Message response) {
- iccIOForApp(command, fileid, path, p1, p2, p3, data,pin2, null, response);
- }
-
- /**
- * parameters equivalent to 27.007 AT+CRSM command
- * response.obj will be an AsyncResult
- * response.obj.userObj will be a SimIoResult on success
- */
- public void iccIOForApp (int command, int fileid, String path, int p1, int p2,
- int p3, String data, String pin2, String aid, Message result) {
- unimplemented(result);
- }
-
- /**
- * (AsyncResult)response.obj).result is an int[] with element [0] set to
- * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned".
- *
- * @param response is callback message
- */
- public void queryCLIP(Message response) { unimplemented(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
- *
- * 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
- */
-
- public void getCLIR(Message result) {unimplemented(result);}
-
- /**
- * clirMode is one of the CLIR_* constants above
- *
- * response.obj is null
- */
-
- public void setCLIR(int clirMode, Message result) {unimplemented(result);}
-
- /**
- * (AsyncResult)response.obj).result is an int[] with element [0] set to
- * 0 for disabled, 1 for enabled.
- *
- * @param serviceClass is a sum of SERVICE_CLASS_*
- * @param response is callback message
- */
-
- public void queryCallWaiting(int serviceClass, Message response) {
- unimplemented(response);
- }
-
- /**
- * @param enable is true to enable, false to disable
- * @param serviceClass is a sum of SERVICE_CLASS_*
- * @param response is callback message
- */
-
- public void setCallWaiting(boolean enable, int serviceClass,
- Message response) {
- unimplemented(response);
- }
-
- /**
- * @param action is one of CF_ACTION_*
- * @param cfReason is one of CF_REASON_*
- * @param serviceClass is a sum of SERVICE_CLASSS_*
- */
- public void setCallForward(int action, int cfReason, int serviceClass,
- String number, int timeSeconds, Message result) {unimplemented(result);}
-
- /**
- * 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"
- */
- public void queryCallForwardStatus(int cfReason, int serviceClass,
- String number, Message result) {unimplemented(result);}
-
- public void setNetworkSelectionModeAutomatic(Message result) {unimplemented(result);}
- public void exitEmergencyCallbackMode(Message result) {unimplemented(result);}
- public void setNetworkSelectionModeManual(
- String operatorNumeric, Message result) {unimplemented(result);}
-
- /**
- * Queries whether the current network selection mode is automatic
- * or manual
- *
- * ((AsyncResult)response.obj).result is an int[] with element [0] being
- * a 0 for automatic selection and a 1 for manual selection
- */
-
- public void getNetworkSelectionMode(Message result) {
- int ret[] = new int[1];
-
- ret[0] = 0;
- resultSuccess(result, ret);
- }
-
- /**
- * Queries the currently available networks
- *
- * ((AsyncResult)response.obj).result is a List of NetworkInfo objects
- */
- public void getAvailableNetworks(Message result) {unimplemented(result);}
-
- public void getBasebandVersion (Message result) {
- resultSuccess(result, "SimulatedCommands");
- }
-
- /**
- * Simulates an incoming USSD message
- * @param statusCode Status code string. See <code>setOnUSSD</code>
- * in CommandsInterface.java
- * @param message Message text to send or null if none
- */
- public void triggerIncomingUssd(String statusCode, String message) {
- if (mUSSDRegistrant != null) {
- String[] result = {statusCode, message};
- mUSSDRegistrant.notifyResult(result);
- }
- }
-
-
- public void sendUSSD (String ussdString, Message result) {
-
- // We simulate this particular sequence
- if (ussdString.equals("#646#")) {
- resultSuccess(result, null);
-
- // 0 == USSD-Notify
- triggerIncomingUssd("0", "You have NNN minutes remaining.");
- } else {
- resultSuccess(result, null);
-
- triggerIncomingUssd("0", "All Done");
- }
- }
-
- // inherited javadoc suffices
- public void cancelPendingUssd (Message response) {
- resultSuccess(response, null);
- }
-
-
- public void resetRadio(Message result) {
- unimplemented(result);
- }
-
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- // Just echo back data
- if (response != null) {
- AsyncResult.forMessage(response).result = data;
- response.sendToTarget();
- }
- }
-
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- // Just echo back data
- if (response != null) {
- AsyncResult.forMessage(response).result = strings;
- response.sendToTarget();
- }
- }
-
- //***** SimulatedRadioControl
-
-
- /** Start the simulated phone ringing */
- public void
- triggerRing(String number) {
- simulatedCallState.triggerRing(number);
- mCallStateRegistrants.notifyRegistrants();
- }
-
- public void
- progressConnectingCallState() {
- simulatedCallState.progressConnectingCallState();
- mCallStateRegistrants.notifyRegistrants();
- }
-
- /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
- public void
- progressConnectingToActive() {
- simulatedCallState.progressConnectingToActive();
- mCallStateRegistrants.notifyRegistrants();
- }
-
- /** automatically progress mobile originated calls to ACTIVE.
- * default to true
- */
- public void
- setAutoProgressConnectingCall(boolean b) {
- simulatedCallState.setAutoProgressConnectingCall(b);
- }
-
- public void
- setNextDialFailImmediately(boolean b) {
- simulatedCallState.setNextDialFailImmediately(b);
- }
-
- public void
- setNextCallFailCause(int gsmCause) {
- nextCallFailCause = gsmCause;
- }
-
- public void
- triggerHangupForeground() {
- simulatedCallState.triggerHangupForeground();
- mCallStateRegistrants.notifyRegistrants();
- }
-
- /** hangup holding calls */
- public void
- triggerHangupBackground() {
- simulatedCallState.triggerHangupBackground();
- mCallStateRegistrants.notifyRegistrants();
- }
-
- public void triggerSsn(int type, int code) {
- SuppServiceNotification not = new SuppServiceNotification();
- not.notificationType = type;
- not.code = code;
- mSsnRegistrant.notifyRegistrant(new AsyncResult(null, not, null));
- }
-
- public void
- shutdown() {
- setRadioState(RadioState.RADIO_UNAVAILABLE);
- Looper looper = mHandlerThread.getLooper();
- if (looper != null) {
- looper.quit();
- }
- }
-
- /** hangup all */
-
- public void
- triggerHangupAll() {
- simulatedCallState.triggerHangupAll();
- mCallStateRegistrants.notifyRegistrants();
- }
-
- public void
- triggerIncomingSMS(String message) {
- //TODO
- }
-
- public void
- pauseResponses() {
- pausedResponseCount++;
- }
-
- public void
- resumeResponses() {
- pausedResponseCount--;
-
- if (pausedResponseCount == 0) {
- for (int i = 0, s = pausedResponses.size(); i < s ; i++) {
- pausedResponses.get(i).sendToTarget();
- }
- pausedResponses.clear();
- } else {
- Log.e("GSM", "SimulatedCommands.resumeResponses < 0");
- }
- }
-
- //***** Private Methods
-
- private void unimplemented(Message result) {
- if (result != null) {
- AsyncResult.forMessage(result).exception
- = new RuntimeException("Unimplemented");
-
- if (pausedResponseCount > 0) {
- pausedResponses.add(result);
- } else {
- result.sendToTarget();
- }
- }
- }
-
- private void resultSuccess(Message result, Object ret) {
- if (result != null) {
- AsyncResult.forMessage(result).result = ret;
- if (pausedResponseCount > 0) {
- pausedResponses.add(result);
- } else {
- result.sendToTarget();
- }
- }
- }
-
- private void resultFail(Message result, Throwable tr) {
- if (result != null) {
- AsyncResult.forMessage(result).exception = tr;
- if (pausedResponseCount > 0) {
- pausedResponses.add(result);
- } else {
- result.sendToTarget();
- }
- }
- }
-
- // ***** Methods for CDMA support
- public void
- getDeviceIdentity(Message response) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(response);
- }
-
- public void
- getCDMASubscription(Message response) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(response);
- }
-
- public void
- setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(response);
- }
-
- public void queryCdmaRoamingPreference(Message response) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(response);
- }
-
- public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(response);
- }
-
- public void
- setPhoneType(int phoneType) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- }
-
- public void getPreferredVoicePrivacy(Message result) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(result);
- }
-
- public void setPreferredVoicePrivacy(boolean enable, Message result) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(result);
- }
-
- /**
- * Set the TTY mode
- *
- * @param ttyMode is one of the following:
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
- * @param response is callback message
- */
- public void setTTYMode(int ttyMode, Message response) {
- Log.w(LOG_TAG, "Not implemented in SimulatedCommands");
- unimplemented(response);
- }
-
- /**
- * Query the TTY mode
- * (AsyncResult)response.obj).result is an int[] with element [0] set to
- * tty mode:
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
- * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
- * @param response is callback message
- */
- public void queryTTYMode(Message response) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(response);
- }
-
- /**
- * {@inheritDoc}
- */
- public void sendCDMAFeatureCode(String FeatureCode, Message response) {
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- unimplemented(response);
- }
-
- /**
- * {@inheritDoc}
- */
- public void sendCdmaSms(byte[] pdu, Message response){
- Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
- }
-
- public void setCdmaBroadcastActivation(boolean activate, Message response) {
- unimplemented(response);
-
- }
-
- public void getCdmaBroadcastConfig(Message response) {
- unimplemented(response);
-
- }
-
- public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
- unimplemented(response);
-
- }
-
- public void forceDataDormancy(Message response) {
- unimplemented(response);
- }
-
-
- public void setGsmBroadcastActivation(boolean activate, Message response) {
- unimplemented(response);
- }
-
-
- public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
- unimplemented(response);
- }
-
- public void getGsmBroadcastConfig(Message response) {
- unimplemented(response);
- }
-
- @Override
- public void supplyIccPinForApp(String pin, String aid, Message response) {
- unimplemented(response);
- }
-
- @Override
- public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
- unimplemented(response);
- }
-
- @Override
- public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
- unimplemented(response);
- }
-
- @Override
- public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
- unimplemented(response);
- }
-
- @Override
- public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
- unimplemented(response);
- }
-
- @Override
- public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
- Message response) {
- unimplemented(response);
- }
-
- public void requestIsimAuthentication(String nonce, Message response) {
- unimplemented(response);
- }
-
- public void getVoiceRadioTechnology(Message response) {
- unimplemented(response);
- }
-}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java b/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
deleted file mode 100644
index c6c301d..0000000
--- a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
- * 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.test;
-
-import android.os.Looper;
-import android.os.Message;
-import android.os.Handler;
-import android.telephony.PhoneNumberUtils;
-import com.android.internal.telephony.ATParseEx;
-import com.android.internal.telephony.DriverCall;
-import java.util.List;
-import java.util.ArrayList;
-
-import android.util.Log;
-
-class CallInfo {
- enum State {
- ACTIVE(0),
- HOLDING(1),
- DIALING(2), // MO call only
- ALERTING(3), // MO call only
- INCOMING(4), // MT call only
- WAITING(5); // MT call only
-
- State (int value) {this.value = value;}
-
- private final int value;
- public int value() {return value;};
- };
-
- boolean isMT;
- State state;
- boolean isMpty;
- String number;
- int TOA;
-
- CallInfo (boolean isMT, State state, boolean isMpty, String number) {
- this.isMT = isMT;
- this.state = state;
- this.isMpty = isMpty;
- this.number = number;
-
- if (number.length() > 0 && number.charAt(0) == '+') {
- TOA = PhoneNumberUtils.TOA_International;
- } else {
- TOA = PhoneNumberUtils.TOA_Unknown;
- }
- }
-
- static CallInfo
- createOutgoingCall(String number) {
- return new CallInfo (false, State.DIALING, false, number);
- }
-
- static CallInfo
- createIncomingCall(String number) {
- return new CallInfo (true, State.INCOMING, false, number);
- }
-
- String
- toCLCCLine(int index) {
- return
- "+CLCC: "
- + index + "," + (isMT ? "1" : "0") +","
- + state.value() + ",0," + (isMpty ? "1" : "0")
- + ",\"" + number + "\"," + TOA;
- }
-
- DriverCall
- toDriverCall(int index) {
- DriverCall ret;
-
- ret = new DriverCall();
-
- ret.index = index;
- ret.isMT = isMT;
-
- try {
- ret.state = DriverCall.stateFromCLCC(state.value());
- } catch (ATParseEx ex) {
- throw new RuntimeException("should never happen", ex);
- }
-
- ret.isMpty = isMpty;
- ret.number = number;
- ret.TOA = TOA;
- ret.isVoice = true;
- ret.als = 0;
-
- return ret;
- }
-
-
- boolean
- isActiveOrHeld() {
- return state == State.ACTIVE || state == State.HOLDING;
- }
-
- boolean
- isConnecting() {
- return state == State.DIALING || state == State.ALERTING;
- }
-
- boolean
- isRinging() {
- return state == State.INCOMING || state == State.WAITING;
- }
-
-}
-
-class InvalidStateEx extends Exception {
- InvalidStateEx() {
-
- }
-}
-
-
-class SimulatedGsmCallState extends Handler {
- //***** Instance Variables
-
- CallInfo calls[] = new CallInfo[MAX_CALLS];
-
- private boolean autoProgressConnecting = true;
- private boolean nextDialFailImmediately;
-
-
- //***** Event Constants
-
- static final int EVENT_PROGRESS_CALL_STATE = 1;
-
- //***** Constants
-
- static final int MAX_CALLS = 7;
- /** number of msec between dialing -> alerting and alerting->active */
- static final int CONNECTING_PAUSE_MSEC = 5 * 100;
-
-
- //***** Overridden from Handler
-
- public SimulatedGsmCallState(Looper looper) {
- super(looper);
- }
-
- public void
- handleMessage(Message msg) {
- synchronized(this) { switch (msg.what) {
- // PLEASE REMEMBER
- // calls may have hung up by the time delayed events happen
-
- case EVENT_PROGRESS_CALL_STATE:
- progressConnectingCallState();
- break;
- }}
- }
-
- //***** Public Methods
-
- /**
- * Start the simulated phone ringing
- * true if succeeded, false if failed
- */
- public boolean
- triggerRing(String number) {
- synchronized (this) {
- int empty = -1;
- boolean isCallWaiting = false;
-
- // ensure there aren't already calls INCOMING or WAITING
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call == null && empty < 0) {
- empty = i;
- } else if (call != null
- && (call.state == CallInfo.State.INCOMING
- || call.state == CallInfo.State.WAITING)
- ) {
- Log.w("ModelInterpreter",
- "triggerRing failed; phone already ringing");
- return false;
- } else if (call != null) {
- isCallWaiting = true;
- }
- }
-
- if (empty < 0 ) {
- Log.w("ModelInterpreter", "triggerRing failed; all full");
- return false;
- }
-
- calls[empty] = CallInfo.createIncomingCall(
- PhoneNumberUtils.extractNetworkPortion(number));
-
- if (isCallWaiting) {
- calls[empty].state = CallInfo.State.WAITING;
- }
-
- }
- return true;
- }
-
- /** If a call is DIALING or ALERTING, progress it to the next state */
- public void
- progressConnectingCallState() {
- synchronized (this) {
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call != null && call.state == CallInfo.State.DIALING) {
- call.state = CallInfo.State.ALERTING;
-
- if (autoProgressConnecting) {
- sendMessageDelayed(
- obtainMessage(EVENT_PROGRESS_CALL_STATE, call),
- CONNECTING_PAUSE_MSEC);
- }
- break;
- } else if (call != null
- && call.state == CallInfo.State.ALERTING
- ) {
- call.state = CallInfo.State.ACTIVE;
- break;
- }
- }
- }
- }
-
- /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */
- public void
- progressConnectingToActive() {
- synchronized (this) {
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call != null && (call.state == CallInfo.State.DIALING
- || call.state == CallInfo.State.ALERTING)
- ) {
- call.state = CallInfo.State.ACTIVE;
- break;
- }
- }
- }
- }
-
- /** automatically progress mobile originated calls to ACTIVE.
- * default to true
- */
- public void
- setAutoProgressConnectingCall(boolean b) {
- autoProgressConnecting = b;
- }
-
- public void
- setNextDialFailImmediately(boolean b) {
- nextDialFailImmediately = b;
- }
-
- /**
- * hangup ringing, dialing, or active calls
- * returns true if call was hung up, false if not
- */
- public boolean
- triggerHangupForeground() {
- synchronized (this) {
- boolean found;
-
- found = false;
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call != null
- && (call.state == CallInfo.State.INCOMING
- || call.state == CallInfo.State.WAITING)
- ) {
- calls[i] = null;
- found = true;
- }
- }
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call != null
- && (call.state == CallInfo.State.DIALING
- || call.state == CallInfo.State.ACTIVE
- || call.state == CallInfo.State.ALERTING)
- ) {
- calls[i] = null;
- found = true;
- }
- }
- return found;
- }
- }
-
- /**
- * hangup holding calls
- * returns true if call was hung up, false if not
- */
- public boolean
- triggerHangupBackground() {
- synchronized (this) {
- boolean found = false;
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call != null && call.state == CallInfo.State.HOLDING) {
- calls[i] = null;
- found = true;
- }
- }
-
- return found;
- }
- }
-
- /**
- * hangup all
- * returns true if call was hung up, false if not
- */
- public boolean
- triggerHangupAll() {
- synchronized(this) {
- boolean found = false;
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (calls[i] != null) {
- found = true;
- }
-
- calls[i] = null;
- }
-
- return found;
- }
- }
-
- public boolean
- onAnswer() {
- synchronized (this) {
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call != null
- && (call.state == CallInfo.State.INCOMING
- || call.state == CallInfo.State.WAITING)
- ) {
- return switchActiveAndHeldOrWaiting();
- }
- }
- }
-
- return false;
- }
-
- public boolean
- onHangup() {
- boolean found = false;
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call != null && call.state != CallInfo.State.WAITING) {
- calls[i] = null;
- found = true;
- }
- }
-
- return found;
- }
-
- public boolean
- onChld(char c0, char c1) {
- boolean ret;
- int callIndex = 0;
-
- if (c1 != 0) {
- callIndex = c1 - '1';
-
- if (callIndex < 0 || callIndex >= calls.length) {
- return false;
- }
- }
-
- switch (c0) {
- case '0':
- ret = releaseHeldOrUDUB();
- break;
- case '1':
- if (c1 <= 0) {
- ret = releaseActiveAcceptHeldOrWaiting();
- } else {
- if (calls[callIndex] == null) {
- ret = false;
- } else {
- calls[callIndex] = null;
- ret = true;
- }
- }
- break;
- case '2':
- if (c1 <= 0) {
- ret = switchActiveAndHeldOrWaiting();
- } else {
- ret = separateCall(callIndex);
- }
- break;
- case '3':
- ret = conference();
- break;
- case '4':
- ret = explicitCallTransfer();
- break;
- case '5':
- if (true) { //just so javac doesnt complain about break
- //CCBS not impled
- ret = false;
- }
- break;
- default:
- ret = false;
-
- }
-
- return ret;
- }
-
- public boolean
- releaseHeldOrUDUB() {
- boolean found = false;
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null && c.isRinging()) {
- found = true;
- calls[i] = null;
- break;
- }
- }
-
- if (!found) {
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null && c.state == CallInfo.State.HOLDING) {
- found = true;
- calls[i] = null;
- // don't stop...there may be more than one
- }
- }
- }
-
- return true;
- }
-
-
- public boolean
- releaseActiveAcceptHeldOrWaiting() {
- boolean foundHeld = false;
- boolean foundActive = false;
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null && c.state == CallInfo.State.ACTIVE) {
- calls[i] = null;
- foundActive = true;
- }
- }
-
- if (!foundActive) {
- // FIXME this may not actually be how most basebands react
- // CHLD=1 may not hang up dialing/alerting calls
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null
- && (c.state == CallInfo.State.DIALING
- || c.state == CallInfo.State.ALERTING)
- ) {
- calls[i] = null;
- foundActive = true;
- }
- }
- }
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null && c.state == CallInfo.State.HOLDING) {
- c.state = CallInfo.State.ACTIVE;
- foundHeld = true;
- }
- }
-
- if (foundHeld) {
- return true;
- }
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null && c.isRinging()) {
- c.state = CallInfo.State.ACTIVE;
- return true;
- }
- }
-
- return true;
- }
-
- public boolean
- switchActiveAndHeldOrWaiting() {
- boolean hasHeld = false;
-
- // first, are there held calls?
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null && c.state == CallInfo.State.HOLDING) {
- hasHeld = true;
- break;
- }
- }
-
- // Now, switch
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null) {
- if (c.state == CallInfo.State.ACTIVE) {
- c.state = CallInfo.State.HOLDING;
- } else if (c.state == CallInfo.State.HOLDING) {
- c.state = CallInfo.State.ACTIVE;
- } else if (!hasHeld && c.isRinging()) {
- c.state = CallInfo.State.ACTIVE;
- }
- }
- }
-
- return true;
- }
-
-
- public boolean
- separateCall(int index) {
- try {
- CallInfo c;
-
- c = calls[index];
-
- if (c == null || c.isConnecting() || countActiveLines() != 1) {
- return false;
- }
-
- c.state = CallInfo.State.ACTIVE;
- c.isMpty = false;
-
- for (int i = 0 ; i < calls.length ; i++) {
- int countHeld=0, lastHeld=0;
-
- if (i != index) {
- CallInfo cb = calls[i];
-
- if (cb != null && cb.state == CallInfo.State.ACTIVE) {
- cb.state = CallInfo.State.HOLDING;
- countHeld++;
- lastHeld = i;
- }
- }
-
- if (countHeld == 1) {
- // if there's only one left, clear the MPTY flag
- calls[lastHeld].isMpty = false;
- }
- }
-
- return true;
- } catch (InvalidStateEx ex) {
- return false;
- }
- }
-
-
-
- public boolean
- conference() {
- int countCalls = 0;
-
- // if there's connecting calls, we can't do this yet
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null) {
- countCalls++;
-
- if (c.isConnecting()) {
- return false;
- }
- }
- }
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null) {
- c.state = CallInfo.State.ACTIVE;
- if (countCalls > 0) {
- c.isMpty = true;
- }
- }
- }
-
- return true;
- }
-
- public boolean
- explicitCallTransfer() {
- int countCalls = 0;
-
- // if there's connecting calls, we can't do this yet
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null) {
- countCalls++;
-
- if (c.isConnecting()) {
- return false;
- }
- }
- }
-
- // disconnect the subscriber from both calls
- return triggerHangupAll();
- }
-
- public boolean
- onDial(String address) {
- CallInfo call;
- int freeSlot = -1;
-
- Log.d("GSM", "SC> dial '" + address + "'");
-
- if (nextDialFailImmediately) {
- nextDialFailImmediately = false;
-
- Log.d("GSM", "SC< dial fail (per request)");
- return false;
- }
-
- String phNum = PhoneNumberUtils.extractNetworkPortion(address);
-
- if (phNum.length() == 0) {
- Log.d("GSM", "SC< dial fail (invalid ph num)");
- return false;
- }
-
- // Ignore setting up GPRS
- if (phNum.startsWith("*99") && phNum.endsWith("#")) {
- Log.d("GSM", "SC< dial ignored (gprs)");
- return true;
- }
-
- // There can be at most 1 active "line" when we initiate
- // a new call
- try {
- if (countActiveLines() > 1) {
- Log.d("GSM", "SC< dial fail (invalid call state)");
- return false;
- }
- } catch (InvalidStateEx ex) {
- Log.d("GSM", "SC< dial fail (invalid call state)");
- return false;
- }
-
- for (int i = 0 ; i < calls.length ; i++) {
- if (freeSlot < 0 && calls[i] == null) {
- freeSlot = i;
- }
-
- if (calls[i] != null && !calls[i].isActiveOrHeld()) {
- // Can't make outgoing calls when there is a ringing or
- // connecting outgoing call
- Log.d("GSM", "SC< dial fail (invalid call state)");
- return false;
- } else if (calls[i] != null && calls[i].state == CallInfo.State.ACTIVE) {
- // All active calls behome held
- calls[i].state = CallInfo.State.HOLDING;
- }
- }
-
- if (freeSlot < 0) {
- Log.d("GSM", "SC< dial fail (invalid call state)");
- return false;
- }
-
- calls[freeSlot] = CallInfo.createOutgoingCall(phNum);
-
- if (autoProgressConnecting) {
- sendMessageDelayed(
- obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]),
- CONNECTING_PAUSE_MSEC);
- }
-
- Log.d("GSM", "SC< dial (slot = " + freeSlot + ")");
-
- return true;
- }
-
- public List<DriverCall>
- getDriverCalls() {
- ArrayList<DriverCall> ret = new ArrayList<DriverCall>(calls.length);
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null) {
- DriverCall dc;
-
- dc = c.toDriverCall(i + 1);
- ret.add(dc);
- }
- }
-
- Log.d("GSM", "SC< getDriverCalls " + ret);
-
- return ret;
- }
-
- public List<String>
- getClccLines() {
- ArrayList<String> ret = new ArrayList<String>(calls.length);
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo c = calls[i];
-
- if (c != null) {
- ret.add((c.toCLCCLine(i + 1)));
- }
- }
-
- return ret;
- }
-
- private int
- countActiveLines() throws InvalidStateEx {
- boolean hasMpty = false;
- boolean hasHeld = false;
- boolean hasActive = false;
- boolean hasConnecting = false;
- boolean hasRinging = false;
- boolean mptyIsHeld = false;
-
- for (int i = 0 ; i < calls.length ; i++) {
- CallInfo call = calls[i];
-
- if (call != null) {
- if (!hasMpty && call.isMpty) {
- mptyIsHeld = call.state == CallInfo.State.HOLDING;
- } else if (call.isMpty && mptyIsHeld
- && call.state == CallInfo.State.ACTIVE
- ) {
- Log.e("ModelInterpreter", "Invalid state");
- throw new InvalidStateEx();
- } else if (!call.isMpty && hasMpty && mptyIsHeld
- && call.state == CallInfo.State.HOLDING
- ) {
- Log.e("ModelInterpreter", "Invalid state");
- throw new InvalidStateEx();
- }
-
- hasMpty |= call.isMpty;
- hasHeld |= call.state == CallInfo.State.HOLDING;
- hasActive |= call.state == CallInfo.State.ACTIVE;
- hasConnecting |= call.isConnecting();
- hasRinging |= call.isRinging();
- }
- }
-
- int ret = 0;
-
- if (hasHeld) ret++;
- if (hasActive) ret++;
- if (hasConnecting) ret++;
- if (hasRinging) ret++;
-
- return ret;
- }
-
-}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java b/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
deleted file mode 100644
index 054d370..0000000
--- a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.test;
-
-public interface SimulatedRadioControl
-{
- public void triggerRing(String number);
-
- public void progressConnectingCallState();
-
- public void progressConnectingToActive();
-
- public void setAutoProgressConnectingCall(boolean b);
-
- public void setNextDialFailImmediately(boolean b);
-
- public void setNextCallFailCause(int gsmCause);
-
- public void triggerHangupForeground();
-
- public void triggerHangupBackground();
-
- public void triggerHangupAll();
-
- public void triggerIncomingSMS(String message);
-
- public void shutdown();
-
- /** Pause responses to async requests until (ref-counted) resumeResponses() */
- public void pauseResponses();
-
- /** see pauseResponses */
- public void resumeResponses();
-
- public void triggerSsn(int type, int code);
-
- /** Generates an incoming USSD message. */
- public void triggerIncomingUssd(String statusCode, String message);
-}
diff --git a/telephony/java/com/android/internal/telephony/test/package.html b/telephony/java/com/android/internal/telephony/test/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/telephony/java/com/android/internal/telephony/test/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/telephony/java/com/android/internal/telephony/uicc/UiccController.java b/telephony/java/com/android/internal/telephony/uicc/UiccController.java
deleted file mode 100644
index 5961efd..0000000
--- a/telephony/java/com/android/internal/telephony/uicc/UiccController.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 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.uicc;
-
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.PhoneBase;
-import com.android.internal.telephony.cdma.CDMALTEPhone;
-import com.android.internal.telephony.cdma.CDMAPhone;
-import com.android.internal.telephony.gsm.GSMPhone;
-
-import android.util.Log;
-
-/* This class is responsible for keeping all knowledge about
- * ICCs in the system. It is also used as API to get appropriate
- * applications to pass them to phone and service trackers.
- */
-public class UiccController {
- private static final boolean DBG = true;
- private static final String LOG_TAG = "RIL_UiccController";
-
- private static UiccController mInstance;
-
- private PhoneBase mCurrentPhone;
- private boolean mIsCurrentCard3gpp;
- private IccCard mIccCard;
-
- public static synchronized UiccController getInstance(PhoneBase phone) {
- if (mInstance == null) {
- mInstance = new UiccController(phone);
- } else {
- mInstance.setNewPhone(phone);
- }
- return mInstance;
- }
-
- public IccCard getIccCard() {
- return mIccCard;
- }
-
- private UiccController(PhoneBase phone) {
- if (DBG) log("Creating UiccController");
- setNewPhone(phone);
- }
-
- private void setNewPhone(PhoneBase phone) {
- mCurrentPhone = phone;
- if (phone instanceof GSMPhone) {
- if (DBG) log("New phone is GSMPhone");
- updateCurrentCard(IccCard.CARD_IS_3GPP);
- } else if (phone instanceof CDMALTEPhone){
- if (DBG) log("New phone type is CDMALTEPhone");
- updateCurrentCard(IccCard.CARD_IS_3GPP);
- } else if (phone instanceof CDMAPhone){
- if (DBG) log("New phone type is CDMAPhone");
- updateCurrentCard(IccCard.CARD_IS_NOT_3GPP);
- } else {
- Log.e(LOG_TAG, "Unhandled phone type. Critical error!");
- }
- }
-
- private void updateCurrentCard(boolean isNewCard3gpp) {
- if (mIsCurrentCard3gpp == isNewCard3gpp && mIccCard != null) {
- return;
- }
-
- if (mIccCard != null) {
- mIccCard.dispose();
- mIccCard = null;
- }
-
- mIsCurrentCard3gpp = isNewCard3gpp;
- mIccCard = new IccCard(mCurrentPhone, mCurrentPhone.getPhoneName(),
- isNewCard3gpp, DBG);
- }
-
- private void log(String string) {
- Log.d(LOG_TAG, string);
- }
-}
\ No newline at end of file
diff --git a/telephony/mockril/Android.mk b/telephony/mockril/Android.mk
deleted file mode 100644
index 95ae84c..0000000
--- a/telephony/mockril/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2010 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.
-#
-#
-
-LOCAL_PATH:=$(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := core framework
-
-LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java
-
-LOCAL_MODULE := mockrilcontroller
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java b/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java
deleted file mode 100644
index 0e75c72..0000000
--- a/telephony/mockril/src/com/android/internal/telephony/mockril/MockRilController.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2010, 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.mockril;
-
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.internal.communication.MsgHeader;
-import com.android.internal.communication.Msg;
-import com.android.internal.telephony.RilChannel;
-import com.android.internal.telephony.ril_proto.RilCtrlCmds;
-import com.android.internal.telephony.ril_proto.RilCmds;
-import com.google.protobuf.micro.MessageMicro;
-
-import java.io.IOException;
-
-/**
- * Contain a list of commands to control Mock RIL. Before using these commands the devices
- * needs to be set with Mock RIL. Refer to hardware/ril/mockril/README.txt for details.
- *
- */
-public class MockRilController {
- private static final String TAG = "MockRILController";
- private RilChannel mRilChannel = null;
- private Msg mMessage = null;
-
- public MockRilController() throws IOException {
- mRilChannel = RilChannel.makeRilChannel();
- }
-
- /**
- * Close the channel after the communication is done.
- * This method has to be called after the test is finished.
- */
- public void closeChannel() {
- mRilChannel.close();
- }
-
- /**
- * Send commands and return true on success
- * @param cmd for MsgHeader
- * @param token for MsgHeader
- * @param status for MsgHeader
- * @param pbData for Msg data
- * @return true if command is sent successfully, false if it fails
- */
- private boolean sendCtrlCommand(int cmd, long token, int status, MessageMicro pbData) {
- try {
- Msg.send(mRilChannel, cmd, token, status, pbData);
- } catch (IOException e) {
- Log.v(TAG, "send command : %d failed: " + e.getStackTrace());
- return false;
- }
- return true;
- }
-
- /**
- * Get control response
- * @return Msg if response is received, else return null.
- */
- private Msg getCtrlResponse() {
- Msg response = null;
- try {
- response = Msg.recv(mRilChannel);
- } catch (IOException e) {
- Log.v(TAG, "receive response for getRadioState() error: " + e.getStackTrace());
- return null;
- }
- return response;
- }
-
- /**
- * @return the radio state if it is valid, otherwise return -1
- */
- public int getRadioState() {
- if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_GET_RADIO_STATE, 0, 0, null)) {
- return -1;
- }
- Msg response = getCtrlResponse();
- if (response == null) {
- Log.v(TAG, "failed to get response");
- return -1;
- }
- response.printHeader(TAG);
- RilCtrlCmds.CtrlRspRadioState resp =
- response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
- int state = resp.getState();
- if ((state >= RilCmds.RADIOSTATE_OFF) && (state <= RilCmds.RADIOSTATE_NV_READY))
- return state;
- else
- return -1;
- }
-
- /**
- * Set the radio state of mock ril to the given state
- * @param state for given radio state
- * @return true if the state is set successful, false if it fails
- */
- public boolean setRadioState(int state) {
- RilCtrlCmds.CtrlReqRadioState req = new RilCtrlCmds.CtrlReqRadioState();
- if (state < 0 || state > RilCmds.RADIOSTATE_NV_READY) {
- Log.v(TAG, "the give radio state is not valid.");
- return false;
- }
- req.setState(state);
- if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, req)) {
- Log.v(TAG, "send set radio state request failed.");
- return false;
- }
- Msg response = getCtrlResponse();
- if (response == null) {
- Log.v(TAG, "failed to get response for setRadioState");
- return false;
- }
- response.printHeader(TAG);
- RilCtrlCmds.CtrlRspRadioState resp =
- response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
- int curstate = resp.getState();
- return curstate == state;
- }
-
- /**
- * Start an incoming call for the given phone number
- *
- * @param phoneNumber is the number to show as incoming call
- * @return true if the incoming call is started successfully, false if it fails.
- */
- public boolean startIncomingCall(String phoneNumber) {
- RilCtrlCmds.CtrlReqSetMTCall req = new RilCtrlCmds.CtrlReqSetMTCall();
-
- req.setPhoneNumber(phoneNumber);
- if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, req)) {
- Log.v(TAG, "send CMD_SET_MT_CALL request failed");
- return false;
- }
- return true;
- }
-
- /**
- * Hang up a connection remotelly for the given call fail cause
- *
- * @param connectionID is the connection to be hung up
- * @param failCause is the call fail cause defined in ril.h
- * @return true if the hangup is successful, false if it fails
- */
- public boolean hangupRemote(int connectionId, int failCause) {
- RilCtrlCmds.CtrlHangupConnRemote req = new RilCtrlCmds.CtrlHangupConnRemote();
- req.setConnectionId(connectionId);
- req.setCallFailCause(failCause);
-
- if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, req)) {
- Log.v(TAG, "send CTRL_CMD_HANGUP_CONN_REMOTE request failed");
- return false;
- }
- return true;
- }
-
- /**
- * Set call transition flag to the Mock Ril
- *
- * @param flag is a boolean value for the call transiton flag
- * true: call transition: dialing->alert, alert->active is controlled
- * false: call transition is automatically handled by Mock Ril
- * @return true if the request is successful, false if it failed to set the flag
- */
- public boolean setCallTransitionFlag(boolean flag) {
- RilCtrlCmds.CtrlSetCallTransitionFlag req = new RilCtrlCmds.CtrlSetCallTransitionFlag();
-
- req.setFlag(flag);
-
- if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, req)) {
- Log.v(TAG, "send CTRL_CMD_SET_CALL_TRANSITION_FLAG request failed");
- return false;
- }
- return true;
- }
-
- /**
- * Set the dialing call to alert if the call transition flag is true
- *
- * @return true if the call transition is successful, false if it fails
- */
- public boolean setDialCallToAlert() {
- if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null)) {
- Log.v(TAG, "send CTRL_CMD_SET_CALL_ALERT request failed");
- return false;
- }
- return true;
- }
-
- /**
- * Set the alert call to active if the call transition flag is true
- *
- * @return true if the call transition is successful, false if it fails
- */
- public boolean setAlertCallToActive() {
- if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null)) {
- Log.v(TAG, "send CTRL_CMD_SET_CALL_ACTIVE request failed");
- return false;
- }
- return true;
- }
-}
diff --git a/telephony/tests/telephonymockriltests/Android.mk b/telephony/tests/telephonymockriltests/Android.mk
deleted file mode 100644
index 9731d0d..0000000
--- a/telephony/tests/telephonymockriltests/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_STATIC_JAVA_LIBRARIES := mockrilcontroller
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := TelephonyMockRilTests
-
-include $(BUILD_PACKAGE)
diff --git a/telephony/tests/telephonymockriltests/AndroidManifest.xml b/telephony/tests/telephonymockriltests/AndroidManifest.xml
deleted file mode 100644
index 63f44a2..0000000
--- a/telephony/tests/telephonymockriltests/AndroidManifest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Copyright (C) 2009 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.telephonymockriltests">
-
- <application>
- <uses-library android:name="android.test.runner" />
- <activity android:label="TelephonyMockRilTest"
- android:name="TelephonyMockRilTest">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- </application>
-
- <instrumentation android:name=".TelephonyMockTestRunner"
- android:targetPackage="com.android.telephonymockriltests"
- android:label="Test runner for Telephony Tests Using Mock RIL"
- />
-
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.INTERNET" />
-
-</manifest>
diff --git a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java
deleted file mode 100644
index 78ee738..0000000
--- a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/TelephonyMockTestRunner.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010, 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.telephonymockriltests;
-
-import android.os.Bundle;
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-import com.android.internal.telephony.mockril.MockRilController;
-import android.util.Log;
-
-import com.android.telephonymockriltests.functional.SimpleTestUsingMockRil;
-
-import java.io.IOException;
-import junit.framework.TestSuite;
-import junit.framework.TestCase;
-
-/**
- * Test runner for telephony tests that using Mock RIL
- *
- */
-public class TelephonyMockTestRunner extends InstrumentationTestRunner {
- private static final String TAG="TelephonyMockTestRunner";
- public MockRilController mController;
-
- @Override
- public TestSuite getAllTests() {
- TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(SimpleTestUsingMockRil.class);
- return suite;
- }
-
- @Override
- public void onCreate(Bundle icicle) {
- try {
- mController = new MockRilController();
- } catch (IOException e) {
- e.printStackTrace();
- TestCase.assertTrue("Create Mock RIl Controller failed", false);
- }
- TestCase.assertNotNull(mController);
- super.onCreate(icicle);
- }
-
- @Override
- public void finish(int resultCode, Bundle results) {
- if (mController != null)
- mController.closeChannel();
- super.finish(resultCode, results);
- }
-}
diff --git a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java b/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java
deleted file mode 100644
index 3ea1cf2..0000000
--- a/telephony/tests/telephonymockriltests/src/com/android/telephonymockriltests/functional/SimpleTestUsingMockRil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 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.telephonymockriltests.functional;
-
-import com.android.internal.telephony.mockril.MockRilController;
-import android.test.InstrumentationTestCase;
-import android.util.Log;
-
-import com.android.telephonymockriltests.TelephonyMockTestRunner;
-
-/**
- * A simple test that using Mock RIL Controller
- */
-public class SimpleTestUsingMockRil extends InstrumentationTestCase {
- private static final String TAG = "SimpleTestUsingMockRil";
- private MockRilController mMockRilCtrl = null;
- private TelephonyMockTestRunner mRunner;
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- mRunner = (TelephonyMockTestRunner)getInstrumentation();
- mMockRilCtrl = mRunner.mController;
- assertNotNull(mMockRilCtrl);
- }
-
- /**
- * Get the current radio state of RIL
- */
- public void testGetRadioState() {
- int state = mMockRilCtrl.getRadioState();
- Log.v(TAG, "testGetRadioState: " + state);
- assertTrue(state >= 0 && state <= 9);
- }
-
- /**
- * Set the current radio state of RIL
- * and verify the radio state is set correctly
- */
- public void testSetRadioState() {
- for (int state = 0; state <= 9; state++) {
- Log.v(TAG, "set radio state to be " + state);
- assertTrue("set radio state: " + state + " failed.",
- mMockRilCtrl.setRadioState(state));
- }
- assertFalse("use an invalid radio state", mMockRilCtrl.setRadioState(-1));
- assertFalse("the radio state doesn't exist", mMockRilCtrl.setRadioState(10));
- }
-}
diff --git a/telephony/tests/telephonytests/Android.mk b/telephony/tests/telephonytests/Android.mk
deleted file mode 100644
index 98e4403..0000000
--- a/telephony/tests/telephonytests/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := FrameworksTelephonyTests
-
-include $(BUILD_PACKAGE)
diff --git a/telephony/tests/telephonytests/AndroidManifest.xml b/telephony/tests/telephonytests/AndroidManifest.xml
deleted file mode 100644
index ba1d957..0000000
--- a/telephony/tests/telephonytests/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Copyright (C) 2009 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.frameworks.telephonytests">
-
- <application>
- <uses-library android:name="android.test.runner" />
- <activity android:label="TelephonyTest"
- android:name="TelephonyTest">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- </application>
- <instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.frameworks.telephonytests"
- android:label="Frameworks Telephony Tests">
- </instrumentation>
-
- <instrumentation android:name=".TelephonyMockRilTestRunner"
- android:targetPackage="com.android.frameworks.telephonytests"
- android:label="Test Runner for Mock Ril Tests"
- />
-
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.INTERNET" />
-
-</manifest>
diff --git a/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java b/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java
deleted file mode 100644
index 9192f57..0000000
--- a/telephony/tests/telephonytests/src/com/android/frameworks/telephonytests/TelephonyMockRilTestRunner.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010, 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.frameworks.telephonytests;
-
-import android.os.Bundle;
-
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-import android.util.Log;
-
-import java.io.IOException;
-
-import com.android.internal.telephony.RilChannel;
-import com.android.internal.telephony.mockril.MockRilTest;
-
-import junit.framework.TestSuite;
-
-public class TelephonyMockRilTestRunner extends InstrumentationTestRunner {
-
- public RilChannel mMockRilChannel;
-
- @Override
- public TestSuite getAllTests() {
- log("getAllTests E");
- TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(MockRilTest.class);
- log("getAllTests X");
- return suite;
- }
-
- @Override
- public ClassLoader getLoader() {
- log("getLoader EX");
- return TelephonyMockRilTestRunner.class.getClassLoader();
- }
-
- @Override
- public void onCreate(Bundle icicle) {
- log("onCreate E");
- try {
- mMockRilChannel = RilChannel.makeRilChannel();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- log("onCreate X");
-
- super.onCreate(icicle);
- }
-
- @Override
- public void onDestroy() {
- // I've not seen this called
- log("onDestroy EX");
- super.onDestroy();
- }
-
- @Override
- public void onStart() {
- // Called when the instrumentation thread is started.
- // At the moment we don't need the thread so return
- // which will shut down this unused thread.
- log("onStart EX");
- super.onStart();
- }
-
- @Override
- public void finish(int resultCode, Bundle results) {
- // Called when complete so I ask the mMockRilChannel to quit.
- log("finish E");
- mMockRilChannel.close();
- log("finish X");
- super.finish(resultCode, results);
- }
-
- private void log(String s) {
- Log.e("TelephonyMockRilTestRunner", s);
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java
deleted file mode 100644
index 81727e4..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/ATResponseParserTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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 junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class ATResponseParserTest extends TestCase {
- @SmallTest
- public void testBasic() throws Exception {
- ATResponseParser p = new ATResponseParser("+CREG: 0");
-
- assertEquals(0, p.nextInt());
-
- assertFalse(p.hasMore());
-
- try {
- p.nextInt();
- fail("exception expected");
- } catch (ATParseEx ex) {
- //test pass
- }
-
- p = new ATResponseParser("+CREG: 0,1");
- assertEquals(0, p.nextInt());
- assertEquals(1, p.nextInt());
- assertFalse(p.hasMore());
-
- p = new ATResponseParser("+CREG: 0, 1");
- assertEquals(0, p.nextInt());
- assertEquals(1, p.nextInt());
- assertFalse(p.hasMore());
-
- p = new ATResponseParser("+CREG: 0, 1,");
- assertEquals(0, p.nextInt());
- assertEquals(1, p.nextInt());
- // this seems odd but is probably OK
- assertFalse(p.hasMore());
- try {
- p.nextInt();
- fail("exception expected");
- } catch (ATParseEx ex) {
- //test pass
- }
-
- p = new ATResponseParser("+CREG: 0, 1 ");
- assertEquals(0, p.nextInt());
- assertEquals(1, p.nextInt());
- assertFalse(p.hasMore());
-
- p = new ATResponseParser("0, 1 ");
- // no prefix -> exception
- try {
- p.nextInt();
- fail("exception expected");
- } catch (ATParseEx ex) {
- //test pass
- }
-
- p = new ATResponseParser("+CREG: 0, 1, 5");
- assertFalse(p.nextBoolean());
- assertTrue(p.nextBoolean());
- try {
- // is this over-constraining?
- p.nextBoolean();
- fail("exception expected");
- } catch (ATParseEx ex) {
- //test pass
- }
-
- p = new ATResponseParser("+CLCC: 1,0,2,0,0,\"+18005551212\",145");
-
- assertEquals(1, p.nextInt());
- assertFalse(p.nextBoolean());
- assertEquals(2, p.nextInt());
- assertEquals(0, p.nextInt());
- assertEquals(0, p.nextInt());
- assertEquals("+18005551212", p.nextString());
- assertEquals(145, p.nextInt());
- assertFalse(p.hasMore());
-
- p = new ATResponseParser("+CLCC: 1,0,2,0,0,\"+18005551212,145");
-
- assertEquals(1, p.nextInt());
- assertFalse(p.nextBoolean());
- assertEquals(2, p.nextInt());
- assertEquals(0, p.nextInt());
- assertEquals(0, p.nextInt());
- try {
- p.nextString();
- fail("expected ex");
- } catch (ATParseEx ex) {
- //test pass
- }
-
- p = new ATResponseParser("+FOO: \"\"");
- assertEquals("", p.nextString());
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java
deleted file mode 100644
index 8a4a285..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/AdnRecordTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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 junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * {@hide}
- */
-public class AdnRecordTest extends TestCase {
-
- @SmallTest
- public void testBasic() throws Exception {
- AdnRecord adn;
-
- //
- // Typical record
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes("566F696365204D61696C07918150367742F3FFFFFFFFFFFF"));
-
- assertEquals("Voice Mail", adn.getAlphaTag());
- assertEquals("+18056377243", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // Empty records, empty strings
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
-
- assertEquals("", adn.getAlphaTag());
- assertEquals("", adn.getNumber());
- assertTrue(adn.isEmpty());
-
- //
- // Record too short
- //
- adn = new AdnRecord(IccUtils.hexStringToBytes( "FF"));
-
- assertEquals("", adn.getAlphaTag());
- assertEquals("", adn.getNumber());
- assertTrue(adn.isEmpty());
-
- //
- // TOA = 0xff ("control string")
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes("566F696365204D61696C07FF8150367742F3FFFFFFFFFFFF"));
-
- assertEquals("Voice Mail", adn.getAlphaTag());
- assertEquals("18056377243", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // TOA = 0x81 (unknown)
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes("566F696365204D61696C07818150367742F3FFFFFFFFFFFF"));
-
- assertEquals("Voice Mail", adn.getAlphaTag());
- assertEquals("18056377243", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // Number Length is too long
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes("566F696365204D61696C0F918150367742F3FFFFFFFFFFFF"));
-
- assertEquals("Voice Mail", adn.getAlphaTag());
- assertEquals("", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // Number Length is zero (invalid)
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes("566F696365204D61696C00918150367742F3FFFFFFFFFFFF"));
-
- assertEquals("Voice Mail", adn.getAlphaTag());
- assertEquals("", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // Number Length is 2, first number byte is FF, TOA is international
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes("566F696365204D61696C0291FF50367742F3FFFFFFFFFFFF"));
-
- assertEquals("Voice Mail", adn.getAlphaTag());
- assertEquals("", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // Number Length is 2, first number digit is valid, TOA is international
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes("566F696365204D61696C0291F150367742F3FFFFFFFFFFFF"));
-
- assertEquals("Voice Mail", adn.getAlphaTag());
- assertEquals("+1", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // An extended record
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes(
- "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01"));
-
- assertEquals("Adgjm", adn.getAlphaTag());
- assertEquals("+18885551212,12345678", adn.getNumber());
- assertFalse(adn.isEmpty());
- assertTrue(adn.hasExtendedRecord());
-
- adn.appendExtRecord(IccUtils.hexStringToBytes("0206092143658709ffffffffff"));
-
- assertEquals("Adgjm", adn.getAlphaTag());
- assertEquals("+18885551212,12345678901234567890", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // An extended record with an invalid extension
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes(
- "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01"));
-
- assertEquals("Adgjm", adn.getAlphaTag());
- assertEquals("+18885551212,12345678", adn.getNumber());
- assertFalse(adn.isEmpty());
- assertTrue(adn.hasExtendedRecord());
-
- adn.appendExtRecord(IccUtils.hexStringToBytes("0106092143658709ffffffffff"));
-
- assertEquals("Adgjm", adn.getAlphaTag());
- assertEquals("+18885551212,12345678", adn.getNumber());
- assertFalse(adn.isEmpty());
-
- //
- // An extended record with an invalid extension
- //
- adn = new AdnRecord(
- IccUtils.hexStringToBytes(
- "4164676A6DFFFFFFFFFFFFFFFFFFFFFF0B918188551512C221436587FF01"));
-
- assertEquals("Adgjm", adn.getAlphaTag());
- assertEquals("+18885551212,12345678", adn.getNumber());
- assertFalse(adn.isEmpty());
- assertTrue(adn.hasExtendedRecord());
-
- adn.appendExtRecord(IccUtils.hexStringToBytes("020B092143658709ffffffffff"));
-
- assertEquals("Adgjm", adn.getAlphaTag());
- assertEquals("+18885551212,12345678", adn.getNumber());
- assertFalse(adn.isEmpty());
- }
-}
-
-
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java
deleted file mode 100755
index ac8c4c1..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/ApnSettingTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2010 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 junit.framework.TestCase;
-
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class ApnSettingTest extends TestCase {
-
- public static final String[] TYPES = {"default", "*"};
-
- public static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) {
- assertEquals(a1.carrier, a2.carrier);
- assertEquals(a1.apn, a2.apn);
- assertEquals(a1.proxy, a2.proxy);
- assertEquals(a1.port, a2.port);
- assertEquals(a1.mmsc, a2.mmsc);
- assertEquals(a1.mmsProxy, a2.mmsProxy);
- assertEquals(a1.mmsPort, a2.mmsPort);
- assertEquals(a1.user, a2.user);
- assertEquals(a1.password, a2.password);
- assertEquals(a1.authType, a2.authType);
- assertEquals(a1.id, a2.id);
- assertEquals(a1.numeric, a2.numeric);
- assertEquals(a1.protocol, a2.protocol);
- assertEquals(a1.roamingProtocol, a2.roamingProtocol);
- assertEquals(a1.types.length, a2.types.length);
- int i;
- for (i = 0; i < a1.types.length; i++) {
- assertEquals(a1.types[i], a2.types[i]);
- }
- assertEquals(a1.carrierEnabled, a2.carrierEnabled);
- assertEquals(a1.bearer, a2.bearer);
- }
-
- @SmallTest
- public void testFromString() throws Exception {
- String[] dunTypes = {"DUN"};
- String[] mmsTypes = {"mms", "*"};
-
- ApnSetting expected_apn;
- String testString;
-
- // A real-world v1 example string.
- testString = "Vodafone IT,web.omnitel.it,,,,,,,,,222,10,,DUN";
- expected_apn = new ApnSetting(
- -1, "22210", "Vodafone IT", "web.omnitel.it", "", "",
- "", "", "", "", "", 0, dunTypes, "IP", "IP",true,0);
- assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString));
-
- // A v2 string.
- testString = "[ApnSettingV2] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14";
- expected_apn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "",
- "", "", "", "", "", 0, mmsTypes, "IPV6", "IP",true,14);
- assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString));
-
- // A v2 string with spaces.
- testString = "[ApnSettingV2] Name,apn, ,,,,,,,,123,45,,mms|*,IPV4V6, IP,true,14";
- expected_apn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "",
- "", "", "", "", "", 0, mmsTypes, "IPV4V6", "IP",true,14);
- assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString));
-
- // Return null if insufficient fields given.
- testString = "[ApnSettingV2] Name,apn,,,,,,,,,123, 45,,mms|*";
- assertEquals(null, ApnSetting.fromString(testString));
-
- testString = "Name,apn,,,,,,,,,123, 45,";
- assertEquals(null, ApnSetting.fromString(testString));
-
- // Parse (incorrect) V2 format without the tag as V1.
- testString = "Name,apn,,,,,,,,,123, 45,,mms|*,IPV6,true,14";
- String[] incorrectTypes = {"mms|*", "IPV6"};
- expected_apn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "",
- "", "", "", "", "", 0, incorrectTypes, "IP", "IP",true,14);
- assertApnSettingEqual(expected_apn, ApnSetting.fromString(testString));
- }
-
-
- @SmallTest
- public void testToString() throws Exception {
- String[] types = {"default", "*"};
- ApnSetting apn = new ApnSetting(
- 99, "12345", "Name", "apn", "proxy", "port",
- "mmsc", "mmsproxy", "mmsport", "user", "password", 0,
- types, "IPV4V6", "IP", true, 14);
- String expected = "[ApnSettingV2] Name, 99, 12345, apn, proxy, " +
- "mmsc, mmsproxy, mmsport, port, 0, default | *, " +
- "IPV4V6, IP, true, 14";
- assertEquals(expected, apn.toString());
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java
deleted file mode 100644
index 1e5dafb..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/CallerInfoTest.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2009 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.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.CallerInfoAsyncQuery;
-import android.util.Log;
-import android.os.Looper;
-import android.test.ActivityInstrumentationTestCase;
-import android.util.StringBuilderPrinter;
-
-/*
- * Check the CallerInfo utility class works as expected.
- *
- */
-
-public class CallerInfoTest extends AndroidTestCase {
- private CallerInfo mInfo;
- private Context mContext;
-
- private static final String kEmergencyNumber = "Emergency Number";
- private static final int kToken = 0xdeadbeef;
- private static final String TAG = "CallerInfoUnitTest";
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mContext = new MockContext();
- mInfo = new CallerInfo();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- /**
- * Checks the caller info instance is flagged as an emergency if
- * the number is an emergency one. There is no test for the
- * contact based constructors because emergency number are not in
- * the contact DB.
- */
- @SmallTest
- public void testEmergencyIsProperlySet() throws Exception {
- assertFalse(mInfo.isEmergencyNumber());
-
- mInfo = CallerInfo.getCallerInfo(mContext, "911");
- assertIsValidEmergencyCallerInfo();
-
- mInfo = CallerInfo.getCallerInfo(mContext, "tel:911");
- assertIsValidEmergencyCallerInfo();
-
-
- // This one hits the content resolver.
- mInfo = CallerInfo.getCallerInfo(mContext, "18001234567");
- assertFalse(mInfo.isEmergencyNumber());
- }
-
- /**
- * Same as testEmergencyIsProperlySet but uses the async query api.
- */
- @SmallTest
- public void testEmergencyIsProperlySetUsingAsyncQuery() throws Exception {
- QueryRunner query;
-
- query = new QueryRunner("911");
- query.runAndCheckCompletion();
- assertIsValidEmergencyCallerInfo();
-
- query = new QueryRunner("tel:911");
- query.runAndCheckCompletion();
- assertIsValidEmergencyCallerInfo();
-
- query = new QueryRunner("18001234567");
- query.runAndCheckCompletion();
- assertFalse(mInfo.isEmergencyNumber());
- }
-
- /**
- * For emergency caller info, phoneNumber should be set to the
- * string emergency_call_dialog_number_for_display and the
- * photoResource should be set to the picture_emergency drawable.
- */
- @SmallTest
- public void testEmergencyNumberAndPhotoAreSet() throws Exception {
- mInfo = CallerInfo.getCallerInfo(mContext, "911");
-
- assertIsValidEmergencyCallerInfo();
- }
-
- // TODO: Add more tests:
- /**
- * Check if the voice mail number cannot be retrieved that the
- * original phone number is preserved.
- */
- /**
- * Check the markAs* methods work.
- */
-
-
- //
- // Helpers
- //
-
- // Partial implementation of MockResources.
- public class MockResources extends android.test.mock.MockResources
- {
- @Override
- public String getString(int resId) throws Resources.NotFoundException {
- switch (resId) {
- case com.android.internal.R.string.emergency_call_dialog_number_for_display:
- return kEmergencyNumber;
- default:
- throw new UnsupportedOperationException("Missing handling for resid " + resId);
- }
- }
- }
-
- // Partial implementation of MockContext.
- public class MockContext extends android.test.mock.MockContext {
- private ContentResolver mResolver;
- private Resources mResources;
-
- public MockContext() {
- mResolver = new android.test.mock.MockContentResolver();
- mResources = new MockResources();
- }
-
- @Override
- public ContentResolver getContentResolver() {
- return mResolver;
- }
-
- @Override
- public Resources getResources() {
- return mResources;
- }
- }
-
- /**
- * Class to run a CallerInfoAsyncQuery in a separate thread, with
- * its own Looper. We cannot use the main Looper because on the
- * 1st quit the thread is maked dead, ie no further test can use
- * it. Also there is not way to inject a Looper instance in the
- * query, so we have to use a thread with its own looper.
- */
- private class QueryRunner extends Thread
- implements CallerInfoAsyncQuery.OnQueryCompleteListener {
- private Looper mLooper;
- private String mNumber;
- private boolean mAsyncCompleted;
-
- public QueryRunner(String number) {
- super();
- mNumber = number;
- }
-
- // Run the query in the thread, wait for completion.
- public void runAndCheckCompletion() throws InterruptedException {
- start();
- join();
- assertTrue(mAsyncCompleted);
- }
-
- @Override
- public void run() {
- Looper.prepare();
- mLooper = Looper.myLooper();
- mAsyncCompleted = false;
- // The query will pick the thread local looper we've just prepared.
- CallerInfoAsyncQuery.startQuery(kToken, mContext, mNumber, this, null);
- mLooper.loop();
- }
-
- // Quit the Looper on the 1st callback
- // (EVENT_EMERGENCY_NUMBER). There is another message
- // (EVENT_END_OF_QUEUE) that will never be delivered because
- // the test has exited. The corresponding stack trace
- // "Handler{xxxxx} sending message to a Handler on a dead
- // thread" can be ignored.
- public void onQueryComplete(int token, Object cookie, CallerInfo info) {
- mAsyncCompleted = true;
- mInfo = info;
- mLooper.quit();
- }
- }
-
- /**
- * Fail if mInfo does not contain a valid emergency CallerInfo instance.
- */
- private void assertIsValidEmergencyCallerInfo() throws Exception {
- assertTrue(mInfo.isEmergencyNumber());
-
- // For emergency caller info, phoneNumber should be set to the
- // string emergency_call_dialog_number_for_display and the
- // photoResource should be set to the picture_emergency drawable.
- assertEquals(kEmergencyNumber, mInfo.phoneNumber);
- assertEquals(com.android.internal.R.drawable.picture_emergency, mInfo.photoResource);
-
- // The name should be null
- assertNull(mInfo.name);
- assertEquals(0, mInfo.namePresentation);
- assertNull(mInfo.cnapName);
- assertEquals(0, mInfo.numberPresentation);
-
- assertFalse(mInfo.contactExists);
- assertEquals(0, mInfo.person_id);
- assertFalse(mInfo.needUpdate);
- assertNull(mInfo.contactRefUri);
-
- assertNull(mInfo.phoneLabel);
- assertEquals(0, mInfo.numberType);
- assertNull(mInfo.numberLabel);
-
- assertNull(mInfo.contactRingtoneUri);
- assertFalse(mInfo.shouldSendToVoicemail);
-
- assertNull(mInfo.cachedPhoto);
- assertFalse(mInfo.isCachedPhotoCurrent);
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java
deleted file mode 100644
index f9dc3a9..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmAlphabetTest.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * 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 com.android.internal.telephony.GsmAlphabet;
-
-import junit.framework.TestCase;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class GsmAlphabetTest extends TestCase {
-
- private static final String sGsmExtendedChars = "{|}\\[~]\f\u20ac";
-
- @SmallTest
- public void test7bitWithHeader() throws Exception {
- SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
- concatRef.refNumber = 1;
- concatRef.seqNumber = 2;
- concatRef.msgCount = 2;
- concatRef.isEightBits = true;
- SmsHeader header = new SmsHeader();
- header.concatRef = concatRef;
-
- String message = "aaaaaaaaaabbbbbbbbbbcccccccccc";
- byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message,
- SmsHeader.toByteArray(header), 0, 0);
- int septetCount = GsmAlphabet.countGsmSeptetsUsingTables(message, true, 0, 0);
- String parsedMessage = GsmAlphabet.gsm7BitPackedToString(
- userData, SmsHeader.toByteArray(header).length+2, septetCount, 1, 0, 0);
- assertEquals(message, parsedMessage);
- }
-
- // TODO: This method should *really* be a series of individual test methods.
- // However, it's a SmallTest because it executes quickly.
- @SmallTest
- public void testBasic() throws Exception {
- // '@' maps to char 0
- assertEquals(0, GsmAlphabet.charToGsm('@'));
-
- // `a (a with grave accent) maps to last GSM character
- assertEquals(0x7f, GsmAlphabet.charToGsm('\u00e0'));
-
- //
- // These are the extended chars
- // They should all return GsmAlphabet.GSM_EXTENDED_ESCAPE
- //
-
- for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
- assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE,
- GsmAlphabet.charToGsm(sGsmExtendedChars.charAt(i)));
-
- }
-
- // euro symbol
- assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE,
- GsmAlphabet.charToGsm('\u20ac'));
-
- // An unmappable char (the 'cent' char) maps to a space
- assertEquals(GsmAlphabet.charToGsm(' '),
- GsmAlphabet.charToGsm('\u00a2'));
-
- // unmappable = space = 1 septet
- assertEquals(1, GsmAlphabet.countGsmSeptets('\u00a2'));
-
- //
- // Test extended table
- //
-
- for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
- assertEquals(sGsmExtendedChars.charAt(i),
- GsmAlphabet.gsmExtendedToChar(
- GsmAlphabet.charToGsmExtended(sGsmExtendedChars.charAt(i))));
-
- }
-
- // Unmappable extended char
- assertEquals(GsmAlphabet.charToGsm(' '),
- GsmAlphabet.charToGsmExtended('@'));
-
- //
- // gsmToChar()
- //
-
- assertEquals('@', GsmAlphabet.gsmToChar(0));
-
- // `a (a with grave accent) maps to last GSM character
- assertEquals('\u00e0', GsmAlphabet.gsmToChar(0x7f));
-
- assertEquals('\uffff',
- GsmAlphabet.gsmToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE));
-
- // Out-of-range/unmappable value
- assertEquals(' ', GsmAlphabet.gsmToChar(0x80));
-
- //
- // gsmExtendedToChar()
- //
-
- assertEquals('{', GsmAlphabet.gsmExtendedToChar(0x28));
-
- // No double-escapes
- assertEquals(' ', GsmAlphabet.gsmExtendedToChar(
- GsmAlphabet.GSM_EXTENDED_ESCAPE));
-
- // Reserved for extension to extension table (mapped to space)
- assertEquals(' ', GsmAlphabet.gsmExtendedToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE));
-
- // Unmappable (mapped to character in default or national locking shift table)
- assertEquals('@', GsmAlphabet.gsmExtendedToChar(0));
- assertEquals('\u00e0', GsmAlphabet.gsmExtendedToChar(0x7f));
-
- //
- // stringTo7BitPacked, gsm7BitPackedToString
- //
-
- byte[] packed;
- StringBuilder testString = new StringBuilder(300);
-
- // Check all alignment cases
- for (int i = 0; i < 9; i++, testString.append('@')) {
- packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
- assertEquals(testString.toString(),
- GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
- }
-
- // Check full non-extended alphabet
- for (int i = 0; i < 0x80; i++) {
- char c;
-
- if (i == GsmAlphabet.GSM_EXTENDED_ESCAPE) {
- continue;
- }
-
- c = GsmAlphabet.gsmToChar(i);
- testString.append(c);
-
- // These are all non-extended chars, so it should be
- // one septet per char
- assertEquals(1, GsmAlphabet.countGsmSeptets(c));
- }
-
- packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
- assertEquals(testString.toString(),
- GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-
- // Test extended chars too
-
- testString.append(sGsmExtendedChars);
-
- for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
- // These are all extended chars, so it should be
- // two septets per char
- assertEquals(2, GsmAlphabet.countGsmSeptets(sGsmExtendedChars.charAt(i)));
-
- }
-
- packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
- assertEquals(testString.toString(),
- GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-
- // stringTo7BitPacked handles up to 255 septets
-
- testString.setLength(0);
- for (int i = 0; i < 255; i++) {
- testString.append('@');
- }
-
- packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
- assertEquals(testString.toString(),
- GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-
- // > 255 septets throws runtime exception
- testString.append('@');
-
- try {
- GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
- fail("expected exception");
- } catch (EncodeException ex) {
- // exception expected
- }
-
- // Try 254 septets with 127 extended chars
-
- testString.setLength(0);
- for (int i = 0; i < (255 / 2); i++) {
- testString.append('{');
- }
-
- packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
- assertEquals(testString.toString(),
- GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
-
- // > 255 septets throws runtime exception
- testString.append('{');
-
- try {
- GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
- fail("expected exception");
- } catch (EncodeException ex) {
- // exception expected
- }
-
- // Reserved for extension to extension table (mapped to space)
- packed = new byte[]{(byte)(0x1b | 0x80), 0x1b >> 1};
- assertEquals(" ", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
-
- // Unmappable (mapped to character in default alphabet table)
- packed[0] = 0x1b;
- packed[1] = 0x00;
- assertEquals("@", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
- packed[0] = (byte)(0x1b | 0x80);
- packed[1] = (byte)(0x7f >> 1);
- assertEquals("\u00e0", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
-
- //
- // 8 bit unpacked format
- //
- // Note: we compare hex strings here
- // because Assert doesn't have array comparisons
-
- byte unpacked[];
-
- unpacked = IccUtils.hexStringToBytes("566F696365204D61696C");
- assertEquals("Voice Mail",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
- assertEquals(IccUtils.bytesToHexString(unpacked),
- IccUtils.bytesToHexString(
- GsmAlphabet.stringToGsm8BitPacked("Voice Mail")));
-
- unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars);
- // two bytes for every extended char
- assertEquals(2 * sGsmExtendedChars.length(), unpacked.length);
- assertEquals(sGsmExtendedChars,
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
- // should be two bytes per extended char
- assertEquals(2 * sGsmExtendedChars.length(), unpacked.length);
-
- // Test truncation of unaligned extended chars
- unpacked = new byte[3];
- GsmAlphabet.stringToGsm8BitUnpackedField(sGsmExtendedChars, unpacked,
- 0, unpacked.length);
-
- // Should be one extended char and an 0xff at the end
-
- assertEquals(0xff, 0xff & unpacked[2]);
- assertEquals(sGsmExtendedChars.substring(0, 1),
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
- // Test truncation of normal chars
- unpacked = new byte[3];
- GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked,
- 0, unpacked.length);
-
- assertEquals("abc",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
- // Test truncation of mixed normal and extended chars
- unpacked = new byte[3];
- GsmAlphabet.stringToGsm8BitUnpackedField("a{cd", unpacked,
- 0, unpacked.length);
-
- assertEquals("a{",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
- // Test padding after normal char
- unpacked = new byte[3];
- GsmAlphabet.stringToGsm8BitUnpackedField("a", unpacked,
- 0, unpacked.length);
-
- assertEquals("a",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
- assertEquals(0xff, 0xff & unpacked[1]);
- assertEquals(0xff, 0xff & unpacked[2]);
-
- // Test malformed input -- escape char followed by end of field
- unpacked[0] = 0;
- unpacked[1] = 0;
- unpacked[2] = GsmAlphabet.GSM_EXTENDED_ESCAPE;
-
- assertEquals("@@",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
-
- // non-zero offset
- assertEquals("@",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
-
- // test non-zero offset
- unpacked[0] = 0;
- GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked,
- 1, unpacked.length - 1);
-
-
- assertEquals(0, unpacked[0]);
-
- assertEquals("ab",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
-
- // test non-zero offset with truncated extended char
- unpacked[0] = 0;
-
- GsmAlphabet.stringToGsm8BitUnpackedField("a{", unpacked,
- 1, unpacked.length - 1);
-
- assertEquals(0, unpacked[0]);
-
- assertEquals("a",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
-
- // Reserved for extension to extension table (mapped to space)
- unpacked[0] = 0x1b;
- unpacked[1] = 0x1b;
- assertEquals(" ", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
-
- // Unmappable (mapped to character in default or national locking shift table)
- unpacked[1] = 0x00;
- assertEquals("@", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
- unpacked[1] = 0x7f;
- assertEquals("\u00e0", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
- }
-
- @SmallTest
- public void testGsm8BitUpackedWithEuckr() throws Exception {
- // Some feature phones in Korea store contacts as euc-kr.
- // Test this situations.
- byte unpacked[];
-
- // Test general alphabet strings.
- unpacked = IccUtils.hexStringToBytes("61626320646566FF");
- assertEquals("abc def",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
-
- // Test korean strings.
- unpacked = IccUtils.hexStringToBytes("C5D7BDBAC6AEFF");
- assertEquals("\uD14C\uC2A4\uD2B8",
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
-
- // Test gsm Extented Characters.
- unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars);
- assertEquals(sGsmExtendedChars,
- GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
deleted file mode 100644
index 5950669..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/GsmSmsTest.java
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * 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.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.gsm.SmsMessage;
-import com.android.internal.util.HexDump;
-
-import java.util.ArrayList;
-
-public class GsmSmsTest extends AndroidTestCase {
-
- @SmallTest
- public void testAddressing() throws Exception {
- String pdu = "07914151551512f2040B916105551511f100006060605130308A04D4F29C0E";
- SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
- assertEquals("+14155551212", sms.getServiceCenterAddress());
- assertEquals("+16505551111", sms.getOriginatingAddress());
- assertEquals("Test", sms.getMessageBody());
-
- pdu = "07914151551512f2040B916105551511f100036060924180008A0DA"
- + "8695DAC2E8FE9296A794E07";
- sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
- assertEquals("+14155551212", sms.getServiceCenterAddress());
- assertEquals("+16505551111", sms.getOriginatingAddress());
- assertEquals("(Subject)Test", sms.getMessageBody());
- }
-
- @SmallTest
- public void testUdh() throws Exception {
- String pdu = "07914140279510F6440A8111110301003BF56080207130138A8C0B05040B8423F"
- + "000032A02010106276170706C69636174696F6E2F766E642E7761702E6D6D732D"
- + "6D65737361676500AF848D0185B4848C8298524E453955304A6D7135514141426"
- + "66C414141414D7741414236514141414141008D908918802B3135313232393737"
- + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703"
- + "A2F2F36";
- SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
- SmsHeader header = sms.getUserDataHeader();
- assertNotNull(header);
- assertNotNull(header.concatRef);
- assertEquals(header.concatRef.refNumber, 42);
- assertEquals(header.concatRef.msgCount, 2);
- assertEquals(header.concatRef.seqNumber, 1);
- assertEquals(header.concatRef.isEightBits, true);
- assertNotNull(header.portAddrs);
- assertEquals(header.portAddrs.destPort, 2948);
- assertEquals(header.portAddrs.origPort, 9200);
- assertEquals(header.portAddrs.areEightBits, false);
-
- pdu = "07914140279510F6440A8111110301003BF56080207130238A3B0B05040B8423F"
- + "000032A0202362E3130322E3137312E3135302F524E453955304A6D7135514141"
- + "42666C414141414D774141423651414141414100";
- sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
- header = sms.getUserDataHeader();
- assertNotNull(header);
- assertNotNull(header.concatRef);
- assertEquals(header.concatRef.refNumber, 42);
- assertEquals(header.concatRef.msgCount, 2);
- assertEquals(header.concatRef.seqNumber, 2);
- assertEquals(header.concatRef.isEightBits, true);
- assertNotNull(header.portAddrs);
- assertEquals(header.portAddrs.destPort, 2948);
- assertEquals(header.portAddrs.origPort, 9200);
- assertEquals(header.portAddrs.areEightBits, false);
- }
-
- @SmallTest
- public void testUcs2() throws Exception {
- String pdu = "07912160130300F4040B914151245584F600087010807121352B1021220"
- + "0A900AE00680065006C006C006F";
- SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
- assertEquals("\u2122\u00a9\u00aehello", sms.getMessageBody());
- }
-
- @SmallTest
- public void testMultipart() throws Exception {
- /*
- * Multi-part text SMS with septet data.
- */
- String pdu = "07916163838408F6440B816105224431F700007060217175830AA0050003"
- + "00020162B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
- + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
- + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
- + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562B1582C"
- + "168BC562B1582C168BC562B1582C168BC562B1582C168BC562";
- SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
- assertEquals(sms.getMessageBody(),
- "1111111111111111111111111111111111111111"
- + "1111111111111111111111111111111111111111"
- + "1111111111111111111111111111111111111111"
- + "111111111111111111111111111111111");
-
- pdu = "07916163838408F6440B816105224431F700007060217185000A23050003"
- + "00020262B1582C168BC96432994C2693C96432994C2693C96432990C";
- sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
- assertEquals("1111111222222222222222222222", sms.getMessageBody());
- }
-
- @SmallTest
- public void testCPHSVoiceMail() throws Exception {
- // "set MWI flag"
-
- String pdu = "07912160130310F20404D0110041006060627171118A0120";
-
- SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
- assertTrue(sms.isReplace());
- assertEquals("_@", sms.getOriginatingAddress());
- assertEquals(" ", sms.getMessageBody());
- assertTrue(sms.isMWISetMessage());
-
- // "clear mwi flag"
-
- pdu = "07912160130310F20404D0100041006021924193352B0120";
-
- sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
- assertTrue(sms.isMWIClearMessage());
-
- // "clear MWI flag"
-
- pdu = "07912160130310F20404D0100041006060627161058A0120";
-
- sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
- assertTrue(sms.isReplace());
- assertEquals("\u0394@", sms.getOriginatingAddress());
- assertEquals(" ", sms.getMessageBody());
- assertTrue(sms.isMWIClearMessage());
- }
-
- @SmallTest
- public void testCingularVoiceMail() throws Exception {
- // "set MWI flag"
-
- String pdu = "07912180958750F84401800500C87020026195702B06040102000200";
- SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
- assertTrue(sms.isMWISetMessage());
- assertTrue(sms.isMwiDontStore());
-
- // "clear mwi flag"
-
- pdu = "07912180958750F84401800500C07020027160112B06040102000000";
- sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
- assertTrue(sms.isMWIClearMessage());
- assertTrue(sms.isMwiDontStore());
- }
-
- @SmallTest
- public void testEmailGateway() throws Exception {
- String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" +
- "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3";
-
- SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
- assertEquals("+14155551212", sms.getServiceCenterAddress());
- assertTrue(sms.isEmail());
- assertEquals("foo@example.com", sms.getEmailFrom());
- assertEquals("foo@example.com", sms.getDisplayOriginatingAddress());
- // As of https://android-git.corp.google.com/g/#change,9324
- // getPseudoSubject will always be empty, and any subject is not extracted.
- assertEquals("", sms.getPseudoSubject());
- assertEquals("test subject /test body", sms.getDisplayMessageBody());
- assertEquals("test subject /test body", sms.getEmailBody());
-
- // email gateway sms test, including gsm extended character set.
- pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" +
- "7076d9357eb741af0d0a442fcfe9c23739bfe16d289bdee6b5f1813629";
-
- sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
- assertEquals("+14155551212", sms.getServiceCenterAddress());
- assertTrue(sms.isEmail());
- assertEquals("foo@example.com", sms.getDisplayOriginatingAddress());
- assertEquals("foo@example.com", sms.getEmailFrom());
- assertEquals("{ testBody[^~\\] }", sms.getDisplayMessageBody());
- assertEquals("{ testBody[^~\\] }", sms.getEmailBody());
- }
-
- @SmallTest
- public void testExtendedCharacterTable() throws Exception {
- String pdu = "07914151551512f2040B916105551511f100006080615131728A44D4F29C0E2" +
- "AE3E96537B94C068DD16179784C2FCB41F4B0985D06B958ADD00FB0E94536AF9749" +
- "74DA6D281BA00E95E26D509B946FC3DBF87A25D56A04";
-
- SmsMessage sms = SmsMessage.createFromPdu(HexDump.hexStringToByteArray(pdu));
-
- assertEquals("+14155551212", sms.getServiceCenterAddress());
- assertEquals("+16505551111", sms.getOriginatingAddress());
- assertEquals("Test extended character table .,-!?@~_\\/&\"';^|:()<{}>[]=%*+#",
- sms.getMessageBody());
- }
-
- // GSM 7 bit tables in String form, Escape (0x1B) replaced with '@'
- private static final String[] sBasicTables = {
- // GSM 7 bit default alphabet
- "@\u00a3$\u00a5\u00e8\u00e9\u00f9\u00ec\u00f2\u00c7\n\u00d8\u00f8\r\u00c5\u00e5\u0394_"
- + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u00c6\u00e6\u00df\u00c9"
- + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u00a1ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6"
- + "\u00d1\u00dc\u00a7\u00bfabcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0",
-
- // Turkish locking shift table
- "@\u00a3$\u00a5\u20ac\u00e9\u00f9\u0131\u00f2\u00c7\n\u011e\u011f\r\u00c5\u00e5\u0394_"
- + "\u03a6\u0393\u039b\u03a9\u03a0\u03a8\u03a3\u0398\u039e@\u015e\u015f\u00df\u00c9"
- + " !\"#\u00a4%&'()*+,-./0123456789:;<=>?\u0130ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c4\u00d6"
- + "\u00d1\u00dc\u00a7\u00e7abcdefghijklmnopqrstuvwxyz\u00e4\u00f6\u00f1\u00fc\u00e0",
-
- // no locking shift table defined for Spanish
- "",
-
- // Portuguese locking shift table
- "@\u00a3$\u00a5\u00ea\u00e9\u00fa\u00ed\u00f3\u00e7\n\u00d4\u00f4\r\u00c1\u00e1\u0394_"
- + "\u00aa\u00c7\u00c0\u221e^\\\u20ac\u00d3|@\u00c2\u00e2\u00ca\u00c9 !\"#\u00ba%&'()"
- + "*+,-./0123456789:;<=>?\u00cdABCDEFGHIJKLMNOPQRSTUVWXYZ\u00c3\u00d5\u00da\u00dc"
- + "\u00a7~abcdefghijklmnopqrstuvwxyz\u00e3\u00f5`\u00fc\u00e0"
- };
-
- @SmallTest
- public void testFragmentText() throws Exception {
- boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() ==
- TelephonyManager.PHONE_TYPE_GSM);
-
- // Valid 160 character 7-bit text.
- String text = "123456789012345678901234567890123456789012345678901234567890" +
- "1234567890123456789012345678901234567890123456789012345678901234567890" +
- "123456789012345678901234567890";
- SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false);
- assertEquals(1, ted.msgCount);
- assertEquals(160, ted.codeUnitCount);
- assertEquals(1, ted.codeUnitSize);
- assertEquals(0, ted.languageTable);
- assertEquals(0, ted.languageShiftTable);
- if (isGsmPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
- assertEquals(1, fragments.size());
- }
-
- // Valid 161 character 7-bit text.
- text = "123456789012345678901234567890123456789012345678901234567890" +
- "1234567890123456789012345678901234567890123456789012345678901234567890" +
- "1234567890123456789012345678901";
- ted = SmsMessage.calculateLength(text, false);
- assertEquals(2, ted.msgCount);
- assertEquals(161, ted.codeUnitCount);
- assertEquals(1, ted.codeUnitSize);
- assertEquals(0, ted.languageTable);
- assertEquals(0, ted.languageShiftTable);
- if (isGsmPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
- assertEquals(2, fragments.size());
- assertEquals(text, fragments.get(0) + fragments.get(1));
- assertEquals(153, fragments.get(0).length());
- assertEquals(8, fragments.get(1).length());
- }
- }
-
- @SmallTest
- public void testFragmentTurkishText() throws Exception {
- boolean isGsmPhone = (TelephonyManager.getDefault().getPhoneType() ==
- TelephonyManager.PHONE_TYPE_GSM);
-
- int[] oldTables = GsmAlphabet.getEnabledSingleShiftTables();
- int[] turkishTable = { 1 };
- GsmAlphabet.setEnabledSingleShiftTables(turkishTable);
-
- // Valid 77 character text with Turkish characters.
- String text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
- "ĞŞİğşıĞŞİğşıĞŞİğş";
- SmsMessageBase.TextEncodingDetails ted = SmsMessage.calculateLength(text, false);
- assertEquals(1, ted.msgCount);
- assertEquals(154, ted.codeUnitCount);
- assertEquals(1, ted.codeUnitSize);
- assertEquals(0, ted.languageTable);
- assertEquals(1, ted.languageShiftTable);
- if (isGsmPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
- assertEquals(1, fragments.size());
- assertEquals(text, fragments.get(0));
- assertEquals(77, fragments.get(0).length());
- }
-
- // Valid 78 character text with Turkish characters.
- text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
- "ĞŞİğşıĞŞİğşıĞŞİğşı";
- ted = SmsMessage.calculateLength(text, false);
- assertEquals(2, ted.msgCount);
- assertEquals(156, ted.codeUnitCount);
- assertEquals(1, ted.codeUnitSize);
- assertEquals(0, ted.languageTable);
- assertEquals(1, ted.languageShiftTable);
- if (isGsmPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
- assertEquals(2, fragments.size());
- assertEquals(text, fragments.get(0) + fragments.get(1));
- assertEquals(74, fragments.get(0).length());
- assertEquals(4, fragments.get(1).length());
- }
-
- // Valid 160 character text with Turkish characters.
- text = "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı" +
- "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğ" +
- "ĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşıĞŞİğşı";
- ted = SmsMessage.calculateLength(text, false);
- assertEquals(3, ted.msgCount);
- assertEquals(320, ted.codeUnitCount);
- assertEquals(1, ted.codeUnitSize);
- assertEquals(0, ted.languageTable);
- assertEquals(1, ted.languageShiftTable);
- if (isGsmPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text);
- assertEquals(3, fragments.size());
- assertEquals(text, fragments.get(0) + fragments.get(1) + fragments.get(2));
- assertEquals(74, fragments.get(0).length());
- assertEquals(74, fragments.get(1).length());
- assertEquals(12, fragments.get(2).length());
- }
-
- GsmAlphabet.setEnabledSingleShiftTables(oldTables);
- }
-
-
- @SmallTest
- public void testDecode() throws Exception {
- decodeSingle(0); // default table
- decodeSingle(1); // Turkish locking shift table
- decodeSingle(3); // Portuguese locking shift table
- }
-
- private void decodeSingle(int language) throws Exception {
- byte[] septets = new byte[(7 * 128 + 7) / 8];
-
- int bitOffset = 0;
-
- for (int i = 0; i < 128; i++) {
- int v;
- if (i == 0x1b) {
- // extended escape char
- v = 0;
- } else {
- v = i;
- }
-
- int byteOffset = bitOffset / 8;
- int shift = bitOffset % 8;
-
- septets[byteOffset] |= v << shift;
-
- if (shift > 1) {
- septets[byteOffset + 1] = (byte) (v >> (8 - shift));
- }
-
- bitOffset += 7;
- }
-
- String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, 128, 0, language, 0);
- byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, language, 0);
-
- assertEquals(sBasicTables[language], decoded);
-
- // reEncoded has the count septets byte at the front
- assertEquals(septets.length + 1, reEncoded.length);
-
- for (int i = 0; i < septets.length; i++) {
- assertEquals(septets[i], reEncoded[i + 1]);
- }
- }
-
- private static final int GSM_ESCAPE_CHARACTER = 0x1b;
-
- private static final String[] sExtendedTables = {
- // GSM 7 bit default alphabet extension table
- "\f^{}\\[~]|\u20ac",
-
- // Turkish single shift extension table
- "\f^{}\\[~]|\u011e\u0130\u015e\u00e7\u20ac\u011f\u0131\u015f",
-
- // Spanish single shift extension table
- "\u00e7\f^{}\\[~]|\u00c1\u00cd\u00d3\u00da\u00e1\u20ac\u00ed\u00f3\u00fa",
-
- // Portuguese single shift extension table
- "\u00ea\u00e7\f\u00d4\u00f4\u00c1\u00e1\u03a6\u0393^\u03a9\u03a0\u03a8\u03a3\u0398\u00ca"
- + "{}\\[~]|\u00c0\u00cd\u00d3\u00da\u00c3\u00d5\u00c2\u20ac\u00ed\u00f3\u00fa\u00e3"
- + "\u00f5\u00e2"
- };
-
- private static final int[][] sExtendedTableIndexes = {
- {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x65},
- {0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x47, 0x49, 0x53, 0x63,
- 0x65, 0x67, 0x69, 0x73},
- {0x09, 0x0a, 0x14, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49, 0x4f,
- 0x55, 0x61, 0x65, 0x69, 0x6f, 0x75},
- {0x05, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1f, 0x28, 0x29, 0x2f, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x49,
- 0x4f, 0x55, 0x5b, 0x5c, 0x61, 0x65, 0x69, 0x6f, 0x75, 0x7b, 0x7c, 0x7f}
- };
-
- @SmallTest
- public void testDecodeExtended() throws Exception {
- for (int language = 0; language < 3; language++) {
- int[] tableIndex = sExtendedTableIndexes[language];
- int numSeptets = tableIndex.length * 2; // two septets per extended char
- byte[] septets = new byte[(7 * numSeptets + 7) / 8];
-
- int bitOffset = 0;
-
- for (int v : tableIndex) {
- // escape character
- int byteOffset = bitOffset / 8;
- int shift = bitOffset % 8;
-
- septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift;
-
- if (shift > 1) {
- septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift));
- }
-
- bitOffset += 7;
-
- // extended table index
- byteOffset = bitOffset / 8;
- shift = bitOffset % 8;
-
- septets[byteOffset] |= v << shift;
-
- if (shift > 1) {
- septets[byteOffset + 1] = (byte) (v >> (8 - shift));
- }
-
- bitOffset += 7;
- }
-
- String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0,
- 0, language);
- byte[] reEncoded = GsmAlphabet.stringToGsm7BitPacked(decoded, 0, language);
-
- assertEquals(sExtendedTables[language], decoded);
-
- // reEncoded has the count septets byte at the front
- assertEquals(septets.length + 1, reEncoded.length);
-
- for (int i = 0; i < septets.length; i++) {
- assertEquals(septets[i], reEncoded[i + 1]);
- }
- }
- }
-
- @SmallTest
- public void testDecodeExtendedFallback() throws Exception {
- // verify that unmapped characters in extension table fall back to locking shift table
- for (int language = 0; language < 3; language++) {
- int[] tableIndex = sExtendedTableIndexes[language];
- int numChars = 128 - tableIndex.length;
- int numSeptets = numChars * 2; // two septets per extended char
- byte[] septets = new byte[(7 * numSeptets + 7) / 8];
-
- int tableOffset = 0;
- int bitOffset = 0;
-
- StringBuilder defaultTable = new StringBuilder(128);
- StringBuilder turkishTable = new StringBuilder(128);
- StringBuilder portugueseTable = new StringBuilder(128);
-
- for (char c = 0; c < 128; c++) {
- // skip characters that are present in the current extension table
- if (tableOffset < tableIndex.length && tableIndex[tableOffset] == c) {
- tableOffset++;
- continue;
- }
-
- // escape character
- int byteOffset = bitOffset / 8;
- int shift = bitOffset % 8;
-
- septets[byteOffset] |= GSM_ESCAPE_CHARACTER << shift;
-
- if (shift > 1) {
- septets[byteOffset + 1] = (byte) (GSM_ESCAPE_CHARACTER >> (8 - shift));
- }
-
- bitOffset += 7;
-
- // extended table index
- byteOffset = bitOffset / 8;
- shift = bitOffset % 8;
-
- septets[byteOffset] |= c << shift;
-
- if (shift > 1) {
- septets[byteOffset + 1] = (byte) (c >> (8 - shift));
- }
-
- bitOffset += 7;
-
- if (c == GsmAlphabet.GSM_EXTENDED_ESCAPE) {
- // double Escape maps to space character
- defaultTable.append(' ');
- turkishTable.append(' ');
- portugueseTable.append(' ');
- } else {
- // other unmapped chars map to the default or locking shift table
- defaultTable.append(sBasicTables[0].charAt(c));
- turkishTable.append(sBasicTables[1].charAt(c));
- portugueseTable.append(sBasicTables[3].charAt(c));
- }
- }
-
- String decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0,
- 0, language);
-
- assertEquals(defaultTable.toString(), decoded);
-
- decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 1, language);
- assertEquals(turkishTable.toString(), decoded);
-
- decoded = GsmAlphabet.gsm7BitPackedToString(septets, 0, numSeptets, 0, 3, language);
- assertEquals(portugueseTable.toString(), decoded);
- }
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
deleted file mode 100644
index c89f33a..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/IccServiceTableTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2011 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.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * Test IccServiceTable class.
- */
-public class IccServiceTableTest extends AndroidTestCase {
-
- static class TestIccServiceTable extends IccServiceTable {
- public enum TestIccService {
- SERVICE1,
- SERVICE2,
- SERVICE3,
- SERVICE4
- }
-
- public TestIccServiceTable(byte[] table) {
- super(table);
- }
-
- public boolean isAvailable(TestIccService service) {
- return super.isAvailable(service.ordinal());
- }
-
- @Override
- protected String getTag() {
- return "TestIccServiceTable";
- }
-
- @Override
- protected Object[] getValues() {
- return TestIccService.values();
- }
- }
-
- @SmallTest
- public void testIccServiceTable() {
- byte[] noServices = {0x00};
- byte[] service1 = {0x01};
- byte[] service4 = {0x08};
- byte[] allServices = {0x0f};
-
- TestIccServiceTable testTable1 = new TestIccServiceTable(noServices);
- assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
- assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
- assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
- assertFalse(testTable1.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
-
- TestIccServiceTable testTable2 = new TestIccServiceTable(service1);
- assertTrue(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
- assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
- assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
- assertFalse(testTable2.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
-
- TestIccServiceTable testTable3 = new TestIccServiceTable(service4);
- assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
- assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
- assertFalse(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
- assertTrue(testTable3.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
-
- TestIccServiceTable testTable4 = new TestIccServiceTable(allServices);
- assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE1));
- assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE2));
- assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE3));
- assertTrue(testTable4.isAvailable(TestIccServiceTable.TestIccService.SERVICE4));
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java
deleted file mode 100644
index 79dca39..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/IntRangeManagerTest.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2011 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.test.AndroidTestCase;
-
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-import java.util.ArrayList;
-
-/**
- * Test cases for the IntRangeManager class.
- */
-public class IntRangeManagerTest extends AndroidTestCase {
-
- private static final int SMS_CB_CODE_SCHEME_MIN = 0;
- private static final int SMS_CB_CODE_SCHEME_MAX = 255;
-
- private static final int FLAG_START_UPDATE_CALLED = 0x01;
- private static final int FLAG_ADD_RANGE_CALLED = 0x02;
- private static final int FLAG_FINISH_UPDATE_CALLED = 0x04;
-
- private static final int ALL_FLAGS_SET = FLAG_START_UPDATE_CALLED | FLAG_ADD_RANGE_CALLED |
- FLAG_FINISH_UPDATE_CALLED;
-
- /** Dummy IntRangeManager for testing. */
- class TestIntRangeManager extends IntRangeManager {
- ArrayList<SmsBroadcastConfigInfo> mConfigList =
- new ArrayList<SmsBroadcastConfigInfo>();
-
- int flags;
- boolean finishUpdateReturnValue = true;
-
- /**
- * Called when the list of enabled ranges has changed. This will be
- * followed by zero or more calls to {@link #addRange} followed by
- * a call to {@link #finishUpdate}.
- */
- protected void startUpdate() {
- mConfigList.clear();
- flags |= FLAG_START_UPDATE_CALLED;
- }
-
- /**
- * Called after {@link #startUpdate} to indicate a range of enabled
- * values.
- * @param startId the first id included in the range
- * @param endId the last id included in the range
- */
- protected void addRange(int startId, int endId, boolean selected) {
- mConfigList.add(new SmsBroadcastConfigInfo(startId, endId,
- SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected));
- flags |= FLAG_ADD_RANGE_CALLED;
- }
-
- /**
- * Called to indicate the end of a range update started by the
- * previous call to {@link #startUpdate}.
- */
- protected boolean finishUpdate() {
- flags |= FLAG_FINISH_UPDATE_CALLED;
- return finishUpdateReturnValue;
- }
-
- /** Reset the object for the next test case. */
- void reset() {
- flags = 0;
- mConfigList.clear();
- }
- }
-
- public void testEmptyRangeManager() {
- TestIntRangeManager testManager = new TestIntRangeManager();
- assertEquals("expecting empty configlist", 0, testManager.mConfigList.size());
- }
-
- private void checkConfigInfo(SmsBroadcastConfigInfo info, int fromServiceId,
- int toServiceId, int fromCodeScheme, int toCodeScheme, boolean selected) {
- assertEquals("fromServiceId", fromServiceId, info.getFromServiceId());
- assertEquals("toServiceId", toServiceId, info.getToServiceId());
- assertEquals("fromCodeScheme", fromCodeScheme, info.getFromCodeScheme());
- assertEquals("toCodeScheme", toCodeScheme, info.getToCodeScheme());
- assertEquals("selected", selected, info.isSelected());
- }
-
- public void testAddSingleChannel() {
- TestIntRangeManager testManager = new TestIntRangeManager();
- assertEquals("flags before test", 0, testManager.flags);
- assertTrue("enabling range", testManager.enableRange(123, 123, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- }
-
- public void testRemoveSingleChannel() {
- TestIntRangeManager testManager = new TestIntRangeManager();
- assertTrue("enabling range", testManager.enableRange(123, 123, "client1"));
- assertEquals("flags after enable", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- testManager.reset();
- assertTrue("disabling range", testManager.disableRange(123, 123, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 123, 123, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED,
- testManager.flags);
- assertEquals("configlist size", 0, testManager.mConfigList.size());
- }
-
- public void testRemoveBadChannel() {
- TestIntRangeManager testManager = new TestIntRangeManager();
- assertFalse("disabling missing range", testManager.disableRange(123, 123, "client1"));
- assertEquals("flags after test", 0, testManager.flags);
- assertEquals("configlist size", 0, testManager.mConfigList.size());
- }
-
- public void testAddTwoChannels() {
- TestIntRangeManager testManager = new TestIntRangeManager();
- assertEquals("flags before test", 0, testManager.flags);
- assertTrue("enabling range 1", testManager.enableRange(100, 120, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 100, 120, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("enabling range 2", testManager.enableRange(200, 250, "client2"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 200, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 2, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 100, 120, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(1), 200, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- }
-
- public void testOverlappingChannels() {
- TestIntRangeManager testManager = new TestIntRangeManager();
- assertEquals("flags before test", 0, testManager.flags);
- assertTrue("enabling range 1", testManager.enableRange(100, 200, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 100, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 1", testManager.disableRange(100, 200, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 100, 149, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 150, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED,
- testManager.flags);
- assertEquals("configlist size", 0, testManager.mConfigList.size());
- }
-
- public void testOverlappingChannels2() {
- TestIntRangeManager testManager = new TestIntRangeManager();
- assertEquals("flags before test", 0, testManager.flags);
- assertTrue("enabling range 1", testManager.enableRange(100, 200, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 201, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 1", testManager.disableRange(100, 200, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 100, 200, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- }
-
- public void testMultipleOverlappingChannels() {
- TestIntRangeManager testManager = new TestIntRangeManager();
- assertEquals("flags before test", 0, testManager.flags);
- assertTrue("enabling range 1", testManager.enableRange(67, 9999, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 67, 9999, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("enabling range 2", testManager.enableRange(150, 250, "client2"));
- assertEquals("flags after test", 0, testManager.flags);
- assertEquals("configlist size", 0, testManager.mConfigList.size());
- testManager.reset();
- assertTrue("enabling range 3", testManager.enableRange(25, 75, "client3"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 25, 66, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("enabling range 4", testManager.enableRange(12, 500, "client4"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 12, 24, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("enabling range 5", testManager.enableRange(8000, 9998, "client5"));
- assertEquals("flags after test", 0, testManager.flags);
- assertEquals("configlist size", 0, testManager.mConfigList.size());
- testManager.reset();
- assertTrue("enabling range 6", testManager.enableRange(50000, 65535, "client6"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 2, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 12, 9999, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(1), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 1", testManager.disableRange(67, 9999, "client1"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 2, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 501, 7999, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- checkConfigInfo(testManager.mConfigList.get(1), 9999, 9999, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 3, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 12, 500, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(1), 8000, 9998, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(2), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 4", testManager.disableRange(12, 500, "client4"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 3, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 12, 24, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- checkConfigInfo(testManager.mConfigList.get(1), 76, 149, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- checkConfigInfo(testManager.mConfigList.get(2), 251, 500, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 4, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(2), 8000, 9998, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(3), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 5", testManager.disableRange(8000, 9998, "client5"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 8000, 9998, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 3, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(2), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 6", testManager.disableRange(50000, 65535, "client6"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 50000, 65535, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 2, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- checkConfigInfo(testManager.mConfigList.get(1), 150, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 2", testManager.disableRange(150, 250, "client2"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 150, 250, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, true);
- testManager.reset();
- assertTrue("disabling range 3", testManager.disableRange(25, 75, "client3"));
- assertEquals("flags after test", ALL_FLAGS_SET, testManager.flags);
- assertEquals("configlist size", 1, testManager.mConfigList.size());
- checkConfigInfo(testManager.mConfigList.get(0), 25, 75, SMS_CB_CODE_SCHEME_MIN,
- SMS_CB_CODE_SCHEME_MAX, false);
- testManager.reset();
- assertTrue("updating ranges", testManager.updateRanges());
- assertEquals("flags after test", FLAG_START_UPDATE_CALLED | FLAG_FINISH_UPDATE_CALLED,
- testManager.flags);
- assertEquals("configlist size", 0, testManager.mConfigList.size());
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
deleted file mode 100644
index 868c76d..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 com.android.internal.telephony.MccTable;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import android.util.Log;
-
-public class MccTableTest extends AndroidTestCase {
- private final static String LOG_TAG = "GSM";
-
- @SmallTest
- public void testTimeZone() throws Exception {
- assertEquals(MccTable.defaultTimeZoneForMcc(208), "ECT");
- assertEquals(MccTable.defaultTimeZoneForMcc(232), "Europe/Vienna");
- assertEquals(MccTable.defaultTimeZoneForMcc(655), "Africa/Johannesburg");
- assertEquals(MccTable.defaultTimeZoneForMcc(440), "Asia/Tokyo");
- assertEquals(MccTable.defaultTimeZoneForMcc(441), "Asia/Tokyo");
- assertEquals(MccTable.defaultTimeZoneForMcc(525), "Asia/Singapore");
- assertEquals(MccTable.defaultTimeZoneForMcc(240), null); // tz not defined, hence default
- assertEquals(MccTable.defaultTimeZoneForMcc(0), null); // mcc not defined, hence default
- assertEquals(MccTable.defaultTimeZoneForMcc(2000), null); // mcc not defined, hence default
- }
-
- @SmallTest
- public void testCountryCode() throws Exception {
- assertEquals(MccTable.countryCodeForMcc(270), "lu");
- assertEquals(MccTable.countryCodeForMcc(202), "gr");
- assertEquals(MccTable.countryCodeForMcc(750), "fk");
- assertEquals(MccTable.countryCodeForMcc(646), "mg");
- assertEquals(MccTable.countryCodeForMcc(314), "us");
- assertEquals(MccTable.countryCodeForMcc(300), ""); // mcc not defined, hence default
- assertEquals(MccTable.countryCodeForMcc(0), ""); // mcc not defined, hence default
- assertEquals(MccTable.countryCodeForMcc(2000), ""); // mcc not defined, hence default
- }
-
- @SmallTest
- public void testLang() throws Exception {
- assertEquals(MccTable.defaultLanguageForMcc(311), "en");
- assertEquals(MccTable.defaultLanguageForMcc(232), "de");
- assertEquals(MccTable.defaultLanguageForMcc(230), "cs");
- assertEquals(MccTable.defaultLanguageForMcc(204), "nl");
- assertEquals(MccTable.defaultLanguageForMcc(274), null); // lang not defined, hence default
- assertEquals(MccTable.defaultLanguageForMcc(0), null); // mcc not defined, hence default
- assertEquals(MccTable.defaultLanguageForMcc(2000), null); // mcc not defined, hence default
- }
-
- @SmallTest
- public void testSmDigits() throws Exception {
- assertEquals(MccTable.smallestDigitsMccForMnc(312), 3);
- assertEquals(MccTable.smallestDigitsMccForMnc(430), 2);
- assertEquals(MccTable.smallestDigitsMccForMnc(365), 3);
- assertEquals(MccTable.smallestDigitsMccForMnc(536), 2);
- assertEquals(MccTable.smallestDigitsMccForMnc(352), 2); // sd not defined, hence default
- assertEquals(MccTable.smallestDigitsMccForMnc(0), 2); // mcc not defined, hence default
- assertEquals(MccTable.smallestDigitsMccForMnc(2000), 2); // mcc not defined, hence default
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java
deleted file mode 100644
index b63dc71..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/NeighboringCellInfoTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2009 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.test.AndroidTestCase;
-import android.telephony.NeighboringCellInfo;
-import android.test. suitebuilder.annotation.SmallTest;
-
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
-
-public class NeighboringCellInfoTest extends AndroidTestCase {
- @SmallTest
- public void testConstructor() {
- int rssi = 31;
- NeighboringCellInfo nc;
-
- nc = new NeighboringCellInfo(rssi, "FFFFFFF", NETWORK_TYPE_EDGE);
- assertEquals(NETWORK_TYPE_EDGE, nc.getNetworkType());
- assertEquals(rssi, nc.getRssi());
- assertEquals(0xfff, nc.getLac());
- assertEquals(0xffff, nc.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
-
- nc = new NeighboringCellInfo(rssi, "1FF", NETWORK_TYPE_UMTS);
- assertEquals(NETWORK_TYPE_UMTS, nc.getNetworkType());
- assertEquals(rssi, nc.getRssi());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getLac());
- assertEquals(0x1ff, nc.getPsc());
-
- nc = new NeighboringCellInfo(rssi, "1FF", NETWORK_TYPE_UNKNOWN);
- assertEquals(NETWORK_TYPE_UNKNOWN, nc.getNetworkType());
- assertEquals(rssi, nc.getRssi());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getLac());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
- }
-
- @SmallTest
- public void testParcel() {
- int rssi = 20;
-
- NeighboringCellInfo nc = new NeighboringCellInfo(rssi, "12345678", NETWORK_TYPE_GPRS);
- assertEquals(NETWORK_TYPE_GPRS, nc.getNetworkType());
- assertEquals(rssi, nc.getRssi());
- assertEquals(0x1234, nc.getLac());
- assertEquals(0x5678, nc.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
-
- Parcel p = Parcel.obtain();
- p.setDataPosition(0);
- nc.writeToParcel(p, 0);
-
- p.setDataPosition(0);
- NeighboringCellInfo nw = new NeighboringCellInfo(p);
- assertEquals(NETWORK_TYPE_GPRS, nw.getNetworkType());
- assertEquals(rssi, nw.getRssi());
- assertEquals(0x1234, nw.getLac());
- assertEquals(0x5678, nw.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nw.getPsc());
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
deleted file mode 100644
index db670f8..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * 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.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.SpannableStringBuilder;
-import android.telephony.PhoneNumberUtils;
-
-public class PhoneNumberUtilsTest extends AndroidTestCase {
-
- @SmallTest
- public void testExtractNetworkPortion() throws Exception {
- assertEquals(
- "+17005554141",
- PhoneNumberUtils.extractNetworkPortion("+17005554141")
- );
-
- assertEquals(
- "+17005554141",
- PhoneNumberUtils.extractNetworkPortion("+1 (700).555-4141")
- );
-
- assertEquals(
- "17005554141",
- PhoneNumberUtils.extractNetworkPortion("1 (700).555-4141")
- );
-
- // This may seem wrong, but it's probably ok
- assertEquals(
- "17005554141*#",
- PhoneNumberUtils.extractNetworkPortion("1 (700).555-4141*#")
- );
-
- assertEquals(
- "170055541NN",
- PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN")
- );
-
- assertEquals(
- "170055541NN",
- PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN,1234")
- );
-
- assertEquals(
- "170055541NN",
- PhoneNumberUtils.extractNetworkPortion("1 (700).555-41NN;1234")
- );
-
- // An MMI string is unperterbed, even though it contains a
- // (valid in this case) embedded +
- assertEquals(
- "**21**17005554141#",
- PhoneNumberUtils.extractNetworkPortion("**21**+17005554141#")
- //TODO this is the correct result, although the above
- //result has been returned since change 31776
- //"**21**+17005554141#"
- );
-
- assertEquals("", PhoneNumberUtils.extractNetworkPortion(""));
-
- assertEquals("", PhoneNumberUtils.extractNetworkPortion(",1234"));
-
- byte [] b = new byte[20];
- b[0] = (byte) 0x81; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
- b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
- assertEquals("17005550020",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
- b[0] = (byte) 0x80; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
- b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
- assertEquals("17005550020",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
- b[0] = (byte) 0x90; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
- b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
- assertEquals("+17005550020",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
- b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
- b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0;
- assertEquals("+17005550020",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
- byte[] bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("+17005550020");
- assertEquals(7, bRet.length);
- for (int i = 0; i < 7; i++) {
- assertEquals(b[i], bRet[i]);
- }
-
- bRet = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength("+17005550020");
- assertEquals(8, bRet.length);
- assertEquals(bRet[0], 7);
- for (int i = 1; i < 8; i++) {
- assertEquals(b[i - 1], bRet[i]);
- }
-
- bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("7005550020");
- assertEquals("7005550020",
- PhoneNumberUtils.calledPartyBCDToString(bRet, 0, bRet.length));
-
- b[0] = (byte) 0x81; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
- b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xB0;
- assertEquals("17005550020#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
- b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55;
- b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xB0;
- assertEquals("+17005550020#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 7));
-
- b[0] = (byte) 0x81; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1;
- assertEquals("*21#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 3));
-
- b[0] = (byte) 0x81; b[1] = (byte) 0x2B; b[2] = (byte) 0xB1;
- assertEquals("#21#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 3));
-
- b[0] = (byte) 0x91; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1;
- assertEquals("*21#+",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 3));
-
- b[0] = (byte) 0x81; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0xFB;
- assertEquals("**21#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 4));
-
- b[0] = (byte) 0x91; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0xFB;
- assertEquals("**21#+",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 4));
-
- b[0] = (byte) 0x81; b[1] = (byte) 0x9A; b[2] = (byte) 0xA9; b[3] = (byte) 0x71;
- b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20;
- b[8] = (byte) 0xB0;
- assertEquals("*99*17005550020#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 9));
-
- b[0] = (byte) 0x91; b[1] = (byte) 0x9A; b[2] = (byte) 0xA9; b[3] = (byte) 0x71;
- b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20;
- b[8] = (byte) 0xB0;
- assertEquals("*99*+17005550020#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 9));
-
- b[0] = (byte) 0x81; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0x1A;
- b[4] = (byte) 0x07; b[5] = (byte) 0x50; b[6] = (byte) 0x55; b[7] = (byte) 0x00;
- b[8] = (byte) 0x02; b[9] = (byte) 0xFB;
- assertEquals("**21*17005550020#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 10));
-
- b[0] = (byte) 0x91; b[1] = (byte) 0xAA; b[2] = (byte) 0x12; b[3] = (byte) 0x1A;
- b[4] = (byte) 0x07; b[5] = (byte) 0x50; b[6] = (byte) 0x55; b[7] = (byte) 0x00;
- b[8] = (byte) 0x02; b[9] = (byte) 0xFB;
- assertEquals("**21*+17005550020#",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 10));
-
- b[0] = (byte) 0x81; b[1] = (byte) 0x2A; b[2] = (byte) 0xA1; b[3] = (byte) 0x71;
- b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20;
- b[8] = (byte) 0xF0;
- assertEquals("*21*17005550020",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 9));
-
- b[0] = (byte) 0x91; b[1] = (byte) 0x2A; b[2] = (byte) 0xB1; b[3] = (byte) 0x71;
- b[4] = (byte) 0x00; b[5] = (byte) 0x55; b[6] = (byte) 0x05; b[7] = (byte) 0x20;
- b[8] = (byte) 0xF0;
- assertEquals("*21#+17005550020",
- PhoneNumberUtils.calledPartyBCDToString(b, 0, 9));
-
- assertNull(PhoneNumberUtils.extractNetworkPortion(null));
- assertNull(PhoneNumberUtils.extractPostDialPortion(null));
- assertTrue(PhoneNumberUtils.compare(null, null));
- assertFalse(PhoneNumberUtils.compare(null, "123"));
- assertFalse(PhoneNumberUtils.compare("123", null));
- assertNull(PhoneNumberUtils.toCallerIDMinMatch(null));
- assertNull(PhoneNumberUtils.getStrippedReversed(null));
- assertNull(PhoneNumberUtils.stringFromStringAndTOA(null, 1));
- }
-
- @SmallTest
- public void testExtractNetworkPortionAlt() throws Exception {
- assertEquals(
- "+17005554141",
- PhoneNumberUtils.extractNetworkPortionAlt("+17005554141")
- );
-
- assertEquals(
- "+17005554141",
- PhoneNumberUtils.extractNetworkPortionAlt("+1 (700).555-4141")
- );
-
- assertEquals(
- "17005554141",
- PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-4141")
- );
-
- // This may seem wrong, but it's probably ok
- assertEquals(
- "17005554141*#",
- PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-4141*#")
- );
-
- assertEquals(
- "170055541NN",
- PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN")
- );
-
- assertEquals(
- "170055541NN",
- PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN,1234")
- );
-
- assertEquals(
- "170055541NN",
- PhoneNumberUtils.extractNetworkPortionAlt("1 (700).555-41NN;1234")
- );
-
- // An MMI string is unperterbed, even though it contains a
- // (valid in this case) embedded +
- assertEquals(
- "**21**+17005554141#",
- PhoneNumberUtils.extractNetworkPortionAlt("**21**+17005554141#")
- );
-
- assertEquals(
- "*31#+447966164208",
- PhoneNumberUtils.extractNetworkPortionAlt("*31#+447966164208")
- );
-
- assertEquals(
- "*31#+447966164208",
- PhoneNumberUtils.extractNetworkPortionAlt("*31# (+44) 79 6616 4208")
- );
-
- assertEquals("", PhoneNumberUtils.extractNetworkPortionAlt(""));
-
- assertEquals("", PhoneNumberUtils.extractNetworkPortionAlt(",1234"));
-
- assertNull(PhoneNumberUtils.extractNetworkPortionAlt(null));
- }
-
- @SmallTest
- public void testB() throws Exception {
- assertEquals("", PhoneNumberUtils.extractPostDialPortion("+17005554141"));
- assertEquals("", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-4141"));
- assertEquals("", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN"));
- assertEquals(",1234", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN,1234"));
- assertEquals(";1234", PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN;1234"));
- assertEquals(";1234,;N",
- PhoneNumberUtils.extractPostDialPortion("+1 (700).555-41NN;1-2.34 ,;N"));
- }
-
- @SmallTest
- public void testCompare() throws Exception {
- // this is odd
- assertFalse(PhoneNumberUtils.compare("", ""));
-
- assertTrue(PhoneNumberUtils.compare("911", "911"));
- assertFalse(PhoneNumberUtils.compare("911", "18005550911"));
- assertTrue(PhoneNumberUtils.compare("5555", "5555"));
- assertFalse(PhoneNumberUtils.compare("5555", "180055555555"));
-
- assertTrue(PhoneNumberUtils.compare("+17005554141", "+17005554141"));
- assertTrue(PhoneNumberUtils.compare("+17005554141", "+1 (700).555-4141"));
- assertTrue(PhoneNumberUtils.compare("+17005554141", "+1 (700).555-4141,1234"));
- assertTrue(PhoneNumberUtils.compare("+17005554141", "17005554141"));
- assertTrue(PhoneNumberUtils.compare("+17005554141", "7005554141"));
- assertTrue(PhoneNumberUtils.compare("+17005554141", "5554141"));
- assertTrue(PhoneNumberUtils.compare("17005554141", "5554141"));
- assertTrue(PhoneNumberUtils.compare("+17005554141", "01117005554141"));
- assertTrue(PhoneNumberUtils.compare("+17005554141", "0017005554141"));
- assertTrue(PhoneNumberUtils.compare("17005554141", "0017005554141"));
-
-
- assertTrue(PhoneNumberUtils.compare("+17005554141", "**31#+17005554141"));
-
- assertFalse(PhoneNumberUtils.compare("+1 999 7005554141", "+1 7005554141"));
- assertTrue(PhoneNumberUtils.compare("011 1 7005554141", "7005554141"));
-
- assertFalse(PhoneNumberUtils.compare("011 11 7005554141", "+17005554141"));
-
- assertFalse(PhoneNumberUtils.compare("+17005554141", "7085882300"));
-
- assertTrue(PhoneNumberUtils.compare("+44 207 792 3490", "0 207 792 3490"));
-
- assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "00 207 792 3490"));
- assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "011 207 792 3490"));
-
- /***** FIXME's ******/
- //
- // MMI header should be ignored
- assertFalse(PhoneNumberUtils.compare("+17005554141", "**31#17005554141"));
-
- // It's too bad this is false
- // +44 (0) 207 792 3490 is not a dialable number
- // but it is commonly how European phone numbers are written
- assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "+44 (0) 207 792 3490"));
-
- // The japanese international prefix, for example, messes us up
- // But who uses a GSM phone in Japan?
- assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "010 44 207 792 3490"));
-
- // The Australian one messes us up too
- assertFalse(PhoneNumberUtils.compare("+44 207 792 3490", "0011 44 207 792 3490"));
-
- // The Russian trunk prefix messes us up, as does current
- // Russian area codes (which bein with 0)
-
- assertFalse(PhoneNumberUtils.compare("+7(095)9100766", "8(095)9100766"));
-
- // 444 is not a valid country code, but
- // matchIntlPrefixAndCC doesnt know this
- assertTrue(PhoneNumberUtils.compare("+444 207 792 3490", "0 207 792 3490"));
-
- // compare SMS short code
- assertTrue(PhoneNumberUtils.compare("404-04", "40404"));
- }
-
-
- @SmallTest
- public void testToCallerIDIndexable() throws Exception {
- assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
- assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
- assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
- assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
-
- //this seems wrong, or at least useless
- assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
-
- //<shrug> -- these are all not useful, but not terribly wrong
- assertEquals("", PhoneNumberUtils.toCallerIDMinMatch(""));
- assertEquals("0032", PhoneNumberUtils.toCallerIDMinMatch("2300"));
- assertEquals("0032+", PhoneNumberUtils.toCallerIDMinMatch("+2300"));
- assertEquals("#130#*", PhoneNumberUtils.toCallerIDMinMatch("*#031#"));
- }
-
- @SmallTest
- public void testGetIndexable() throws Exception {
- assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141"));
- assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141,1234"));
- assertEquals("14145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-4141;1234"));
-
- //this seems wrong, or at least useless
- assertEquals("NN145550071", PhoneNumberUtils.getStrippedReversed("1-700-555-41NN"));
-
- //<shrug> -- these are all not useful, but not terribly wrong
- assertEquals("", PhoneNumberUtils.getStrippedReversed(""));
- assertEquals("0032", PhoneNumberUtils.getStrippedReversed("2300"));
- assertEquals("0032+", PhoneNumberUtils.getStrippedReversed("+2300"));
- assertEquals("#130#*", PhoneNumberUtils.getStrippedReversed("*#031#"));
- }
-
- @SmallTest
- public void testNanpFormatting() {
- SpannableStringBuilder number = new SpannableStringBuilder();
- number.append("8005551212");
- PhoneNumberUtils.formatNanpNumber(number);
- assertEquals("800-555-1212", number.toString());
-
- number.clear();
- number.append("800555121");
- PhoneNumberUtils.formatNanpNumber(number);
- assertEquals("800-555-121", number.toString());
-
- number.clear();
- number.append("555-1212");
- PhoneNumberUtils.formatNanpNumber(number);
- assertEquals("555-1212", number.toString());
-
- number.clear();
- number.append("800-55512");
- PhoneNumberUtils.formatNanpNumber(number);
- assertEquals("800-555-12", number.toString());
-
- number.clear();
- number.append("46645");
- PhoneNumberUtils.formatNanpNumber(number);
- assertEquals("46645", number.toString());
- }
-
- @SmallTest
- public void testConvertKeypadLettersToDigits() {
- assertEquals("1-800-4664-411",
- PhoneNumberUtils.convertKeypadLettersToDigits("1-800-GOOG-411"));
- assertEquals("18004664411",
- PhoneNumberUtils.convertKeypadLettersToDigits("1800GOOG411"));
- assertEquals("1-800-466-4411",
- PhoneNumberUtils.convertKeypadLettersToDigits("1-800-466-4411"));
- assertEquals("18004664411",
- PhoneNumberUtils.convertKeypadLettersToDigits("18004664411"));
- assertEquals("222-333-444-555-666-7777-888-9999",
- PhoneNumberUtils.convertKeypadLettersToDigits(
- "ABC-DEF-GHI-JKL-MNO-PQRS-TUV-WXYZ"));
- assertEquals("222-333-444-555-666-7777-888-9999",
- PhoneNumberUtils.convertKeypadLettersToDigits(
- "abc-def-ghi-jkl-mno-pqrs-tuv-wxyz"));
- assertEquals("(800) 222-3334",
- PhoneNumberUtils.convertKeypadLettersToDigits("(800) ABC-DEFG"));
- }
-
- // To run this test, the device has to be registered with network
- public void testCheckAndProcessPlusCode() {
- assertEquals("0118475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000"));
- assertEquals("18475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+18475797000"));
- assertEquals("0111234567",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+1234567"));
- assertEquals("01123456700000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+23456700000"));
- assertEquals("01111875767800",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+11875767800"));
- assertEquals("8475797000,18475231753",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+18475231753"));
- assertEquals("0118475797000,18475231753",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000,+18475231753"));
- assertEquals("8475797000;0118469312345",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;+8469312345"));
- assertEquals("8475797000,0111234567",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+1234567"));
- assertEquals("847597000;01111875767000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847597000;+11875767000"));
- assertEquals("8475797000,,0118469312345",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,+8469312345"));
- assertEquals("8475797000;,0118469312345",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+8469312345"));
- assertEquals("8475797000,;18475231753",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+18475231753"));
- assertEquals("8475797000;,01111875767000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+11875767000"));
- assertEquals("8475797000,;01111875767000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+11875767000"));
- assertEquals("8475797000,,,01111875767000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,,+11875767000"));
- assertEquals("8475797000;,,01111875767000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,,+11875767000"));
- assertEquals("+;,8475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+;,8475797000"));
- assertEquals("8475797000,",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,"));
- assertEquals("847+579-7000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847+579-7000"));
- assertEquals(",8475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode(",8475797000"));
- assertEquals(";;8475797000,,",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode(";;8475797000,,"));
- assertEquals("+this+is$weird;,+",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+this+is$weird;,+"));
- assertEquals("",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCode(""));
- assertNull(PhoneNumberUtils.cdmaCheckAndProcessPlusCode(null));
- }
-
- @SmallTest
- public void testCheckAndProcessPlusCodeByNumberFormat() {
- assertEquals("18475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
- PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_NANP));
- assertEquals("+18475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
- PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_JAPAN));
- assertEquals("+18475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
- PhoneNumberUtils.FORMAT_NANP,PhoneNumberUtils.FORMAT_UNKNOWN));
- assertEquals("+18475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
- PhoneNumberUtils.FORMAT_JAPAN,PhoneNumberUtils.FORMAT_JAPAN));
- assertEquals("+18475797000",
- PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+18475797000",
- PhoneNumberUtils.FORMAT_UNKNOWN,PhoneNumberUtils.FORMAT_UNKNOWN));
- }
-
- /**
- * Basic checks for the VoiceMail number.
- */
- @SmallTest
- public void testWithNumberNotEqualToVoiceMail() throws Exception {
- assertFalse(PhoneNumberUtils.isVoiceMailNumber("911"));
- assertFalse(PhoneNumberUtils.isVoiceMailNumber("tel:911"));
- assertFalse(PhoneNumberUtils.isVoiceMailNumber("+18001234567"));
- assertFalse(PhoneNumberUtils.isVoiceMailNumber(""));
- assertFalse(PhoneNumberUtils.isVoiceMailNumber(null));
- // This test fails on a device without a sim card
- /*TelephonyManager mTelephonyManager =
- (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
- String mVoiceMailNumber = mTelephonyManager.getDefault().getVoiceMailNumber();
- assertTrue(PhoneNumberUtils.isVoiceMailNumber(mVoiceMailNumber));
- */
- }
-
- @SmallTest
- public void testFormatNumberToE164() {
- // Note: ISO 3166-1 only allows upper case country codes.
- assertEquals("+16502910000", PhoneNumberUtils.formatNumberToE164("650 2910000", "US"));
- assertNull(PhoneNumberUtils.formatNumberToE164("1234567", "US"));
- assertEquals("+18004664114", PhoneNumberUtils.formatNumberToE164("800-GOOG-114", "US"));
- }
-
- @SmallTest
- public void testFormatNumber() {
- assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("650 2910000", "US"));
- assertEquals("223-4567", PhoneNumberUtils.formatNumber("2234567", "US"));
- assertEquals("011 86 10 8888 0000",
- PhoneNumberUtils.formatNumber("011861088880000", "US"));
- assertEquals("010 8888 0000", PhoneNumberUtils.formatNumber("01088880000", "CN"));
- // formatNumber doesn't format alpha numbers, but keep them as they are.
- assertEquals("800-GOOG-114", PhoneNumberUtils.formatNumber("800-GOOG-114", "US"));
- }
-
- @SmallTest
- public void testFormatNumber_LeadingStarAndHash() {
- // Numbers with a leading '*' or '#' should be left unchanged.
- assertEquals("*650 2910000", PhoneNumberUtils.formatNumber("*650 2910000", "US"));
- assertEquals("#650 2910000", PhoneNumberUtils.formatNumber("#650 2910000", "US"));
- assertEquals("*#650 2910000", PhoneNumberUtils.formatNumber("*#650 2910000", "US"));
- assertEquals("#*650 2910000", PhoneNumberUtils.formatNumber("#*650 2910000", "US"));
- assertEquals("#650*2910000", PhoneNumberUtils.formatNumber("#650*2910000", "US"));
- assertEquals("#650*2910000", PhoneNumberUtils.formatNumber("#650*2910000", "US"));
- assertEquals("##650 2910000", PhoneNumberUtils.formatNumber("##650 2910000", "US"));
- assertEquals("**650 2910000", PhoneNumberUtils.formatNumber("**650 2910000", "US"));
- }
-
- @SmallTest
- public void testNormalizeNumber() {
- assertEquals("6502910000", PhoneNumberUtils.normalizeNumber("650 2910000"));
- assertEquals("1234567", PhoneNumberUtils.normalizeNumber("12,3#4*567"));
- assertEquals("8004664114", PhoneNumberUtils.normalizeNumber("800-GOOG-114"));
- assertEquals("+16502910000", PhoneNumberUtils.normalizeNumber("+1 650 2910000"));
- }
-
- @SmallTest
- public void testFormatDailabeNumber() {
- // Using the phoneNumberE164's country code
- assertEquals("(650) 291-0000",
- PhoneNumberUtils.formatNumber("6502910000", "+16502910000", "CN"));
- // Using the default country code for a phone number containing the IDD
- assertEquals("011 86 10 8888 0000",
- PhoneNumberUtils.formatNumber("011861088880000", "+861088880000", "US"));
- assertEquals("00 86 10 8888 0000",
- PhoneNumberUtils.formatNumber("00861088880000", "+861088880000", "GB"));
- assertEquals("+86 10 8888 0000",
- PhoneNumberUtils.formatNumber("+861088880000", "+861088880000", "GB"));
- // Wrong default country, so no formatting is done
- assertEquals("011861088880000",
- PhoneNumberUtils.formatNumber("011861088880000", "+861088880000", "GB"));
- // The phoneNumberE164 is null
- assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("6502910000", null, "US"));
- // The given number has a country code.
- assertEquals("+1 650-291-0000", PhoneNumberUtils.formatNumber("+16502910000", null, "CN"));
- // The given number was formatted.
- assertEquals("650-291-0000", PhoneNumberUtils.formatNumber("650-291-0000", null, "US"));
- // A valid Polish number should be formatted.
- assertEquals("506 128 687", PhoneNumberUtils.formatNumber("506128687", null, "PL"));
- // An invalid Polish number should be left as it is. Note Poland doesn't use '0' as a
- // national prefix; therefore, the leading '0' makes the number invalid.
- assertEquals("0506128687", PhoneNumberUtils.formatNumber("0506128687", null, "PL"));
- // Wrong default country, so no formatting is done
- assertEquals("011861088880000",
- PhoneNumberUtils.formatNumber("011861088880000", "", "GB"));
- }
-
- @SmallTest
- public void testIsEmergencyNumber() {
- // There are two parallel sets of tests here: one for the
- // regular isEmergencyNumber() method, and the other for
- // isPotentialEmergencyNumber().
- //
- // (The difference is that isEmergencyNumber() will return true
- // only if the specified number exactly matches an actual
- // emergency number, but isPotentialEmergencyNumber() will
- // return true if the specified number simply starts with the
- // same digits as any actual emergency number.)
-
- // Tests for isEmergencyNumber():
- assertTrue(PhoneNumberUtils.isEmergencyNumber("911", "US"));
- assertTrue(PhoneNumberUtils.isEmergencyNumber("112", "US"));
- // The next two numbers are not valid phone numbers in the US,
- // so do not count as emergency numbers (but they *are* "potential"
- // emergency numbers; see below.)
- assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "US"));
- assertFalse(PhoneNumberUtils.isEmergencyNumber("11212345", "US"));
- // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
- // in Singapore, as 911 is not an emergency number there.
- assertFalse(PhoneNumberUtils.isEmergencyNumber("91121234", "SG"));
- // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
- // in Brazil, as 112 is not an emergency number there.
- assertFalse(PhoneNumberUtils.isEmergencyNumber("1121234567", "BR"));
- // A valid local phone number from Brazil shouldn't be classified as an emergency number in
- // Brazil.
- assertFalse(PhoneNumberUtils.isEmergencyNumber("91112345", "BR"));
-
- // Tests for isPotentialEmergencyNumber():
- // These first two are obviously emergency numbers:
- assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("911", "US"));
- assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("112", "US"));
- // The next two numbers are not valid phone numbers in the US, but can be used to trick the
- // system to dial 911 and 112, which are emergency numbers in the US. For the purpose of
- // addressing that, they are also classified as "potential" emergency numbers in the US.
- assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "US"));
- assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("11212345", "US"));
-
- // A valid mobile phone number from Singapore shouldn't be classified as an emergency number
- // in Singapore, as 911 is not an emergency number there.
- // This test fails on devices that have ecclist property preloaded with 911.
- // assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG"));
-
- // A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
- // in Brazil, as 112 is not an emergency number there.
- assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("1121234567", "BR"));
- // A valid local phone number from Brazil shouldn't be classified as an emergency number in
- // Brazil.
- assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "BR"));
- }
-
- @SmallTest
- public void testStripSeparators() {
- // Smoke tests which should never fail.
- assertEquals("1234567890", PhoneNumberUtils.stripSeparators("1234567890"));
- assertEquals("911", PhoneNumberUtils.stripSeparators("911"));
- assertEquals("112", PhoneNumberUtils.stripSeparators("112"));
-
- // Separators should be removed, while '+' or any other digits should not.
- assertEquals("+16502910000", PhoneNumberUtils.stripSeparators("+1 (650) 291-0000"));
-
- // WAIT, PAUSE should *not* be stripped
- assertEquals("+16502910000,300;",
- PhoneNumberUtils.stripSeparators("+1 (650) 291-0000, 300;"));
- }
-
- @SmallTest
- public void testConvertAndStrip() {
- // Smoke tests which should never fail.
- assertEquals("1234567890", PhoneNumberUtils.convertAndStrip("1234567890"));
- assertEquals("911", PhoneNumberUtils.convertAndStrip("911"));
- assertEquals("112", PhoneNumberUtils.convertAndStrip("112"));
-
- // It should convert keypad characters into digits, and strip separators
- assertEquals("22233344455566677778889999",
- PhoneNumberUtils.convertAndStrip("ABC DEF GHI JKL MNO PQR STUV WXYZ"));
-
- // Test real cases.
- assertEquals("18004664411", PhoneNumberUtils.convertAndStrip("1-800-GOOG-411"));
- assertEquals("8002223334", PhoneNumberUtils.convertAndStrip("(800) ABC-DEFG"));
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
deleted file mode 100644
index a6a0fce..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.telephony;
-
-import android.telephony.PhoneNumberFormattingTextWatcher;
-import android.test.AndroidTestCase;
-import android.text.Editable;
-import android.text.Selection;
-import android.text.SpannableStringBuilder;
-import android.text.TextWatcher;
-
-public class PhoneNumberWatcherTest extends AndroidTestCase {
- public void testAppendChars() {
- final String multiChars = "65012345";
- final String formatted1 = "(650) 123-45";
- TextWatcher textWatcher = getTextWatcher();
- SpannableStringBuilder number = new SpannableStringBuilder();
- // Append more than one chars
- textWatcher.beforeTextChanged(number, 0, 0, multiChars.length());
- number.append(multiChars);
- Selection.setSelection(number, number.length());
- textWatcher.onTextChanged(number, 0, 0, number.length());
- textWatcher.afterTextChanged(number);
- assertEquals(formatted1, number.toString());
- assertEquals(formatted1.length(), Selection.getSelectionEnd(number));
- // Append one chars
- final char appendChar = '6';
- final String formatted2 = "(650) 123-456";
- int len = number.length();
- textWatcher.beforeTextChanged(number, number.length(), 0, 1);
- number.append(appendChar);
- Selection.setSelection(number, number.length());
- textWatcher.onTextChanged(number, len, 0, 1);
- textWatcher.afterTextChanged(number);
- assertEquals(formatted2, number.toString());
- assertEquals(formatted2.length(), Selection.getSelectionEnd(number));
- }
-
- public void testRemoveLastChars() {
- final String init = "65012345678";
- final String result1 = "(650) 123-4567";
- TextWatcher textWatcher = getTextWatcher();
- // Remove the last char.
- SpannableStringBuilder number = new SpannableStringBuilder(init);
- int len = number.length();
- textWatcher.beforeTextChanged(number, len - 1, 1, 0);
- number.delete(len - 1, len);
- Selection.setSelection(number, number.length());
- textWatcher.onTextChanged(number, number.length() - 1, 1, 0);
- textWatcher.afterTextChanged(number);
- assertEquals(result1, number.toString());
- assertEquals(result1.length(), Selection.getSelectionEnd(number));
- // Remove last 5 chars
- final String result2 = "650-123";
- textWatcher.beforeTextChanged(number, number.length() - 4, 4, 0);
- number.delete(number.length() - 5, number.length());
- Selection.setSelection(number, number.length());
- textWatcher.onTextChanged(number, number.length(), 4, 0);
- textWatcher.afterTextChanged(number);
- assertEquals(result2, number.toString());
- assertEquals(result2.length(), Selection.getSelectionEnd(number));
- }
-
- public void testInsertChars() {
- final String init = "650-23";
- final String expected1 = "650-123";
- TextWatcher textWatcher = getTextWatcher();
-
- // Insert one char
- SpannableStringBuilder number = new SpannableStringBuilder(init);
- textWatcher.beforeTextChanged(number, 3, 0, 1);
- number.insert(3, "1"); // 6501-23
- Selection.setSelection(number, 4); // make the cursor at right of 1
- textWatcher.onTextChanged(number, 3, 0, 1);
- textWatcher.afterTextChanged(number);
- assertEquals(expected1, number.toString());
- // the cursor should still at the right of '1'
- assertEquals(5, Selection.getSelectionEnd(number));
-
- // Insert multiple chars
- final String expected2 = "(650) 145-6723";
- textWatcher.beforeTextChanged(number, 5, 0, 4);
- number.insert(5, "4567"); // change to 650-1456723
- Selection.setSelection(number, 9); // the cursor is at the right of '7'.
- textWatcher.onTextChanged(number, 7, 0, 4);
- textWatcher.afterTextChanged(number);
- assertEquals(expected2, number.toString());
- // the cursor should be still at the right of '7'
- assertEquals(12, Selection.getSelectionEnd(number));
- }
-
- public void testStopFormatting() {
- final String init = "(650) 123";
- final String expected1 = "(650) 123 4";
- TextWatcher textWatcher = getTextWatcher();
-
- // Append space
- SpannableStringBuilder number = new SpannableStringBuilder(init);
- textWatcher.beforeTextChanged(number, 9, 0, 2);
- number.insert(9, " 4"); // (6501) 23 4
- Selection.setSelection(number, number.length()); // make the cursor at right of 4
- textWatcher.onTextChanged(number, 9, 0, 2);
- textWatcher.afterTextChanged(number);
- assertEquals(expected1, number.toString());
- // the cursor should still at the right of '1'
- assertEquals(expected1.length(), Selection.getSelectionEnd(number));
-
- // Delete a ')'
- final String expected2 ="(650 123";
- textWatcher = getTextWatcher();
- number = new SpannableStringBuilder(init);
- textWatcher.beforeTextChanged(number, 4, 1, 0);
- number.delete(4, 5); // (6501 23 4
- Selection.setSelection(number, 5); // make the cursor at right of 1
- textWatcher.onTextChanged(number, 4, 1, 0);
- textWatcher.afterTextChanged(number);
- assertEquals(expected2, number.toString());
- // the cursor should still at the right of '1'
- assertEquals(5, Selection.getSelectionEnd(number));
-
- // Insert a hyphen
- final String expected3 ="(650) 12-3";
- textWatcher = getTextWatcher();
- number = new SpannableStringBuilder(init);
- textWatcher.beforeTextChanged(number, 8, 0, 1);
- number.insert(8, "-"); // (650) 12-3
- Selection.setSelection(number, 9); // make the cursor at right of -
- textWatcher.onTextChanged(number, 8, 0, 1);
- textWatcher.afterTextChanged(number);
- assertEquals(expected3, number.toString());
- // the cursor should still at the right of '-'
- assertEquals(9, Selection.getSelectionEnd(number));
- }
-
- public void testRestartFormatting() {
- final String init = "(650) 123";
- final String expected1 = "(650) 123 4";
- TextWatcher textWatcher = getTextWatcher();
-
- // Append space
- SpannableStringBuilder number = new SpannableStringBuilder(init);
- textWatcher.beforeTextChanged(number, 9, 0, 2);
- number.insert(9, " 4"); // (650) 123 4
- Selection.setSelection(number, number.length()); // make the cursor at right of 4
- textWatcher.onTextChanged(number, 9, 0, 2);
- textWatcher.afterTextChanged(number);
- assertEquals(expected1, number.toString());
- // the cursor should still at the right of '4'
- assertEquals(expected1.length(), Selection.getSelectionEnd(number));
-
- // Clear the current string, and start formatting again.
- int len = number.length();
- textWatcher.beforeTextChanged(number, 0, len, 0);
- number.delete(0, len);
- textWatcher.onTextChanged(number, 0, len, 0);
- textWatcher.afterTextChanged(number);
-
- final String expected2 = "650-1234";
- number = new SpannableStringBuilder(init);
- textWatcher.beforeTextChanged(number, 9, 0, 1);
- number.insert(9, "4"); // (650) 1234
- Selection.setSelection(number, number.length()); // make the cursor at right of 4
- textWatcher.onTextChanged(number, 9, 0, 1);
- textWatcher.afterTextChanged(number);
- assertEquals(expected2, number.toString());
- // the cursor should still at the right of '4'
- assertEquals(expected2.length(), Selection.getSelectionEnd(number));
- }
-
- public void testTextChangedByOtherTextWatcher() {
- final TextWatcher cleanupTextWatcher = new TextWatcher() {
- @Override
- public void afterTextChanged(Editable s) {
- s.clear();
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before,
- int count) {
- }
- };
- final String init = "(650) 123";
- final String expected1 = "";
- TextWatcher textWatcher = getTextWatcher();
-
- SpannableStringBuilder number = new SpannableStringBuilder(init);
- textWatcher.beforeTextChanged(number, 5, 0, 1);
- number.insert(5, "4"); // (6504) 123
- Selection.setSelection(number, 5); // make the cursor at right of 4
- textWatcher.onTextChanged(number, 5, 0, 1);
- number.setSpan(cleanupTextWatcher, 0, number.length(), 0);
- textWatcher.afterTextChanged(number);
- assertEquals(expected1, number.toString());
- }
-
- /**
- * Test the case where some other component is auto-completing what the user is typing
- */
- public void testAutoCompleteWithFormattedNumber() {
- String init = "650-1";
- String expected = "+1-650-123-4567"; // Different formatting than ours
- testReplacement(init, expected, expected);
- }
-
- /**
- * Test the case where some other component is auto-completing what the user is typing
- */
- public void testAutoCompleteWithFormattedNameAndNumber() {
- String init = "650-1";
- String expected = "Test User <650-123-4567>";
- testReplacement(init, expected, expected);
- }
-
- /**
- * Test the case where some other component is auto-completing what the user is typing
- */
- public void testAutoCompleteWithNumericNameAndNumber() {
- String init = "650";
- String expected = "2nd Test User <650-123-4567>";
- testReplacement(init, expected, expected);
- }
-
- /**
- * Test the case where some other component is auto-completing what the user is typing
- */
- public void testAutoCompleteWithUnformattedNumber() {
- String init = "650-1";
- String expected = "6501234567";
- testReplacement(init, expected, expected);
- }
-
- /**
- * Test the case where some other component is auto-completing what the user is typing, where
- * the deleted text doesn't have any formatting and neither does the replacement text: in this
- * case the replacement text should be formatted by the PhoneNumberFormattingTextWatcher.
- */
- public void testAutoCompleteUnformattedWithUnformattedNumber() {
- String init = "650";
- String replacement = "6501234567";
- String expected = "(650) 123-4567";
- testReplacement(init, replacement, expected);
-
- String init2 = "650";
- String replacement2 = "16501234567";
- String expected2 = "1 650-123-4567";
- testReplacement(init2, replacement2, expected2);
- }
-
- /**
- * Helper method for testing replacing the entire string with another string
- * @param init The initial string
- * @param expected
- */
- private void testReplacement(String init, String replacement, String expected) {
- TextWatcher textWatcher = getTextWatcher();
-
- SpannableStringBuilder number = new SpannableStringBuilder(init);
-
- // Replace entire text with the given values
- textWatcher.beforeTextChanged(number, 0, init.length(), replacement.length());
- number.replace(0, init.length(), replacement, 0, replacement.length());
- Selection.setSelection(number, replacement.length()); // move the cursor to the end
- textWatcher.onTextChanged(number, 0, init.length(), replacement.length());
- textWatcher.afterTextChanged(number);
-
- assertEquals(expected, number.toString());
- // the cursor should be still at the end
- assertEquals(expected.length(), Selection.getSelectionEnd(number));
- }
-
- private TextWatcher getTextWatcher() {
- return new PhoneNumberFormattingTextWatcher("US");
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java
deleted file mode 100644
index 8a66614..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.test.suitebuilder.annotation.MediumTest;
-import com.android.internal.telephony.TestPhoneNotifier;
-import com.android.internal.telephony.gsm.SmsMessage;
-import com.android.internal.telephony.test.SimulatedCommands;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.Iterator;
-
-/**
- * {@hide}
- */
-public class SMSDispatcherTest extends AndroidTestCase {
- @MediumTest
- public void testCMT1() throws Exception {
- SmsMessage sms;
- SmsHeader header;
-
- String[] lines = new String[2];
-
- lines[0] = "+CMT: ,158";
- lines[1] = "07914140279510F6440A8111110301003BF56080426101748A8C0B05040B"
- + "8423F000035502010106276170706C69636174696F6E2F766E642E776170"
- + "2E6D6D732D6D65737361676500AF848D0185B4848C8298524F347839776F"
- + "7547514D4141424C3641414141536741415A4B554141414141008D908918"
- + "802B31363530323438363137392F545950453D504C4D4E008A808E028000"
- + "88058103093A8083687474703A2F2F36";
-
- sms = SmsMessage.newFromCMT(lines);
- header = sms.getUserDataHeader();
- assertNotNull(header);
- assertNotNull(sms.getUserData());
- assertNotNull(header.concatRef);
- assertEquals(header.concatRef.refNumber, 85);
- assertEquals(header.concatRef.msgCount, 2);
- assertEquals(header.concatRef.seqNumber, 1);
- assertEquals(header.concatRef.isEightBits, true);
- assertNotNull(header.portAddrs);
- assertEquals(header.portAddrs.destPort, 2948);
- assertEquals(header.portAddrs.origPort, 9200);
- assertEquals(header.portAddrs.areEightBits, false);
- }
-
- @MediumTest
- public void testCMT2() throws Exception {
- SmsMessage sms;
- SmsHeader header;
-
- String[] lines = new String[2];
-
- lines[0] = "+CMT: ,77";
- lines[1] = "07914140279510F6440A8111110301003BF56080426101848A3B0B05040B8423F"
- + "00003550202362E3130322E3137312E3135302F524F347839776F7547514D4141"
- + "424C3641414141536741415A4B55414141414100";
-
- sms = SmsMessage.newFromCMT(lines);
- header = sms.getUserDataHeader();
- assertNotNull(header);
- assertNotNull(sms.getUserData());
- assertNotNull(header.concatRef);
- assertEquals(header.concatRef.refNumber, 85);
- assertEquals(header.concatRef.msgCount, 2);
- assertEquals(header.concatRef.seqNumber, 2);
- assertEquals(header.concatRef.isEightBits, true);
- assertNotNull(header.portAddrs);
- assertEquals(header.portAddrs.destPort, 2948);
- assertEquals(header.portAddrs.origPort, 9200);
- assertEquals(header.portAddrs.areEightBits, false);
- }
-
- @MediumTest
- public void testEfRecord() throws Exception {
- SmsMessage sms;
-
- String s = "03029111000c9194981492631000f269206190022000a053e4534a05358bd3"
- + "69f05804259da0219418a40641536a110a0aea408080604028180e888462c1"
- + "50341c0f484432a1542c174c46b3e1743c9f9068442a994ea8946ac56ab95e"
- + "b0986c46abd96eb89c6ec7ebf97ec0a070482c1a8fc8a472c96c3a9fd0a874"
- + "4aad5aafd8ac76cbed7abfe0b0784c2e9bcfe8b47acd6ebbdff0b87c4eafdb"
- + "eff8bc7ecfeffbffffffffffffffffffffffffffff";
- byte[] data = IccUtils.hexStringToBytes(s);
-
- sms = SmsMessage.createFromEfRecord(1, data);
- assertNotNull(sms.getMessageBody());
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java
deleted file mode 100644
index 609e768..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimPhoneBookTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.ServiceManager;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.List;
-
-import junit.framework.TestCase;
-
-@Suppress
-public class SimPhoneBookTest extends TestCase {
-
- public void testBasic() throws Exception {
- IIccPhoneBook simPhoneBook =
- IIccPhoneBook.Stub.asInterface(ServiceManager.getService("simphonebook"));
- assertNotNull(simPhoneBook);
-
- int size[] = simPhoneBook.getAdnRecordsSize(IccConstants.EF_ADN);
- assertNotNull(size);
- assertEquals(3, size.length);
- assertEquals(size[0] * size[2], size[1]);
- assertTrue(size[2] >= 100);
-
- List<AdnRecord> adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
- // do it twice cause the second time shall read from cache only
- adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
- assertNotNull(adnRecordList);
-
- // Test for phone book update
- int adnIndex, listIndex = 0;
- AdnRecord originalAdn = null;
- // We need to maintain the state of the SIM before and after the test.
- // Since this test doesn't mock the SIM we try to get a valid ADN record,
- // for 3 tries and if this fails, we bail out.
- for (adnIndex = 3 ; adnIndex >= 1; adnIndex--) {
- listIndex = adnIndex - 1; // listIndex is zero based.
- originalAdn = adnRecordList.get(listIndex);
- assertNotNull("Original Adn is Null.", originalAdn);
- assertNotNull("Original Adn alpha tag is null.", originalAdn.getAlphaTag());
- assertNotNull("Original Adn number is null.", originalAdn.getNumber());
-
- if (originalAdn.getNumber().length() > 0 &&
- originalAdn.getAlphaTag().length() > 0) {
- break;
- }
- }
- if (adnIndex == 0) return;
-
- AdnRecord emptyAdn = new AdnRecord("", "");
- AdnRecord firstAdn = new AdnRecord("John", "4085550101");
- AdnRecord secondAdn = new AdnRecord("Andy", "6505550102");
- String pin2 = null;
-
- // udpate by index
- boolean success = simPhoneBook.updateAdnRecordsInEfByIndex(IccConstants.EF_ADN,
- firstAdn.getAlphaTag(), firstAdn.getNumber(), adnIndex, pin2);
- adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
- AdnRecord tmpAdn = adnRecordList.get(listIndex);
- assertTrue(success);
- assertTrue(firstAdn.isEqual(tmpAdn));
-
- // replace by search
- success = simPhoneBook.updateAdnRecordsInEfBySearch(IccConstants.EF_ADN,
- firstAdn.getAlphaTag(), firstAdn.getNumber(),
- secondAdn.getAlphaTag(), secondAdn.getNumber(), pin2);
- adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
- tmpAdn = adnRecordList.get(listIndex);
- assertTrue(success);
- assertFalse(firstAdn.isEqual(tmpAdn));
- assertTrue(secondAdn.isEqual(tmpAdn));
-
- // erase be search
- success = simPhoneBook.updateAdnRecordsInEfBySearch(IccConstants.EF_ADN,
- secondAdn.getAlphaTag(), secondAdn.getNumber(),
- emptyAdn.getAlphaTag(), emptyAdn.getNumber(), pin2);
- adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
- tmpAdn = adnRecordList.get(listIndex);
- assertTrue(success);
- assertTrue(tmpAdn.isEmpty());
-
- // restore the orginial adn
- success = simPhoneBook.updateAdnRecordsInEfByIndex(IccConstants.EF_ADN,
- originalAdn.getAlphaTag(), originalAdn.getNumber(), adnIndex,
- pin2);
- adnRecordList = simPhoneBook.getAdnRecordsInEf(IccConstants.EF_ADN);
- tmpAdn = adnRecordList.get(listIndex);
- assertTrue(success);
- assertTrue(originalAdn.isEqual(tmpAdn));
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
deleted file mode 100644
index 1609680..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.ServiceManager;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.List;
-
-import junit.framework.TestCase;
-
-public class SimSmsTest extends TestCase {
-
- @MediumTest
- @Suppress // TODO: suppress this test for now since it doesn't work on the emulator
- public void testBasic() throws Exception {
-
- ISms sms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- assertNotNull(sms);
-
- List<SmsRawData> records = sms.getAllMessagesFromIccEf();
- assertNotNull(records);
- assertTrue(records.size() >= 0);
-
- int firstNullIndex = -1;
- int firstValidIndex = -1;
- byte[] pdu = null;
- for (int i = 0; i < records.size(); i++) {
- SmsRawData data = records.get(i);
- if (data != null && firstValidIndex == -1) {
- firstValidIndex = i;
- pdu = data.getBytes();
- }
- if (data == null && firstNullIndex == -1) {
- firstNullIndex = i;
- }
- if (firstNullIndex != -1 && firstValidIndex != -1) {
- break;
- }
- }
- if (firstNullIndex == -1 || firstValidIndex == -1)
- return;
- assertNotNull(pdu);
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java
deleted file mode 100644
index ef62d85..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SimUtilsTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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 com.android.internal.telephony.gsm.SimTlv;
-import com.android.internal.telephony.IccUtils;
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-
-public class SimUtilsTest extends TestCase {
-
- @SmallTest
- public void testBasic() throws Exception {
- byte[] data, data2;
-
- /*
- * bcdToString()
- */
-
- // An EF[ICCID] record
- data = IccUtils.hexStringToBytes("981062400510444868f2");
- assertEquals("8901260450014484862", IccUtils.bcdToString(data, 0, data.length));
-
- // skip the first and last bytes
- assertEquals("0126045001448486", IccUtils.bcdToString(data, 1, data.length - 2));
-
- // Stops on invalid BCD value
- data = IccUtils.hexStringToBytes("98E062400510444868f2");
- assertEquals("890", IccUtils.bcdToString(data, 0, data.length));
-
- // skip the high nibble 'F' since some PLMNs have it
- data = IccUtils.hexStringToBytes("98F062400510444868f2");
- assertEquals("890260450014484862", IccUtils.bcdToString(data, 0, data.length));
-
- /*
- * gsmBcdByteToInt()
- */
-
- assertEquals(98, IccUtils.gsmBcdByteToInt((byte) 0x89));
-
- // Out of range is treated as 0
- assertEquals(8, IccUtils.gsmBcdByteToInt((byte) 0x8c));
-
- /*
- * cdmaBcdByteToInt()
- */
-
- assertEquals(89, IccUtils.cdmaBcdByteToInt((byte) 0x89));
-
- // Out of range is treated as 0
- assertEquals(80, IccUtils.cdmaBcdByteToInt((byte) 0x8c));
-
- /*
- * adnStringFieldToString()
- */
-
-
- data = IccUtils.hexStringToBytes("00566f696365204d61696c07918150367742f3ffffffffffff");
- // Again, skip prepended 0
- // (this is an EF[ADN] record)
- assertEquals("Voice Mail", IccUtils.adnStringFieldToString(data, 1, data.length - 15));
-
- data = IccUtils.hexStringToBytes("809673539A5764002F004DFFFFFFFFFF");
- // (this is from an EF[ADN] record)
- assertEquals("\u9673\u539A\u5764/M", IccUtils.adnStringFieldToString(data, 0, data.length));
-
- data = IccUtils.hexStringToBytes("810A01566fec6365204de0696cFFFFFF");
- // (this is made up to test since I don't have a real one)
- assertEquals("Vo\u00ECce M\u00E0il", IccUtils.adnStringFieldToString(data, 0, data.length));
-
- data = IccUtils.hexStringToBytes("820505302D82d32d31");
- // Example from 3GPP TS 11.11 V18.1.3.0 annex B
- assertEquals("-\u0532\u0583-1", IccUtils.adnStringFieldToString(data, 0, data.length));
- }
-
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java
deleted file mode 100644
index 170bd9b..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsMessageBodyTest.java
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Copyright (C) 2010 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.telephony.SmsMessage;
-import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import java.util.Random;
-
-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;
-
-/**
- * Test cases to verify selection of the optimal 7 bit encoding tables
- * (for all combinations of enabled national language tables) for messages
- * containing Turkish, Spanish, Portuguese, Greek, and other symbols
- * present in the GSM default and national language tables defined in
- * 3GPP TS 23.038. Also verifies correct SMS encoding for CDMA, which only
- * supports the GSM 7 bit default alphabet, ASCII 8 bit, and UCS-2.
- * Tests both encoding variations: unsupported characters mapped to space,
- * and unsupported characters force entire message to UCS-2.
- */
-public class SmsMessageBodyTest extends AndroidTestCase {
- private static final String TAG = "SmsMessageBodyTest";
-
- // ASCII chars in the GSM 7 bit default alphabet
- private static final String sAsciiChars = "@$_ !\"#%&'()*+,-./0123456789" +
- ":;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n\r";
-
- // Unicode chars in the GSM 7 bit default alphabet and both locking shift tables
- private static final String sGsmDefaultChars = "\u00a3\u00a5\u00e9\u00c7\u0394\u00c9" +
- "\u00dc\u00a7\u00fc\u00e0";
-
- // Unicode chars in the GSM 7 bit default table and Turkish locking shift tables
- private static final String sGsmDefaultAndTurkishTables = "\u00f9\u00f2\u00c5\u00e5\u00df" +
- "\u00a4\u00c4\u00d6\u00d1\u00e4\u00f6\u00f1";
-
- // Unicode chars in the GSM 7 bit default table but not the locking shift tables
- private static final String sGsmDefaultTableOnly = "\u00e8\u00ec\u00d8\u00f8\u00c6\u00e6" +
- "\u00a1\u00bf";
-
- // ASCII chars in the GSM default extension table
- private static final String sGsmExtendedAsciiChars = "{}[]\f";
-
- // chars in GSM default extension table and Portuguese locking shift table
- private static final String sGsmExtendedPortugueseLocking = "^\\|~";
-
- // Euro currency symbol
- private static final String sGsmExtendedEuroSymbol = "\u20ac";
-
- // CJK ideographs, Hiragana, Katakana, full width letters, Cyrillic, etc.
- private static final String sUnicodeChars = "\u4e00\u4e01\u4e02\u4e03" +
- "\u4e04\u4e05\u4e06\u4e07\u4e08\u4e09\u4e0a\u4e0b\u4e0c\u4e0d" +
- "\u4e0e\u4e0f\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048" +
- "\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8" +
- "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18" +
- "\uff70\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78" +
- "\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408" +
- "\u00a2\u00a9\u00ae\u2122";
-
- // chars in Turkish single shift and locking shift tables
- private static final String sTurkishChars = "\u0131\u011e\u011f\u015e\u015f\u0130";
-
- // chars in Spanish single shift table and Portuguese single and locking shift tables
- private static final String sPortugueseAndSpanishChars = "\u00c1\u00e1\u00cd\u00ed"
- + "\u00d3\u00f3\u00da\u00fa";
-
- // chars in all national language tables but not in the standard GSM alphabets
- private static final String sNationalLanguageTablesOnly = "\u00e7";
-
- // chars in Portuguese single shift and locking shift tables
- private static final String sPortugueseChars = "\u00ea\u00d4\u00f4\u00c0\u00c2\u00e2"
- + "\u00ca\u00c3\u00d5\u00e3\u00f5";
-
- // chars in Portuguese locking shift table only
- private static final String sPortugueseLockingShiftChars = "\u00aa\u221e\u00ba`";
-
- // Greek letters in GSM alphabet missing from Portuguese locking and single shift tables
- private static final String sGreekLettersNotInPortugueseTables = "\u039b\u039e";
-
- // Greek letters in GSM alphabet and Portuguese single shift (but not locking shift) table
- private static final String sGreekLettersInPortugueseShiftTable =
- "\u03a6\u0393\u03a9\u03a0\u03a8\u03a3\u0398";
-
- // List of classes of characters in SMS tables
- private static final String[] sCharacterClasses = {
- sGsmExtendedAsciiChars,
- sGsmExtendedPortugueseLocking,
- sGsmDefaultChars,
- sGsmDefaultAndTurkishTables,
- sGsmDefaultTableOnly,
- sGsmExtendedEuroSymbol,
- sUnicodeChars,
- sTurkishChars,
- sPortugueseChars,
- sPortugueseLockingShiftChars,
- sPortugueseAndSpanishChars,
- sGreekLettersNotInPortugueseTables,
- sGreekLettersInPortugueseShiftTable,
- sNationalLanguageTablesOnly,
- sAsciiChars
- };
-
- private static final int sNumCharacterClasses = sCharacterClasses.length;
-
- // For each character class, whether it is present in a particular char table.
- // First three entries are locking shift tables, followed by four single shift tables
- private static final boolean[][] sCharClassPresenceInTables = {
- // ASCII chars in all GSM extension tables
- {false, false, false, true, true, true, true},
- // ASCII chars in all GSM extension tables and Portuguese locking shift table
- {false, false, true, true, true, true, true},
- // non-ASCII chars in GSM default alphabet and all locking tables
- {true, true, true, false, false, false, false},
- // non-ASCII chars in GSM default alphabet and Turkish locking shift table
- {true, true, false, false, false, false, false},
- // non-ASCII chars in GSM default alphabet table only
- {true, false, false, false, false, false, false},
- // Euro symbol is present in several tables
- {false, true, true, true, true, true, true},
- // Unicode characters not present in any 7 bit tables
- {false, false, false, false, false, false, false},
- // Characters specific to Turkish language
- {false, true, false, false, true, false, false},
- // Characters in Portuguese single shift and locking shift tables
- {false, false, true, false, false, false, true},
- // Characters in Portuguese locking shift table only
- {false, false, true, false, false, false, false},
- // Chars in Spanish single shift and Portuguese single and locking shift tables
- {false, false, true, false, false, true, true},
- // Greek letters in GSM default alphabet missing from Portuguese tables
- {true, true, false, false, false, false, false},
- // Greek letters in GSM alphabet and Portuguese single shift table
- {true, true, false, false, false, false, true},
- // Chars in all national language tables but not the standard GSM tables
- {false, true, true, false, true, true, true},
- // ASCII chars in GSM default alphabet
- {true, true, true, false, false, false, false}
- };
-
- private static final int sTestLengthCount = 12;
-
- private static final int[] sSeptetTestLengths =
- { 0, 1, 2, 80, 159, 160, 161, 240, 305, 306, 307, 320};
-
- private static final int[] sUnicodeTestLengths =
- { 0, 1, 2, 35, 69, 70, 71, 100, 133, 134, 135, 160};
-
- private static final int[] sTestMsgCounts =
- { 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3};
-
- private static final int[] sSeptetUnitsRemaining =
- {160, 159, 158, 80, 1, 0, 145, 66, 1, 0, 152, 139};
-
- private static final int[] sUnicodeUnitsRemaining =
- { 70, 69, 68, 35, 1, 0, 63, 34, 1, 0, 66, 41};
-
- // Combinations of enabled GSM national language single shift tables
- private static final int[][] sEnabledSingleShiftTables = {
- {}, // GSM default alphabet only
- {1}, // Turkish (single shift only)
- {1}, // Turkish (single and locking shift)
- {2}, // Spanish
- {3}, // Portuguese (single shift only)
- {3}, // Portuguese (single and locking shift)
- {1, 2}, // Turkish + Spanish (single shift only)
- {1, 2}, // Turkish + Spanish (single and locking shift)
- {1, 3}, // Turkish + Portuguese (single shift only)
- {1, 3}, // Turkish + Portuguese (single and locking shift)
- {2, 3}, // Spanish + Portuguese (single shift only)
- {2, 3}, // Spanish + Portuguese (single and locking shift)
- {1, 2, 3}, // Turkish, Spanish, Portuguese (single shift only)
- {1, 2, 3}, // Turkish, Spanish, Portuguese (single and locking shift)
- {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // all language tables
- };
-
- // Combinations of enabled GSM national language locking shift tables
- private static final int[][] sEnabledLockingShiftTables = {
- {}, // GSM default alphabet only
- {}, // Turkish (single shift only)
- {1}, // Turkish (single and locking shift)
- {}, // Spanish (no locking shift table)
- {}, // Portuguese (single shift only)
- {3}, // Portuguese (single and locking shift)
- {}, // Turkish + Spanish (single shift only)
- {1}, // Turkish + Spanish (single and locking shift)
- {}, // Turkish + Portuguese (single shift only)
- {1, 3}, // Turkish + Portuguese (single and locking shift)
- {}, // Spanish + Portuguese (single shift only)
- {3}, // Spanish + Portuguese (single and locking shift)
- {}, // Turkish, Spanish, Portuguese (single shift only)
- {1, 3}, // Turkish, Spanish, Portuguese (single and locking shift)
- {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // all language tables
- };
-
- // LanguagePair counter indexes to check for each entry above
- private static final int[][] sLanguagePairIndexesByEnabledIndex = {
- {0}, // default tables only
- {0, 1}, // Turkish (single shift only)
- {0, 1, 4, 5}, // Turkish (single and locking shift)
- {0, 2}, // Spanish
- {0, 3}, // Portuguese (single shift only)
- {0, 3, 8, 11}, // Portuguese (single and locking shift)
- {0, 1, 2}, // Turkish + Spanish (single shift only)
- {0, 1, 2, 4, 5, 6}, // Turkish + Spanish (single and locking shift)
- {0, 1, 3}, // Turkish + Portuguese (single shift only)
- {0, 1, 3, 4, 5, 7, 8, 9, 11}, // Turkish + Portuguese (single and locking shift)
- {0, 2, 3}, // Spanish + Portuguese (single shift only)
- {0, 2, 3, 8, 10, 11}, // Spanish + Portuguese (single and locking shift)
- {0, 1, 2, 3}, // all languages (single shift only)
- {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, // all languages (single and locking shift)
- {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} // all languages (no Indic chars in test)
- };
-
- /**
- * User data header requires one octet for length. Count as one septet, because
- * all combinations of header elements below will have at least one free bit
- * when padding to the nearest septet boundary.
- */
- private static final int UDH_SEPTET_COST_LENGTH = 1;
-
- /**
- * Using a non-default language locking shift table OR single shift table
- * requires a user data header of 3 octets, or 4 septets, plus UDH length.
- */
- private static final int UDH_SEPTET_COST_ONE_SHIFT_TABLE = 4;
-
- /**
- * Using a non-default language locking shift table AND single shift table
- * requires a user data header of 6 octets, or 7 septets, plus UDH length.
- */
- private static final int UDH_SEPTET_COST_TWO_SHIFT_TABLES = 7;
-
- /**
- * Multi-part messages require a user data header of 5 octets, or 6 septets,
- * plus UDH length.
- */
- private static final int UDH_SEPTET_COST_CONCATENATED_MESSAGE = 6;
-
- @SmallTest
- public void testCalcLengthAscii() throws Exception {
- StringBuilder sb = new StringBuilder(320);
- int[] values = {0, 0, 0, SmsMessage.ENCODING_7BIT, 0, 0};
- int startPos = 0;
- int asciiCharsLen = sAsciiChars.length();
-
- for (int i = 0; i < sTestLengthCount; i++) {
- int len = sSeptetTestLengths[i];
- assertTrue(sb.length() <= len);
-
- while (sb.length() < len) {
- int addCount = len - sb.length();
- int endPos = (asciiCharsLen - startPos > addCount) ?
- (startPos + addCount) : asciiCharsLen;
- sb.append(sAsciiChars, startPos, endPos);
- startPos = (endPos == asciiCharsLen) ? 0 : endPos;
- }
- assertEquals(len, sb.length());
-
- String testStr = sb.toString();
- values[0] = sTestMsgCounts[i];
- values[1] = len;
- values[2] = sSeptetUnitsRemaining[i];
-
- callGsmLengthMethods(testStr, false, values);
- callGsmLengthMethods(testStr, true, values);
- callCdmaLengthMethods(testStr, false, values);
- callCdmaLengthMethods(testStr, true, values);
- }
- }
-
- @SmallTest
- public void testCalcLengthUnicode() throws Exception {
- StringBuilder sb = new StringBuilder(160);
- int[] values = {0, 0, 0, SmsMessage.ENCODING_16BIT, 0, 0};
- int[] values7bit = {1, 0, 0, SmsMessage.ENCODING_7BIT, 0, 0};
- int startPos = 0;
- int unicodeCharsLen = sUnicodeChars.length();
-
- // start with length 1: empty string uses ENCODING_7BIT
- for (int i = 1; i < sTestLengthCount; i++) {
- int len = sUnicodeTestLengths[i];
- assertTrue(sb.length() <= len);
-
- while (sb.length() < len) {
- int addCount = len - sb.length();
- int endPos = (unicodeCharsLen - startPos > addCount) ?
- (startPos + addCount) : unicodeCharsLen;
- sb.append(sUnicodeChars, startPos, endPos);
- startPos = (endPos == unicodeCharsLen) ? 0 : endPos;
- }
- assertEquals(len, sb.length());
-
- String testStr = sb.toString();
- values[0] = sTestMsgCounts[i];
- values[1] = len;
- values[2] = sUnicodeUnitsRemaining[i];
- values7bit[1] = len;
- values7bit[2] = MAX_USER_DATA_SEPTETS - len;
-
- callGsmLengthMethods(testStr, false, values);
- callCdmaLengthMethods(testStr, false, values);
- callGsmLengthMethods(testStr, true, values7bit);
- callCdmaLengthMethods(testStr, true, values7bit);
- }
- }
-
- private static class LanguagePair {
- // index is 2 for Portuguese locking shift because there is no Spanish locking shift table
- private final int langTableIndex;
- private final int langShiftTableIndex;
- int length;
- int missingChars7bit;
-
- LanguagePair(int langTable, int langShiftTable) {
- langTableIndex = langTable;
- langShiftTableIndex = langShiftTable;
- }
-
- void clear() {
- length = 0;
- missingChars7bit = 0;
- }
-
- void addChar(boolean[] charClassTableRow) {
- if (charClassTableRow[langTableIndex]) {
- length++;
- } else if (charClassTableRow[3 + langShiftTableIndex]) {
- length += 2;
- } else {
- length++; // use ' ' for unmapped char in 7 bit only mode
- missingChars7bit++;
- }
- }
- }
-
- private static class CounterHelper {
- LanguagePair[] mCounters;
- int[] mStatsCounters;
- int mUnicodeCounter;
-
- CounterHelper() {
- mCounters = new LanguagePair[12];
- mStatsCounters = new int[12];
- for (int i = 0; i < 12; i++) {
- mCounters[i] = new LanguagePair(i/4, i%4);
- }
- }
-
- void clear() {
- // Note: don't clear stats counters
- for (int i = 0; i < 12; i++) {
- mCounters[i].clear();
- }
- }
-
- void addChar(int charClass) {
- boolean[] charClassTableRow = sCharClassPresenceInTables[charClass];
- for (int i = 0; i < 12; i++) {
- mCounters[i].addChar(charClassTableRow);
- }
- }
-
- void fillData(int enabledLangsIndex, boolean use7bitOnly, int[] values, int length) {
- int[] languagePairs = sLanguagePairIndexesByEnabledIndex[enabledLangsIndex];
- int minNumSeptets = Integer.MAX_VALUE;
- int minNumSeptetsWithHeader = Integer.MAX_VALUE;
- int minNumMissingChars = Integer.MAX_VALUE;
- int langIndex = -1;
- int langShiftIndex = -1;
- for (int i : languagePairs) {
- LanguagePair pair = mCounters[i];
- int udhLength = 0;
- if (i != 0) {
- udhLength = UDH_SEPTET_COST_LENGTH;
- if (i < 4 || i % 4 == 0) {
- udhLength += UDH_SEPTET_COST_ONE_SHIFT_TABLE;
- } else {
- udhLength += UDH_SEPTET_COST_TWO_SHIFT_TABLES;
- }
- }
- int numSeptetsWithHeader;
- if (pair.length > (MAX_USER_DATA_SEPTETS - udhLength)) {
- if (udhLength == 0) {
- udhLength = UDH_SEPTET_COST_LENGTH;
- }
- udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
- int septetsPerPart = MAX_USER_DATA_SEPTETS - udhLength;
- int msgCount = (pair.length + septetsPerPart - 1) / septetsPerPart;
- numSeptetsWithHeader = udhLength * msgCount + pair.length;
- } else {
- numSeptetsWithHeader = udhLength + pair.length;
- }
-
- if (use7bitOnly) {
- if (pair.missingChars7bit < minNumMissingChars || (pair.missingChars7bit ==
- minNumMissingChars && numSeptetsWithHeader < minNumSeptetsWithHeader)) {
- minNumSeptets = pair.length;
- minNumSeptetsWithHeader = numSeptetsWithHeader;
- minNumMissingChars = pair.missingChars7bit;
- langIndex = pair.langTableIndex;
- langShiftIndex = pair.langShiftTableIndex;
- }
- } else {
- if (pair.missingChars7bit == 0 && numSeptetsWithHeader < minNumSeptetsWithHeader) {
- minNumSeptets = pair.length;
- minNumSeptetsWithHeader = numSeptetsWithHeader;
- langIndex = pair.langTableIndex;
- langShiftIndex = pair.langShiftTableIndex;
- }
- }
- }
- if (langIndex == -1) {
- // nothing matches, use values for Unicode
- int byteCount = length * 2;
- if (byteCount > MAX_USER_DATA_BYTES) {
- values[0] = (byteCount + MAX_USER_DATA_BYTES_WITH_HEADER - 1) /
- MAX_USER_DATA_BYTES_WITH_HEADER;
- values[2] = ((values[0] * MAX_USER_DATA_BYTES_WITH_HEADER) - byteCount) / 2;
- } else {
- values[0] = 1;
- values[2] = (MAX_USER_DATA_BYTES - byteCount) / 2;
- }
- values[1] = length;
- values[3] = SmsMessage.ENCODING_16BIT;
- values[4] = 0;
- values[5] = 0;
- mUnicodeCounter++;
- } else {
- int udhLength = 0;
- if (langIndex != 0 || langShiftIndex != 0) {
- udhLength = UDH_SEPTET_COST_LENGTH;
- if (langIndex == 0 || langShiftIndex == 0) {
- udhLength += UDH_SEPTET_COST_ONE_SHIFT_TABLE;
- } else {
- udhLength += UDH_SEPTET_COST_TWO_SHIFT_TABLES;
- }
- }
- int msgCount;
- if (minNumSeptets > (MAX_USER_DATA_SEPTETS - udhLength)) {
- if (udhLength == 0) {
- udhLength = UDH_SEPTET_COST_LENGTH;
- }
- udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
- int septetsPerPart = MAX_USER_DATA_SEPTETS - udhLength;
- msgCount = (minNumSeptets + septetsPerPart - 1) / septetsPerPart;
- } else {
- msgCount = 1;
- }
- values[0] = msgCount;
- values[1] = minNumSeptets;
- values[2] = (values[0] * (MAX_USER_DATA_SEPTETS - udhLength)) - minNumSeptets;
- values[3] = SmsMessage.ENCODING_7BIT;
- values[4] = (langIndex == 2 ? 3 : langIndex); // Portuguese is code 3, index 2
- values[5] = langShiftIndex;
- assertEquals("minNumSeptetsWithHeader", minNumSeptetsWithHeader,
- udhLength * msgCount + minNumSeptets);
- mStatsCounters[langIndex * 4 + langShiftIndex]++;
- }
- }
-
- void printStats() {
- Log.d(TAG, "Unicode selection count: " + mUnicodeCounter);
- for (int i = 0; i < 12; i++) {
- Log.d(TAG, "Language pair index " + i + " count: " + mStatsCounters[i]);
- }
- }
- }
-
- @LargeTest
- public void testCalcLengthMixed7bit() throws Exception {
- StringBuilder sb = new StringBuilder(320);
- CounterHelper ch = new CounterHelper();
- Random r = new Random(0x4321); // use the same seed for reproducibility
- int[] expectedValues = new int[6];
- int[] origLockingShiftTables = GsmAlphabet.getEnabledLockingShiftTables();
- int[] origSingleShiftTables = GsmAlphabet.getEnabledSingleShiftTables();
- int enabledLanguagesTestCases = sEnabledSingleShiftTables.length;
- long startTime = System.currentTimeMillis();
-
- // Repeat for 10 test runs
- for (int run = 0; run < 10; run++) {
- sb.setLength(0);
- ch.clear();
- int unicodeOnlyCount = 0;
-
- // Test incrementally from 1 to 320 character random messages
- for (int i = 1; i < 320; i++) {
- // 1% chance to add from each special character class, else add an ASCII char
- int charClass = r.nextInt(100);
- if (charClass >= sNumCharacterClasses) {
- charClass = sNumCharacterClasses - 1; // last class is ASCII
- }
- int classLength = sCharacterClasses[charClass].length();
- char nextChar = sCharacterClasses[charClass].charAt(r.nextInt(classLength));
- sb.append(nextChar);
- ch.addChar(charClass);
-
-// if (i % 20 == 0) {
-// Log.d(TAG, "test string: " + sb);
-// }
-
- // Test string against all combinations of enabled languages
- boolean unicodeOnly = true;
- for (int j = 0; j < enabledLanguagesTestCases; j++) {
- GsmAlphabet.setEnabledSingleShiftTables(sEnabledSingleShiftTables[j]);
- GsmAlphabet.setEnabledLockingShiftTables(sEnabledLockingShiftTables[j]);
- ch.fillData(j, false, expectedValues, i);
- if (expectedValues[3] == SmsMessage.ENCODING_7BIT) {
- unicodeOnly = false;
- }
- callGsmLengthMethods(sb, false, expectedValues);
- // test 7 bit only mode
- ch.fillData(j, true, expectedValues, i);
- callGsmLengthMethods(sb, true, expectedValues);
- }
- // after 10 iterations with a Unicode-only string, skip to next test string
- // so we can spend more time testing strings that do encode into 7 bits.
- if (unicodeOnly && ++unicodeOnlyCount == 10) {
-// Log.d(TAG, "Unicode only: skipping to next test string");
- break;
- }
- }
- }
- ch.printStats();
- Log.d(TAG, "Completed in " + (System.currentTimeMillis() - startTime) + " ms");
- GsmAlphabet.setEnabledLockingShiftTables(origLockingShiftTables);
- GsmAlphabet.setEnabledSingleShiftTables(origSingleShiftTables);
- }
-
- private void callGsmLengthMethods(CharSequence msgBody, boolean use7bitOnly,
- int[] expectedValues)
- {
- // deprecated GSM-specific method
- int[] values = android.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly);
- assertEquals("msgCount", expectedValues[0], values[0]);
- assertEquals("codeUnitCount", expectedValues[1], values[1]);
- assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
- assertEquals("codeUnitSize", expectedValues[3], values[3]);
-
- int activePhone = TelephonyManager.getDefault().getPhoneType();
- if (TelephonyManager.PHONE_TYPE_GSM == activePhone) {
- values = android.telephony.SmsMessage.calculateLength(msgBody, use7bitOnly);
- assertEquals("msgCount", expectedValues[0], values[0]);
- assertEquals("codeUnitCount", expectedValues[1], values[1]);
- assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
- assertEquals("codeUnitSize", expectedValues[3], values[3]);
- }
-
- SmsMessageBase.TextEncodingDetails ted =
- com.android.internal.telephony.gsm.SmsMessage.calculateLength(msgBody, use7bitOnly);
- assertEquals("msgCount", expectedValues[0], ted.msgCount);
- assertEquals("codeUnitCount", expectedValues[1], ted.codeUnitCount);
- assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
- assertEquals("codeUnitSize", expectedValues[3], ted.codeUnitSize);
- assertEquals("languageTable", expectedValues[4], ted.languageTable);
- assertEquals("languageShiftTable", expectedValues[5], ted.languageShiftTable);
- }
-
- private void callCdmaLengthMethods(CharSequence msgBody, boolean use7bitOnly,
- int[] expectedValues)
- {
- int activePhone = TelephonyManager.getDefault().getPhoneType();
- if (TelephonyManager.PHONE_TYPE_CDMA == activePhone) {
- int[] values = android.telephony.SmsMessage.calculateLength(msgBody, use7bitOnly);
- assertEquals("msgCount", expectedValues[0], values[0]);
- assertEquals("codeUnitCount", expectedValues[1], values[1]);
- assertEquals("codeUnitsRemaining", expectedValues[2], values[2]);
- assertEquals("codeUnitSize", expectedValues[3], values[3]);
- }
-
- SmsMessageBase.TextEncodingDetails ted =
- com.android.internal.telephony.cdma.SmsMessage.calculateLength(msgBody, use7bitOnly);
- assertEquals("msgCount", expectedValues[0], ted.msgCount);
- assertEquals("codeUnitCount", expectedValues[1], ted.codeUnitCount);
- assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
- assertEquals("codeUnitSize", expectedValues[3], ted.codeUnitSize);
-
- ted = com.android.internal.telephony.cdma.sms.BearerData.calcTextEncodingDetails(msgBody, use7bitOnly);
- assertEquals("msgCount", expectedValues[0], ted.msgCount);
- assertEquals("codeUnitCount", expectedValues[1], ted.codeUnitCount);
- assertEquals("codeUnitsRemaining", expectedValues[2], ted.codeUnitsRemaining);
- assertEquals("codeUnitSize", expectedValues[3], ted.codeUnitSize);
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java
deleted file mode 100644
index 3757017..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TelephonyUtilsTest.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/**
- * Copyright (C) 2009 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 com.android.internal.telephony.RetryManager;
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-public class TelephonyUtilsTest extends TestCase {
-
- /**
- * After first creating the RetryManager
- * isRetryNeeded should be false and the time 0
- */
- @SmallTest
- public void testRetryManagerEmpty() throws Exception {
- RetryManager rm = new RetryManager();
-
- assertEquals(0, rm.getRetryCount());
- assertFalse(rm.isRetryForever());
- assertFalse(rm.isRetryNeeded());
- assertEquals(0, rm.getRetryCount());
- assertEquals(0, rm.getRetryTimer());
-
- rm.increaseRetryCount();
- assertFalse(rm.isRetryForever());
- assertFalse(rm.isRetryNeeded());
- assertEquals(0, rm.getRetryCount());
- assertEquals(0, rm.getRetryTimer());
-
- rm.setRetryCount(123);
- assertFalse(rm.isRetryForever());
- assertFalse(rm.isRetryNeeded());
- assertEquals(0, rm.getRetryCount());
- assertEquals(0, rm.getRetryTimer());
-
- rm.retryForeverUsingLastTimeout();
- assertTrue(rm.isRetryForever());
- assertTrue(rm.isRetryNeeded());
- assertEquals(0, rm.getRetryCount());
- assertEquals(0, rm.getRetryTimer());
-
- rm.setRetryCount(2);
- assertFalse(rm.isRetryForever());
- assertFalse(rm.isRetryNeeded());
- assertEquals(0, rm.getRetryCount());
- assertEquals(0, rm.getRetryTimer());
- }
-
- /**
- * A simple test and that randomization is doing something.
- */
- @SmallTest
- public void testRetryManagerSimplest() throws Exception {
- RetryManager rm = new RetryManager();
-
- assertTrue(rm.configure(1, 500, 10));
- int loops = 10;
- int count = 0;
- for (int i = 0; i < loops; i++) {
- assertTrue(rm.isRetryNeeded());
- int time = rm.getRetryTimer();
- assertTrue((time >= 500) && (time < 600));
- if (time == 500) {
- count++;
- }
- }
- assertFalse(count == loops);
- rm.increaseRetryCount();
- assertFalse(rm.isRetryNeeded());
- rm.setRetryCount(0);
- assertTrue(rm.isRetryNeeded());
- }
-
- /**
- * Test multiple values using simple configuration.
- */
- @SmallTest
- public void testRetryManagerSimple() throws Exception {
- RetryManager rm = new RetryManager();
-
- assertTrue(rm.configure(3, 1000, 0));
- assertTrue(rm.isRetryNeeded());
- assertEquals(1000, rm.getRetryTimer());
- assertEquals(rm.getRetryTimer(), 1000);
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- assertEquals(1000, rm.getRetryTimer());
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- assertEquals(1000, rm.getRetryTimer());
- rm.increaseRetryCount();
- assertFalse(rm.isRetryNeeded());
- assertEquals(1000, rm.getRetryTimer());
- }
-
- /**
- * Test string configuration, simplest
- */
- @SmallTest
- public void testRetryManageSimpleString() throws Exception {
- RetryManager rm = new RetryManager();
-
- assertTrue(rm.configure("101"));
- assertTrue(rm.isRetryNeeded());
- assertEquals(101, rm.getRetryTimer());
- rm.increaseRetryCount();
- assertFalse(rm.isRetryNeeded());
- }
-
- /**
- * Test infinite retires
- */
- @SmallTest
- public void testRetryManageInfinite() throws Exception {
- RetryManager rm = new RetryManager();
-
- assertTrue(rm.configure("1000,2000,3000,max_retries=infinite"));
- assertTrue(rm.isRetryNeeded());
- assertEquals(1000, rm.getRetryTimer());
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- assertEquals(2000, rm.getRetryTimer());
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- // All others are 3000 and isRetryNeeded is always true
- for (int i=0; i < 100; i++) {
- assertEquals(3000, rm.getRetryTimer());
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- }
- }
-
- /**
- * Test string configuration using all options and with quotes.
- */
- @SmallTest
- public void testRetryManageString() throws Exception {
- RetryManager rm = new RetryManager();
- int time;
-
- assertTrue(rm.configure(
- "\"max_retries=4, default_randomization=100,1000, 2000 :200 , 3000\""));
- assertTrue(rm.isRetryNeeded());
- time = rm.getRetryTimer();
- assertTrue((time >= 1000) && (time < 1100));
-
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- time = rm.getRetryTimer();
- assertTrue((time >= 2000) && (time < 2200));
-
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- time = rm.getRetryTimer();
- assertTrue((time >= 3000) && (time < 3100));
-
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- time = rm.getRetryTimer();
- assertTrue((time >= 3000) && (time < 3100));
-
- rm.increaseRetryCount();
- assertFalse(rm.isRetryNeeded());
- }
-
- /**
- * Test string configuration using all options.
- */
- @SmallTest
- public void testRetryManageForever() throws Exception {
- RetryManager rm = new RetryManager();
- int time;
-
- assertTrue(rm.configure("1000, 2000, 3000"));
- assertTrue(rm.isRetryNeeded());
- assertFalse(rm.isRetryForever());
- assertEquals(0, rm.getRetryCount());
- assertEquals(1000, rm.getRetryTimer());
-
- rm.retryForeverUsingLastTimeout();
- rm.increaseRetryCount();
- rm.increaseRetryCount();
- rm.increaseRetryCount();
- assertTrue(rm.isRetryNeeded());
- assertTrue(rm.isRetryForever());
- assertEquals(3, rm.getRetryCount());
- assertEquals(3000, rm.getRetryTimer());
-
- rm.setRetryCount(1);
- assertTrue(rm.isRetryNeeded());
- assertFalse(rm.isRetryForever());
- assertEquals(1, rm.getRetryCount());
- assertEquals(2000, rm.getRetryTimer());
-
- rm.retryForeverUsingLastTimeout();
- assertTrue(rm.isRetryNeeded());
- assertTrue(rm.isRetryForever());
- rm.resetRetryCount();
- assertTrue(rm.isRetryNeeded());
- assertFalse(rm.isRetryForever());
- assertEquals(0, rm.getRetryCount());
- assertEquals(1000, rm.getRetryTimer());
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
deleted file mode 100644
index cb67a93..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 com.android.internal.telephony.Phone;
-import android.telephony.CellInfo;
-
-/**
- * Stub class used for unit tests
- */
-
-public class TestPhoneNotifier implements PhoneNotifier {
- public TestPhoneNotifier() {
- }
-
- public void notifyPhoneState(Phone sender) {
- }
-
- public void notifyServiceState(Phone sender) {
- }
-
- public void notifyCellLocation(Phone sender) {
- }
-
- public void notifySignalStrength(Phone sender) {
- }
-
- public void notifyMessageWaitingChanged(Phone sender) {
- }
-
- public void notifyCallForwardingChanged(Phone sender) {
- }
-
- public void notifyDataConnection(Phone sender, String reason, String apnType) {
- }
-
- public void notifyDataConnection(Phone sender, String reason, String apnType,
- Phone.DataState state) {
- }
-
- public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
- }
-
- public void notifyDataActivity(Phone sender) {
- }
-
- public void notifyOtaspChanged(Phone sender, int otaspMode) {
- }
-
- public void notifyCellInfo(Phone sender, CellInfo cellInfo) {
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
deleted file mode 100644
index d31b294..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/Wap230WspContentTypeTest.java
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.internal.telephony.WspTypeDecoder;
-import com.android.internal.util.HexDump;
-
-import java.io.ByteArrayOutputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-public class Wap230WspContentTypeTest extends TestCase {
-
- public static final Map<Integer, String> WELL_KNOWN_SHORT_MIME_TYPES
- = new HashMap<Integer, String>();
- public static final Map<Integer, String> WELL_KNOWN_LONG_MIME_TYPES
- = new HashMap<Integer, String>();
- public static final Map<Integer, String> WELL_KNOWN_PARAMETERS
- = new HashMap<Integer, String>();
-
- static {
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x00, "*/*");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x01, "text/*");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x02, "text/html");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x03, "text/plain");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x04, "text/x-hdml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x05, "text/x-ttml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x06, "text/x-vCalendar");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x07, "text/x-vCard");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x0B, "multipart/*");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x0C, "multipart/mixed");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x0D, "multipart/form-data");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x0E, "multipart/byterantes");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x0F, "multipart/alternative");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x10, "application/*");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x11, "application/java-vm");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x13, "application/x-hdmlc");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x1C, "image/*");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x1D, "image/gif");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x1E, "image/jpeg");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x1F, "image/tiff");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x20, "image/png");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x27, "application/xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x28, "text/xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x31, "text/vnd.wap.co");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x37, "application/pkcs7-mime");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x3B, "application/xhtml+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x3C, "application/wml+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x3D, "text/css");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x4F, "audio/*");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x50, "video/*");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x52, "application/mikey");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
- WELL_KNOWN_SHORT_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
-
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x020C, "image/x-up-wpng");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0305, "text/calendar");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
- WELL_KNOWN_LONG_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
-
- WELL_KNOWN_PARAMETERS.put(0x00, "Q");
- WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
- WELL_KNOWN_PARAMETERS.put(0x02, "Level");
- WELL_KNOWN_PARAMETERS.put(0x03, "Type");
- WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
- WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
- WELL_KNOWN_PARAMETERS.put(0x09, "Type");
- WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
- WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
- WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
- WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
- WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
- WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
- WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
- WELL_KNOWN_PARAMETERS.put(0x16, "Size");
- WELL_KNOWN_PARAMETERS.put(0x17, "Name");
- WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
- WELL_KNOWN_PARAMETERS.put(0x19, "Start");
- WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
- WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
- WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
- WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
-
- }
-
- final int WSP_DEFINED_SHORT_MIME_TYPE_COUNT = 85;
- final int WSP_DEFINED_LONG_MIME_TYPE_COUNT = 85;
-
- private static final byte WSP_STRING_TERMINATOR = 0x00;
- private static final byte WSP_SHORT_INTEGER_MASK = (byte) 0x80;
- private static final byte WSP_LENGTH_QUOTE = 0x1F;
- private static final byte WSP_QUOTE = 0x22;
-
- private static final short LONG_MIME_TYPE_OMA_DIRECTORY_XML = 0x0314;
- private static final short LONG_MIME_TYPE_UNASSIGNED = 0x052C;
-
- private static final byte SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE = 0x3F;
- private static final byte SHORT_MIME_TYPE_UNASSIGNED = 0x60;
-
- private static final String STRING_MIME_TYPE_ROLLOVER_CERTIFICATE
- = "application/vnd.wap.rollover-certificate";
-
- private static final byte TYPED_PARAM_Q = 0x00;
- private static final byte TYPED_PARAM_DOMAIN = 0x1C;
- private static final byte PARAM_UNASSIGNED = 0x42;
- private static final byte PARAM_NO_VALUE = 0x00;
- private static final byte TYPED_PARAM_SEC = 0x11;
- private static final byte TYPED_PARAM_MAC = 0x12;
-
- public void testHasExpectedNumberOfShortMimeTypes() {
- assertEquals(WSP_DEFINED_SHORT_MIME_TYPE_COUNT, WELL_KNOWN_SHORT_MIME_TYPES.size());
- }
-
- public void testHasExpectedNumberOfLongMimeTypes() {
- assertEquals(WSP_DEFINED_LONG_MIME_TYPE_COUNT, WELL_KNOWN_LONG_MIME_TYPES.size());
- }
-
- public void testWellKnownShortIntegerMimeTypeValues() {
-
- for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) {
- WspTypeDecoder unit = new WspTypeDecoder(
- HexDump.toByteArray((byte) (value | WSP_SHORT_INTEGER_MASK)));
- assertTrue(unit.decodeContentType(0));
- String mimeType = unit.getValueString();
- int wellKnownValue = (int) unit.getValue32();
- assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType);
- assertEquals(value, wellKnownValue);
- assertEquals(1, unit.getDecodedDataLength());
- }
- }
-
- public void testWellKnownLongIntegerMimeTypeValues() {
- byte headerLength = 3;
- byte typeLength = 2;
- for (int value : Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.keySet()) {
- byte[] data = new byte[10];
- data[0] = headerLength;
- data[1] = typeLength;
- data[2] = (byte) (value >> 8);
- data[3] = (byte) (value & 0xFF);
- WspTypeDecoder unit = new WspTypeDecoder(data);
- assertTrue(unit.decodeContentType(0));
- String mimeType = unit.getValueString();
- int wellKnownValue = (int) unit.getValue32();
- assertEquals(Wap230WspContentTypeTest.WELL_KNOWN_SHORT_MIME_TYPES.get(value), mimeType);
- assertEquals(value, wellKnownValue);
- assertEquals(4, unit.getDecodedDataLength());
- }
- }
-
- public void testDecodeReturnsFalse_WhenOnlyAZeroBytePresent() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x00);
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertFalse(unit.decodeContentType(0));
- }
-
- public void testConstrainedMediaExtensionMedia() throws Exception {
-
- String testType = "application/wibble";
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(testType.getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
- String mimeType = unit.getValueString();
- assertEquals(testType, mimeType);
- assertEquals(-1, unit.getValue32());
- assertEquals(19, unit.getDecodedDataLength());
- }
-
- public void testGeneralFormShortLengthExtensionMedia() throws Exception {
-
- String testType = "12345678901234567890123456789";
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(testType.length() + 1);
- out.write(testType.getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
- assertEquals(testType, mimeType);
- assertEquals(-1, unit.getValue32());
- assertEquals(31, unit.getDecodedDataLength());
- }
-
- public void testGeneralFormShortLengthWellKnownShortInteger() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x01);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
- assertEquals(2, unit.getDecodedDataLength());
-
- }
-
- public void testGeneralFormShortLengthWellKnownShortIntegerWithUnknownValue() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x01);
- out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
- assertNull(mimeType);
- assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32());
- assertEquals(2, unit.getDecodedDataLength());
-
- }
-
- public void testGeneralFormShortLengthWellKnownLongInteger() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(0x03); // header length
- out.write(0x02); // type length (2 octets)
- out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8);
- out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals("application/oma-directory+xml", mimeType);
- assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32());
- assertEquals(4, unit.getDecodedDataLength());
- }
-
- public void testGeneralFormShortLengthWellKnownLongIntegerWithUnknownValue() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(0x03); // Value-length, short-length
- out.write(0x02); // long-integer length (2 octets)
- out.write(LONG_MIME_TYPE_UNASSIGNED >> 8);
- out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertNull(mimeType);
- assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32());
- assertEquals(4, unit.getDecodedDataLength());
-
- }
-
- public void testGeneralFormLengthQuoteWellKnownShortInteger() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(WSP_LENGTH_QUOTE);
- out.write(0x01); // Length as UINTVAR
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
- assertEquals(3, unit.getDecodedDataLength());
-
- }
-
- public void testGeneralFormLengthQuoteWellKnownShortIntegerWithUnknownValue() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(WSP_LENGTH_QUOTE);
- out.write(0x01); // Length as UINTVAR
- out.write(SHORT_MIME_TYPE_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
- assertNull(mimeType);
- assertEquals(SHORT_MIME_TYPE_UNASSIGNED, unit.getValue32());
- assertEquals(3, unit.getDecodedDataLength());
- }
-
- public void testGeneralFormLengthQuoteWellKnownLongInteger() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(WSP_LENGTH_QUOTE);
- out.write(0x03); // Length as UINTVAR
- out.write(0x02); // long-integer length (2 octets)
- out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML >> 8);
- out.write(LONG_MIME_TYPE_OMA_DIRECTORY_XML & 0xFF);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals("application/oma-directory+xml", mimeType);
- assertEquals(LONG_MIME_TYPE_OMA_DIRECTORY_XML, unit.getValue32());
- assertEquals(5, unit.getDecodedDataLength());
-
- }
-
- public void testGeneralFormLengthQuoteWellKnownLongIntegerWithUnknownValue() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(WSP_LENGTH_QUOTE);
- out.write(0x03); // Length as UINTVAR
- out.write(0x02); // long-integer length (2 octets)
- out.write(LONG_MIME_TYPE_UNASSIGNED >> 8);
- out.write(LONG_MIME_TYPE_UNASSIGNED & 0xFF);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertNull(mimeType);
- assertEquals(LONG_MIME_TYPE_UNASSIGNED, unit.getValue32());
- assertEquals(5, unit.getDecodedDataLength());
-
- }
-
- public void testGeneralFormLengthQuoteExtensionMedia() throws Exception {
-
- String testType = "application/wibble";
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(WSP_LENGTH_QUOTE);
- out.write(testType.length() + 1); // Length as UINTVAR
-
- out.write(testType.getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(testType, mimeType);
- assertEquals(-1, unit.getValue32());
- assertEquals(21, unit.getDecodedDataLength());
-
- }
-
- public void testGeneralFormLengthQuoteExtensionMediaWithNiceLongMimeType() throws Exception {
-
- String testType =
- "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
- +"01234567890123456789012345678901234567890123456789012345678901234567890123456789";
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- out.write(WSP_LENGTH_QUOTE);
- out.write(0x81); // Length as UINTVAR (161 decimal, 0xA1), 2 bytes
- out.write(0x21);
-
- out.write(testType.getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(testType, mimeType);
- assertEquals(-1, unit.getValue32());
- assertEquals(164, unit.getDecodedDataLength());
-
- }
-
- public void testConstrainedMediaExtensionMediaWithSpace() throws Exception {
-
- String testType = " application/wibble";
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(testType.getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(testType, mimeType);
- assertEquals(-1, unit.getValue32());
- assertEquals(20, unit.getDecodedDataLength());
-
- }
-
- public void testTypedParamWellKnownShortIntegerNoValue() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x03); // Value-length, short-length
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
- out.write(PARAM_NO_VALUE);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
- assertEquals(4, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals(null, params.get("Domain"));
-
- }
-
- public void testTypedParamWellKnownShortIntegerTokenText() throws Exception {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x14); // Value-length, short-length
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
- out.write("wdstechnology.com".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
- assertEquals(out.toByteArray().length, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("wdstechnology.com", params.get("Domain"));
-
- }
-
- public void testTypedParamWellKnownLongIntegerTokenText() throws Exception {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x15);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(0x01);
- out.write(TYPED_PARAM_DOMAIN);
- out.write("wdstechnology.com".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
- assertEquals(22, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("wdstechnology.com", params.get("Domain"));
-
- }
-
- public void testTypedParamWellKnownShortIntegerQuotedText() throws Exception {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x15);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(TYPED_PARAM_DOMAIN | WSP_SHORT_INTEGER_MASK);
- out.write(WSP_QUOTE);
- out.write("wdstechnology.com".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(0x3F, unit.getValue32());
- assertEquals(22, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("wdstechnology.com", params.get("Domain"));
-
- }
-
- public void testTypedParamWellKnownShortIntegerCompactIntegerValue() {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x3);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK);
- out.write(0x01 | WSP_SHORT_INTEGER_MASK);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(0x3F, unit.getValue32());
- assertEquals(4, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("1", params.get("SEC"));
-
- }
-
- public void testTypedParamWellKnownShortIntegerMultipleParameters() throws Exception {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x0B);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(TYPED_PARAM_SEC | WSP_SHORT_INTEGER_MASK);
- out.write(0x01 | WSP_SHORT_INTEGER_MASK);
- out.write(TYPED_PARAM_MAC | WSP_SHORT_INTEGER_MASK);
- out.write(WSP_QUOTE);
- out.write("imapc".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
- assertEquals(12, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("1", params.get("SEC"));
- assertEquals("imapc", params.get("MAC"));
- }
-
- public void testUntypedParamIntegerValueShortInteger() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x0A);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write("MYPARAM".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR); // EOS
- out.write(0x45 | WSP_SHORT_INTEGER_MASK);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
- assertEquals(11, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("69", params.get("MYPARAM"));
- }
-
- public void testUntypedParamIntegerValueLongInteger() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x0C);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write("MYPARAM".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
- out.write(0x02); // Short Length
- out.write(0x42); // Long Integer byte 1
- out.write(0x69); // Long Integer byte 2
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(0x3F, unit.getValue32());
- assertEquals(13, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("17001", params.get("MYPARAM"));
- }
-
- public void testUntypedParamTextNoValue() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x0A);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write("MYPARAM".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
- out.write(PARAM_NO_VALUE);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
- assertEquals(11, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals(null, params.get("MYPARAM"));
-
- }
-
- public void testUntypedParamTextTokenText() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x11);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write("MYPARAM".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
- out.write("myvalue".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
- assertEquals(18, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("myvalue", params.get("MYPARAM"));
- }
-
- public void testUntypedParamTextQuotedString() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x11);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write("MYPARAM".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
- out.write(WSP_QUOTE);
- out.write("myvalue".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
- assertEquals(19, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("myvalue", params.get("MYPARAM"));
-
- }
-
- public void testDecodesReturnsFalse_ForParamWithMissingValue() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x09);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write("MYPARAM".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertFalse(unit.decodeContentType(0));
- }
-
- public void testTypedParamTextQValue() {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x04);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(TYPED_PARAM_Q);
- out.write(0x83); // Q value byte 1
- out.write(0x31); // Q value byte 2
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(0x3F, unit.getValue32());
- assertEquals(5, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("433", params.get("Q"));
-
- }
-
- public void testTypedParamUnassignedWellKnownShortIntegerTokenText() throws Exception {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x14);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(PARAM_UNASSIGNED | WSP_SHORT_INTEGER_MASK);
- out.write("wdstechnology.com".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
- assertEquals(21, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("wdstechnology.com", params.get("unassigned/0x42"));
-
- }
-
- public void testTypedParamUnassignedWellKnownLongIntegerTokenText() throws Exception {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x15);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(0x01); // Short-length of well-known parameter token
- out.write(PARAM_UNASSIGNED);
- out.write("wdstechnology.com".getBytes("US-ASCII"));
- out.write(WSP_STRING_TERMINATOR);
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertTrue(unit.decodeContentType(0));
-
- String mimeType = unit.getValueString();
-
- assertEquals(STRING_MIME_TYPE_ROLLOVER_CERTIFICATE, mimeType);
- assertEquals(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE, unit.getValue32());
-
- assertEquals(22, unit.getDecodedDataLength());
-
- Map<String, String> params = unit.getContentParameters();
- assertEquals("wdstechnology.com", params.get("unassigned/0x42"));
- }
-
- public void testDecodesReturnsFalse_WhenParamValueNotTerminated() throws Exception {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- out.write(0x15);
- out.write(SHORT_MIME_TYPE_ROLLOVER_CERTIFICATE | WSP_SHORT_INTEGER_MASK);
- out.write(0x01);
- out.write(PARAM_UNASSIGNED);
- out.write("wdstechnology.com".getBytes("US-ASCII"));
-
- WspTypeDecoder unit = new WspTypeDecoder(out.toByteArray());
- assertFalse(unit.decodeContentType(0));
- }
-}
\ No newline at end of file
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
deleted file mode 100644
index a95f60c..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-import android.os.Parcel;
-import android.telephony.SmsCbCmasInfo;
-import android.telephony.SmsCbMessage;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.util.BitwiseOutputStream;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Test cases for basic SmsCbMessage operation for CDMA.
- */
-public class CdmaSmsCbTest extends AndroidTestCase {
-
- /* Copy of private subparameter identifier constants from BearerData class. */
- private static final byte SUBPARAM_MESSAGE_IDENTIFIER = (byte) 0x00;
- private static final byte SUBPARAM_USER_DATA = (byte) 0x01;
- private static final byte SUBPARAM_PRIORITY_INDICATOR = (byte) 0x08;
- private static final byte SUBPARAM_LANGUAGE_INDICATOR = (byte) 0x0D;
- private static final byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA = 0x12;
-
- /**
- * Initialize a Parcel for an incoming CDMA cell broadcast. The caller will write the
- * bearer data and then convert it to an SmsMessage.
- * @param serviceCategory the CDMA service category
- * @return the initialized Parcel
- */
- private static Parcel createBroadcastParcel(int serviceCategory) {
- Parcel p = Parcel.obtain();
-
- p.writeInt(SmsEnvelope.TELESERVICE_NOT_SET);
- p.writeByte((byte) 1); // non-zero for MESSAGE_TYPE_BROADCAST
- p.writeInt(serviceCategory);
-
- // dummy address (RIL may generate a different dummy address for broadcasts)
- p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); // sAddress.digit_mode
- p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); // sAddress.number_mode
- p.writeInt(CdmaSmsAddress.TON_UNKNOWN); // sAddress.number_type
- p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY); // sAddress.number_plan
- p.writeByte((byte) 0); // sAddress.number_of_digits
- p.writeInt((byte) 0); // sSubAddress.subaddressType
- p.writeByte((byte) 0); // sSubAddress.odd
- p.writeByte((byte) 0); // sSubAddress.number_of_digits
- return p;
- }
-
- /**
- * Initialize a BitwiseOutputStream with the CDMA bearer data subparameters except for
- * user data. The caller will append the user data and add it to the parcel.
- * @param messageId the 16-bit message identifier
- * @param priority message priority
- * @param language message language code
- * @return the initialized BitwiseOutputStream
- */
- private static BitwiseOutputStream createBearerDataStream(int messageId, int priority,
- int language) throws BitwiseOutputStream.AccessException {
- BitwiseOutputStream bos = new BitwiseOutputStream(10);
- bos.write(8, SUBPARAM_MESSAGE_IDENTIFIER);
- bos.write(8, 3); // length: 3 bytes
- bos.write(4, BearerData.MESSAGE_TYPE_DELIVER);
- bos.write(8, ((messageId >>> 8) & 0xff));
- bos.write(8, (messageId & 0xff));
- bos.write(1, 0); // no User Data Header
- bos.write(3, 0); // reserved
-
- if (priority != -1) {
- bos.write(8, SUBPARAM_PRIORITY_INDICATOR);
- bos.write(8, 1); // length: 1 byte
- bos.write(2, (priority & 0x03));
- bos.write(6, 0); // reserved
- }
-
- if (language != -1) {
- bos.write(8, SUBPARAM_LANGUAGE_INDICATOR);
- bos.write(8, 1); // length: 1 byte
- bos.write(8, (language & 0xff));
- }
-
- return bos;
- }
-
- /**
- * Write the bearer data array to the parcel, then return a new SmsMessage from the parcel.
- * @param p the parcel containing the CDMA SMS headers
- * @param bearerData the bearer data byte array to append to the parcel
- * @return the new SmsMessage created from the parcel
- */
- private static SmsMessage createMessageFromParcel(Parcel p, byte[] bearerData) {
- p.writeInt(bearerData.length);
- for (byte b : bearerData) {
- p.writeByte(b);
- }
- p.setDataPosition(0); // reset position for reading
- SmsMessage message = SmsMessage.newFromParcel(p);
- p.recycle();
- return message;
- }
-
- /**
- * Create a parcel for an incoming CMAS broadcast, then return a new SmsMessage created
- * from the parcel.
- * @param serviceCategory the CDMA service category
- * @param messageId the 16-bit message identifier
- * @param priority message priority
- * @param language message language code
- * @param body message body
- * @param cmasCategory CMAS category (or -1 to skip adding CMAS type 1 elements record)
- * @param responseType CMAS response type
- * @param severity CMAS severity
- * @param urgency CMAS urgency
- * @param certainty CMAS certainty
- * @return the newly created SmsMessage object
- */
- private static SmsMessage createCmasSmsMessage(int serviceCategory, int messageId, int priority,
- int language, int encoding, String body, int cmasCategory, int responseType,
- int severity, int urgency, int certainty) throws Exception {
- BitwiseOutputStream cmasBos = new BitwiseOutputStream(10);
- cmasBos.write(8, 0); // CMAE protocol version 0
-
- if (body != null) {
- cmasBos.write(8, 0); // Type 0 elements (alert text)
- encodeBody(encoding, body, true, cmasBos);
- }
-
- if (cmasCategory != SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN) {
- cmasBos.write(8, 1); // Type 1 elements
- cmasBos.write(8, 4); // length: 4 bytes
- cmasBos.write(8, (cmasCategory & 0xff));
- cmasBos.write(8, (responseType & 0xff));
- cmasBos.write(4, (severity & 0x0f));
- cmasBos.write(4, (urgency & 0x0f));
- cmasBos.write(4, (certainty & 0x0f));
- cmasBos.write(4, 0); // pad to octet boundary
- }
-
- byte[] cmasUserData = cmasBos.toByteArray();
-
- Parcel p = createBroadcastParcel(serviceCategory);
- BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language);
-
- bos.write(8, SUBPARAM_USER_DATA);
- bos.write(8, cmasUserData.length + 2); // add 2 bytes for msg_encoding and num_fields
- bos.write(5, UserData.ENCODING_OCTET);
- bos.write(8, cmasUserData.length);
- bos.writeByteArray(cmasUserData.length * 8, cmasUserData);
- bos.write(3, 0); // pad to byte boundary
-
- return createMessageFromParcel(p, bos.toByteArray());
- }
-
- /**
- * Create a parcel for an incoming CDMA cell broadcast, then return a new SmsMessage created
- * from the parcel.
- * @param serviceCategory the CDMA service category
- * @param messageId the 16-bit message identifier
- * @param priority message priority
- * @param language message language code
- * @param encoding user data encoding method
- * @param body the message body
- * @return the newly created SmsMessage object
- */
- private static SmsMessage createBroadcastSmsMessage(int serviceCategory, int messageId,
- int priority, int language, int encoding, String body) throws Exception {
- Parcel p = createBroadcastParcel(serviceCategory);
- BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language);
-
- bos.write(8, SUBPARAM_USER_DATA);
- encodeBody(encoding, body, false, bos);
-
- return createMessageFromParcel(p, bos.toByteArray());
- }
-
- /**
- * Append the message length, encoding, and body to the BearerData output stream.
- * This is used for writing the User Data subparameter for non-CMAS broadcasts and for
- * writing the alert text for CMAS broadcasts.
- * @param encoding one of the CDMA UserData encoding values
- * @param body the message body
- * @param isCmasRecord true if this is a CMAS type 0 elements record; false for user data
- * @param bos the BitwiseOutputStream to write to
- * @throws Exception on any encoding error
- */
- private static void encodeBody(int encoding, String body, boolean isCmasRecord,
- BitwiseOutputStream bos) throws Exception {
- if (encoding == UserData.ENCODING_7BIT_ASCII || encoding == UserData.ENCODING_IA5) {
- int charCount = body.length();
- int recordBits = (charCount * 7) + 5; // add 5 bits for char set field
- int recordOctets = (recordBits + 7) / 8; // round up to octet boundary
- int padBits = (recordOctets * 8) - recordBits;
-
- if (!isCmasRecord) {
- recordOctets++; // add 8 bits for num_fields
- }
-
- bos.write(8, recordOctets);
- bos.write(5, (encoding & 0x1f));
-
- if (!isCmasRecord) {
- bos.write(8, charCount);
- }
-
- for (int i = 0; i < charCount; i++) {
- bos.write(7, body.charAt(i));
- }
-
- bos.write(padBits, 0); // pad to octet boundary
- } else if (encoding == UserData.ENCODING_GSM_7BIT_ALPHABET
- || encoding == UserData.ENCODING_GSM_DCS) {
- // convert to 7-bit packed encoding with septet count in index 0 of byte array
- byte[] encodedBody = GsmAlphabet.stringToGsm7BitPacked(body);
-
- int charCount = encodedBody[0]; // septet count
- int recordBits = (charCount * 7) + 5; // add 5 bits for char set field
- int recordOctets = (recordBits + 7) / 8; // round up to octet boundary
- int padBits = (recordOctets * 8) - recordBits;
-
- if (!isCmasRecord) {
- recordOctets++; // add 8 bits for num_fields
- if (encoding == UserData.ENCODING_GSM_DCS) {
- recordOctets++; // add 8 bits for DCS (message type)
- }
- }
-
- bos.write(8, recordOctets);
- bos.write(5, (encoding & 0x1f));
-
- if (!isCmasRecord && encoding == UserData.ENCODING_GSM_DCS) {
- bos.write(8, 0); // GSM DCS: 7 bit default alphabet, no msg class
- }
-
- if (!isCmasRecord) {
- bos.write(8, charCount);
- }
- byte[] bodySeptets = Arrays.copyOfRange(encodedBody, 1, encodedBody.length);
- bos.writeByteArray(charCount * 7, bodySeptets);
- bos.write(padBits, 0); // pad to octet boundary
- } else if (encoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) {
- // 6 bit packed encoding with 0x20 offset (ASCII 0x20 - 0x60)
- int charCount = body.length();
- int recordBits = (charCount * 6) + 21; // add 21 bits for header fields
- int recordOctets = (recordBits + 7) / 8; // round up to octet boundary
- int padBits = (recordOctets * 8) - recordBits;
-
- bos.write(8, recordOctets);
-
- bos.write(5, (encoding & 0x1f));
- bos.write(8, UserData.IS91_MSG_TYPE_SHORT_MESSAGE);
- bos.write(8, charCount);
-
- for (int i = 0; i < charCount; i++) {
- bos.write(6, ((int) body.charAt(i) - 0x20));
- }
-
- bos.write(padBits, 0); // pad to octet boundary
- } else {
- byte[] encodedBody;
- switch (encoding) {
- case UserData.ENCODING_UNICODE_16:
- encodedBody = body.getBytes("UTF-16BE");
- break;
-
- case UserData.ENCODING_SHIFT_JIS:
- encodedBody = body.getBytes("Shift_JIS");
- break;
-
- case UserData.ENCODING_KOREAN:
- encodedBody = body.getBytes("KSC5601");
- break;
-
- case UserData.ENCODING_LATIN_HEBREW:
- encodedBody = body.getBytes("ISO-8859-8");
- break;
-
- case UserData.ENCODING_LATIN:
- default:
- encodedBody = body.getBytes("ISO-8859-1");
- break;
- }
- int charCount = body.length(); // use actual char count for num fields
- int recordOctets = encodedBody.length + 1; // add 1 byte for encoding and pad bits
- if (!isCmasRecord) {
- recordOctets++; // add 8 bits for num_fields
- }
- bos.write(8, recordOctets);
- bos.write(5, (encoding & 0x1f));
- if (!isCmasRecord) {
- bos.write(8, charCount);
- }
- bos.writeByteArray(encodedBody.length * 8, encodedBody);
- bos.write(3, 0); // pad to octet boundary
- }
- }
-
- private static final String TEST_TEXT = "This is a test CDMA cell broadcast message..."
- + "678901234567890123456789012345678901234567890";
-
- private static final String PRES_ALERT =
- "THE PRESIDENT HAS ISSUED AN EMERGENCY ALERT. CHECK LOCAL MEDIA FOR MORE DETAILS";
-
- private static final String EXTREME_ALERT = "FLASH FLOOD WARNING FOR SOUTH COCONINO COUNTY"
- + " - NORTH CENTRAL ARIZONA UNTIL 415 PM MST";
-
- private static final String SEVERE_ALERT = "SEVERE WEATHER WARNING FOR SOMERSET COUNTY"
- + " - NEW JERSEY UNTIL 415 PM MST";
-
- private static final String AMBER_ALERT =
- "AMBER ALERT:Mountain View,CA VEH'07 Blue Honda Civic CA LIC 5ABC123";
-
- private static final String MONTHLY_TEST_ALERT = "This is a test of the emergency alert system."
- + " This is only a test. 89012345678901234567890";
-
- private static final String IS91_TEXT = "IS91 SHORT MSG"; // max length 14 chars
-
- /**
- * Verify that the SmsCbMessage has the correct values for CDMA.
- * @param cbMessage the message to test
- */
- private static void verifyCbValues(SmsCbMessage cbMessage) {
- assertEquals(SmsCbMessage.MESSAGE_FORMAT_3GPP2, cbMessage.getMessageFormat());
- assertEquals(SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, cbMessage.getGeographicalScope());
- assertEquals(false, cbMessage.isEtwsMessage()); // ETWS on CDMA not currently supported
- }
-
- private static void doTestNonEmergencyBroadcast(int encoding) throws Exception {
- SmsMessage msg = createBroadcastSmsMessage(123, 456, BearerData.PRIORITY_NORMAL,
- BearerData.LANGUAGE_ENGLISH, encoding, TEST_TEXT);
-
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- verifyCbValues(cbMessage);
- assertEquals(123, cbMessage.getServiceCategory());
- assertEquals(456, cbMessage.getSerialNumber());
- assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority());
- assertEquals("en", cbMessage.getLanguageCode());
- assertEquals(TEST_TEXT, cbMessage.getMessageBody());
- assertEquals(false, cbMessage.isEmergencyMessage());
- assertEquals(false, cbMessage.isCmasMessage());
- }
-
- public void testNonEmergencyBroadcast7bitAscii() throws Exception {
- doTestNonEmergencyBroadcast(UserData.ENCODING_7BIT_ASCII);
- }
-
- public void testNonEmergencyBroadcast7bitGsm() throws Exception {
- doTestNonEmergencyBroadcast(UserData.ENCODING_GSM_7BIT_ALPHABET);
- }
-
- public void testNonEmergencyBroadcast16bitUnicode() throws Exception {
- doTestNonEmergencyBroadcast(UserData.ENCODING_UNICODE_16);
- }
-
- public void testNonEmergencyBroadcastIs91Extended() throws Exception {
- // IS-91 doesn't support language or priority subparameters, max 14 chars text
- SmsMessage msg = createBroadcastSmsMessage(987, 654, -1, -1,
- UserData.ENCODING_IS91_EXTENDED_PROTOCOL, IS91_TEXT);
-
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- verifyCbValues(cbMessage);
- assertEquals(987, cbMessage.getServiceCategory());
- assertEquals(654, cbMessage.getSerialNumber());
- assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority());
- assertEquals(null, cbMessage.getLanguageCode());
- assertEquals(IS91_TEXT, cbMessage.getMessageBody());
- assertEquals(false, cbMessage.isEmergencyMessage());
- assertEquals(false, cbMessage.isCmasMessage());
- }
-
- private static void doTestCmasBroadcast(int serviceCategory, int messageClass, String body)
- throws Exception {
- SmsMessage msg = createCmasSmsMessage(
- serviceCategory, 1234, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
- UserData.ENCODING_7BIT_ASCII, body, -1, -1, -1, -1, -1);
-
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- verifyCbValues(cbMessage);
- assertEquals(serviceCategory, cbMessage.getServiceCategory());
- assertEquals(1234, cbMessage.getSerialNumber());
- assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
- assertEquals("en", cbMessage.getLanguageCode());
- assertEquals(body, cbMessage.getMessageBody());
- assertEquals(true, cbMessage.isEmergencyMessage());
- assertEquals(true, cbMessage.isCmasMessage());
- SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
- assertEquals(messageClass, cmasInfo.getMessageClass());
- assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
- assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
- assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity());
- assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency());
- assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty());
- }
-
- public void testCmasPresidentialAlert() throws Exception {
- doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
- SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, PRES_ALERT);
- }
-
- public void testCmasExtremeAlert() throws Exception {
- doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
- SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, EXTREME_ALERT);
- }
-
- public void testCmasSevereAlert() throws Exception {
- doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT,
- SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT, SEVERE_ALERT);
- }
-
- public void testCmasAmberAlert() throws Exception {
- doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
- SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY, AMBER_ALERT);
- }
-
- public void testCmasTestMessage() throws Exception {
- doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE,
- SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST, MONTHLY_TEST_ALERT);
- }
-
- public void testCmasExtremeAlertType1Elements() throws Exception {
- SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
- 5678, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
- UserData.ENCODING_7BIT_ASCII, EXTREME_ALERT, SmsCbCmasInfo.CMAS_CATEGORY_ENV,
- SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, SmsCbCmasInfo.CMAS_SEVERITY_SEVERE,
- SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);
-
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- verifyCbValues(cbMessage);
- assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
- cbMessage.getServiceCategory());
- assertEquals(5678, cbMessage.getSerialNumber());
- assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
- assertEquals("en", cbMessage.getLanguageCode());
- assertEquals(EXTREME_ALERT, cbMessage.getMessageBody());
- assertEquals(true, cbMessage.isEmergencyMessage());
- assertEquals(true, cbMessage.isCmasMessage());
- SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
- assertEquals(SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, cmasInfo.getMessageClass());
- assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_ENV, cmasInfo.getCategory());
- assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, cmasInfo.getResponseType());
- assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_SEVERE, cmasInfo.getSeverity());
- assertEquals(SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, cmasInfo.getUrgency());
- assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY, cmasInfo.getCertainty());
- }
-
- // VZW requirement is to discard message with unsupported charset. Verify that we return null
- // for this unsupported character set.
- public void testCmasUnsupportedCharSet() throws Exception {
- SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
- 12345, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
- UserData.ENCODING_GSM_DCS, EXTREME_ALERT, -1, -1, -1, -1, -1);
-
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- assertNull("expected null for unsupported charset", cbMessage);
- }
-
- // VZW requirement is to discard message with unsupported charset. Verify that we return null
- // for this unsupported character set.
- public void testCmasUnsupportedCharSet2() throws Exception {
- SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
- 67890, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
- UserData.ENCODING_KOREAN, EXTREME_ALERT, -1, -1, -1, -1, -1);
-
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- assertNull("expected null for unsupported charset", cbMessage);
- }
-
- // VZW requirement is to discard message without record type 0. The framework will decode it
- // and the app will discard it.
- public void testCmasNoRecordType0() throws Exception {
- SmsMessage msg = createCmasSmsMessage(
- SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, 1234,
- BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
- UserData.ENCODING_7BIT_ASCII, null, -1, -1, -1, -1, -1);
-
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- verifyCbValues(cbMessage);
- assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
- cbMessage.getServiceCategory());
- assertEquals(1234, cbMessage.getSerialNumber());
- assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
- assertEquals("en", cbMessage.getLanguageCode());
- assertEquals(null, cbMessage.getMessageBody());
- assertEquals(true, cbMessage.isEmergencyMessage());
- assertEquals(true, cbMessage.isCmasMessage());
- SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
- assertEquals(SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, cmasInfo.getMessageClass());
- assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
- assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
- assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity());
- assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency());
- assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty());
- }
-
- // Make sure we don't throw an exception if we feed completely random data to BearerStream.
- public void testRandomBearerStreamData() {
- Random r = new Random(54321);
- for (int run = 0; run < 1000; run++) {
- int len = r.nextInt(140);
- byte[] data = new byte[len];
- for (int i = 0; i < len; i++) {
- data[i] = (byte) r.nextInt(256);
- }
- // Log.d("CdmaSmsCbTest", "trying random bearer data run " + run + " length " + len);
- try {
- int category = 0x0ff0 + r.nextInt(32); // half CMAS, half non-CMAS
- Parcel p = createBroadcastParcel(category);
- SmsMessage msg = createMessageFromParcel(p, data);
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- // with random input, cbMessage will almost always be null (log when it isn't)
- if (cbMessage != null) {
- Log.d("CdmaSmsCbTest", "success: " + cbMessage);
- }
- } catch (Exception e) {
- Log.d("CdmaSmsCbTest", "exception thrown", e);
- fail("Exception in decoder at run " + run + " length " + len + ": " + e);
- }
- }
- }
-
- // Make sure we don't throw an exception if we put random data in the UserData subparam.
- public void testRandomUserData() {
- Random r = new Random(94040);
- for (int run = 0; run < 1000; run++) {
- int category = 0x0ff0 + r.nextInt(32); // half CMAS, half non-CMAS
- Parcel p = createBroadcastParcel(category);
- int len = r.nextInt(140);
- // Log.d("CdmaSmsCbTest", "trying random user data run " + run + " length " + len);
-
- try {
- BitwiseOutputStream bos = createBearerDataStream(r.nextInt(65536), r.nextInt(4),
- r.nextInt(256));
-
- bos.write(8, SUBPARAM_USER_DATA);
- bos.write(8, len);
-
- for (int i = 0; i < len; i++) {
- bos.write(8, r.nextInt(256));
- }
-
- SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- } catch (Exception e) {
- Log.d("CdmaSmsCbTest", "exception thrown", e);
- fail("Exception in decoder at run " + run + " length " + len + ": " + e);
- }
- }
- }
-
- /**
- * Initialize a Parcel for incoming Service Category Program Data teleservice. The caller will
- * write the bearer data and then convert it to an SmsMessage.
- * @return the initialized Parcel
- */
- private static Parcel createServiceCategoryProgramDataParcel() {
- Parcel p = Parcel.obtain();
-
- p.writeInt(SmsEnvelope.TELESERVICE_SCPT);
- p.writeByte((byte) 0); // non-zero for MESSAGE_TYPE_BROADCAST
- p.writeInt(0);
-
- // dummy address (RIL may generate a different dummy address for broadcasts)
- p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); // sAddress.digit_mode
- p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); // sAddress.number_mode
- p.writeInt(CdmaSmsAddress.TON_UNKNOWN); // sAddress.number_type
- p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY); // sAddress.number_plan
- p.writeByte((byte) 0); // sAddress.number_of_digits
- p.writeInt((byte) 0); // sSubAddress.subaddressType
- p.writeByte((byte) 0); // sSubAddress.odd
- p.writeByte((byte) 0); // sSubAddress.number_of_digits
- return p;
- }
-
- private static final String CAT_EXTREME_THREAT = "Extreme Threat to Life and Property";
- private static final String CAT_SEVERE_THREAT = "Severe Threat to Life and Property";
- private static final String CAT_AMBER_ALERTS = "AMBER Alerts";
-
- public void testServiceCategoryProgramDataAddCategory() throws Exception {
- Parcel p = createServiceCategoryProgramDataParcel();
- BitwiseOutputStream bos = createBearerDataStream(123, -1, -1);
-
- int categoryNameLength = CAT_EXTREME_THREAT.length();
- int subparamLengthBits = (53 + (categoryNameLength * 7));
- int subparamLengthBytes = (subparamLengthBits + 7) / 8;
- int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits;
-
- bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA);
- bos.write(8, subparamLengthBytes);
- bos.write(5, UserData.ENCODING_7BIT_ASCII);
-
- bos.write(4, CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY);
- bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT >>> 8));
- bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT & 0xff));
- bos.write(8, BearerData.LANGUAGE_ENGLISH);
- bos.write(8, 100); // max messages
- bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT);
-
- bos.write(8, categoryNameLength);
- for (int i = 0; i < categoryNameLength; i++) {
- bos.write(7, CAT_EXTREME_THREAT.charAt(i));
- }
- bos.write(subparamPadBits, 0);
-
- SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
- assertNotNull(msg);
- msg.parseSms();
- List<CdmaSmsCbProgramData> programDataList = msg.getSmsCbProgramData();
- assertNotNull(programDataList);
- assertEquals(1, programDataList.size());
- CdmaSmsCbProgramData programData = programDataList.get(0);
- assertEquals(CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY, programData.getOperation());
- assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, programData.getCategory());
- assertEquals(CAT_EXTREME_THREAT, programData.getCategoryName());
- assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
- assertEquals(100, programData.getMaxMessages());
- assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT, programData.getAlertOption());
- }
-
- public void testServiceCategoryProgramDataDeleteTwoCategories() throws Exception {
- Parcel p = createServiceCategoryProgramDataParcel();
- BitwiseOutputStream bos = createBearerDataStream(456, -1, -1);
-
- int category1NameLength = CAT_SEVERE_THREAT.length();
- int category2NameLength = CAT_AMBER_ALERTS.length();
-
- int subparamLengthBits = (101 + (category1NameLength * 7) + (category2NameLength * 7));
- int subparamLengthBytes = (subparamLengthBits + 7) / 8;
- int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits;
-
- bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA);
- bos.write(8, subparamLengthBytes);
- bos.write(5, UserData.ENCODING_7BIT_ASCII);
-
- bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY);
- bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT >>> 8));
- bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT & 0xff));
- bos.write(8, BearerData.LANGUAGE_ENGLISH);
- bos.write(8, 0); // max messages
- bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT);
-
- bos.write(8, category1NameLength);
- for (int i = 0; i < category1NameLength; i++) {
- bos.write(7, CAT_SEVERE_THREAT.charAt(i));
- }
-
- bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY);
- bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY >>> 8));
- bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY & 0xff));
- bos.write(8, BearerData.LANGUAGE_ENGLISH);
- bos.write(8, 0); // max messages
- bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT);
-
- bos.write(8, category2NameLength);
- for (int i = 0; i < category2NameLength; i++) {
- bos.write(7, CAT_AMBER_ALERTS.charAt(i));
- }
-
- bos.write(subparamPadBits, 0);
-
- SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
- assertNotNull(msg);
- msg.parseSms();
- List<CdmaSmsCbProgramData> programDataList = msg.getSmsCbProgramData();
- assertNotNull(programDataList);
- assertEquals(2, programDataList.size());
-
- CdmaSmsCbProgramData programData = programDataList.get(0);
- assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation());
- assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, programData.getCategory());
- assertEquals(CAT_SEVERE_THREAT, programData.getCategoryName());
- assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
- assertEquals(0, programData.getMaxMessages());
- assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption());
-
- programData = programDataList.get(1);
- assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation());
- assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
- programData.getCategory());
- assertEquals(CAT_AMBER_ALERTS, programData.getCategoryName());
- assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
- assertEquals(0, programData.getMaxMessages());
- assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption());
- }
-
- private static final byte[] CMAS_TEST_BEARER_DATA = {
- 0x00, 0x03, 0x1C, 0x78, 0x00, 0x01, 0x59, 0x02, (byte) 0xB8, 0x00, 0x02, 0x10, (byte) 0xAA,
- 0x68, (byte) 0xD3, (byte) 0xCD, 0x06, (byte) 0x9E, 0x68, 0x30, (byte) 0xA0, (byte) 0xE9,
- (byte) 0x97, (byte) 0x9F, 0x44, 0x1B, (byte) 0xF3, 0x20, (byte) 0xE9, (byte) 0xA3,
- 0x2A, 0x08, 0x7B, (byte) 0xF6, (byte) 0xED, (byte) 0xCB, (byte) 0xCB, 0x1E, (byte) 0x9C,
- 0x3B, 0x10, 0x4D, (byte) 0xDF, (byte) 0x8B, 0x4E,
- (byte) 0xCC, (byte) 0xA8, 0x20, (byte) 0xEC, (byte) 0xCB, (byte) 0xCB, (byte) 0xA2, 0x0A,
- 0x7E, 0x79, (byte) 0xF4, (byte) 0xCB, (byte) 0xB5, 0x72, 0x0A, (byte) 0x9A, 0x34,
- (byte) 0xF3, 0x41, (byte) 0xA7, (byte) 0x9A, 0x0D, (byte) 0xFB, (byte) 0xB6, 0x79, 0x41,
- (byte) 0x85, 0x07, 0x4C, (byte) 0xBC, (byte) 0xFA, 0x2E, 0x00, 0x08, 0x20, 0x58, 0x38,
- (byte) 0x88, (byte) 0x80, 0x10, 0x54, 0x06, 0x38, 0x20, 0x60,
- 0x30, (byte) 0xA8, (byte) 0x81, (byte) 0x90, 0x20, 0x08
- };
-
- // Test case for CMAS test message received on the Sprint network.
- public void testDecodeRawBearerData() throws Exception {
- Parcel p = createBroadcastParcel(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
- SmsMessage msg = createMessageFromParcel(p, CMAS_TEST_BEARER_DATA);
-
- SmsCbMessage cbMessage = msg.parseBroadcastSms();
- assertNotNull("expected non-null for bearer data", cbMessage);
- assertEquals("geoScope", cbMessage.getGeographicalScope(), 1);
- assertEquals("serialNumber", cbMessage.getSerialNumber(), 51072);
- assertEquals("serviceCategory", cbMessage.getServiceCategory(),
- SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
- assertEquals("payload", cbMessage.getMessageBody(),
- "This is a test of the Commercial Mobile Alert System. This is only a test.");
-
- SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
- assertNotNull("expected non-null for CMAS info", cmasInfo);
- assertEquals("category", cmasInfo.getCategory(), SmsCbCmasInfo.CMAS_CATEGORY_OTHER);
- assertEquals("responseType", cmasInfo.getResponseType(),
- SmsCbCmasInfo.CMAS_RESPONSE_TYPE_NONE);
- assertEquals("severity", cmasInfo.getSeverity(), SmsCbCmasInfo.CMAS_SEVERITY_SEVERE);
- assertEquals("urgency", cmasInfo.getUrgency(), SmsCbCmasInfo.CMAS_URGENCY_EXPECTED);
- assertEquals("certainty", cmasInfo.getCertainty(), SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
deleted file mode 100644
index f1bc268..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/cdma/sms/CdmaSmsTest.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * 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.cdma.sms;
-
-import android.telephony.TelephonyManager;
-
-import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.cdma.SmsMessage;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.UserData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
-import com.android.internal.util.BitwiseInputStream;
-import com.android.internal.util.BitwiseOutputStream;
-import com.android.internal.util.HexDump;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class CdmaSmsTest extends AndroidTestCase {
- private final static String LOG_TAG = "XXX CdmaSmsTest XXX";
-
- // CJK ideographs, Hiragana, Katakana, full width letters, Cyrillic, etc.
- private static final String sUnicodeChars = "\u4e00\u4e01\u4e02\u4e03" +
- "\u4e04\u4e05\u4e06\u4e07\u4e08\u4e09\u4e0a\u4e0b\u4e0c\u4e0d" +
- "\u4e0e\u4e0f\u3041\u3042\u3043\u3044\u3045\u3046\u3047\u3048" +
- "\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8" +
- "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18" +
- "\uff70\uff71\uff72\uff73\uff74\uff75\uff76\uff77\uff78" +
- "\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408" +
- "\u00a2\u00a9\u00ae\u2122";
-
- @SmallTest
- public void testCdmaSmsAddrParsing() throws Exception {
- CdmaSmsAddress addr = CdmaSmsAddress.parse("6502531000");
- assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN);
- assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
- assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
- assertEquals(addr.numberOfDigits, 10);
- assertEquals(addr.origBytes.length, 10);
- byte[] data = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10};
- for (int i = 0; i < data.length; i++) {
- assertEquals(addr.origBytes[i], data[i]);
- }
- addr = CdmaSmsAddress.parse("(650) 253-1000");
- assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN);
- assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
- assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
- assertEquals(addr.numberOfDigits, 10);
- assertEquals(addr.origBytes.length, 10);
- byte[] data2 = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10};
- for (int i = 0; i < data2.length; i++) {
- assertEquals(addr.origBytes[i], data2[i]);
- }
- addr = CdmaSmsAddress.parse("650.253.1000");
- assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN);
- assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
- assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
- assertEquals(addr.numberOfDigits, 10);
- assertEquals(addr.origBytes.length, 10);
- byte[] data5 = {6, 5, 10, 2, 5, 3, 1, 10, 10, 10};
- for (int i = 0; i < data2.length; i++) {
- assertEquals(addr.origBytes[i], data5[i]);
- }
- addr = CdmaSmsAddress.parse("(+886) 917 222 555");
- assertEquals(addr.ton, CdmaSmsAddress.TON_INTERNATIONAL_OR_IP);
- assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
- assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
- assertEquals(addr.numberOfDigits, 12);
- assertEquals(addr.origBytes.length, 12);
- byte[] data3 = {8, 8, 6, 9, 1, 7, 2, 2, 2, 5, 5, 5};
- for (int i = 0; i < data3.length; i++) {
- assertEquals(addr.origBytes[i], data3[i]);
- }
- addr = CdmaSmsAddress.parse("(650) *253-1000 #600");
- byte[] data4 = {6, 5, 10, 11, 2, 5, 3, 1, 10, 10, 10, 12, 6, 10, 10};
- for (int i = 0; i < data4.length; i++) {
- assertEquals(addr.origBytes[i], data4[i]);
- }
- String input = "x@y.com,a@b.com";
- addr = CdmaSmsAddress.parse(input);
- assertEquals(addr.ton, CdmaSmsAddress.TON_NATIONAL_OR_EMAIL);
- assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR);
- assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK);
- assertEquals(addr.numberOfDigits, 15);
- assertEquals(addr.origBytes.length, 15);
- assertEquals(new String(addr.origBytes), input);
- addr = CdmaSmsAddress.parse("foo bar");
- assertEquals(addr.ton, CdmaSmsAddress.TON_UNKNOWN);
- assertEquals(addr.digitMode, CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR);
- assertEquals(addr.numberMode, CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK);
- assertEquals(addr.numberOfDigits, 6);
- assertEquals(addr.origBytes.length, 6);
- assertEquals(new String(addr.origBytes), "foobar");
- addr = CdmaSmsAddress.parse("f\noo\tb a\rr");
- assertEquals(new String(addr.origBytes), "foobar");
- assertEquals(CdmaSmsAddress.parse("f\u0000oo bar"), null);
- assertEquals(CdmaSmsAddress.parse("f\u0007oo bar"), null);
- assertEquals(CdmaSmsAddress.parse("f\u0080oo bar"), null);
- assertEquals(CdmaSmsAddress.parse("f\u1ECFboo\u001fbar"), null);
- assertEquals(CdmaSmsAddress.parse("f\u0080oo bar"), null);
- }
-
- @SmallTest
- public void testUserData7bitGsm() throws Exception {
- String pdu = "00031040900112488ea794e074d69e1b7392c270326cde9e98";
- BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
- assertEquals("Test standard SMS", bearerData.userData.payloadStr);
- }
-
- @SmallTest
- public void testUserData7bitAscii() throws Exception {
- String pdu = "0003100160010610262d5ab500";
- BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
- assertEquals("bjjj", bearerData.userData.payloadStr);
- }
-
- @SmallTest
- public void testUserData7bitAsciiTwo() throws Exception {
- String pdu = "00031001d00109104539b4d052ebb3d0";
- BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
- assertEquals("SMS Rulz", bearerData.userData.payloadStr);
- }
-
- @SmallTest
- public void testUserDataIa5() throws Exception {
- String pdu = "00031002100109184539b4d052ebb3d0";
- BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
- assertEquals("SMS Rulz", bearerData.userData.payloadStr);
- }
-
- @SmallTest
- public void testUserData7bitAsciiFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "Test standard SMS";
- userData.msgEncoding = UserData.ENCODING_7BIT_ASCII;
- userData.msgEncodingSet = true;
- bearerData.userData = userData;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
- assertEquals(0, revBearerData.messageId);
- assertEquals(false, revBearerData.hasUserDataHeader);
- assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding);
- assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields);
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.payloadStr = "Test \u007f standard \u0000 SMS";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals("Test standard SMS", revBearerData.userData.payloadStr);
- userData.payloadStr = "Test \n standard \r SMS";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.payloadStr = "";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- }
-
- @SmallTest
- public void testUserData7bitGsmFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "Test standard SMS";
- userData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
- userData.msgEncodingSet = true;
- bearerData.userData = userData;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
- assertEquals(0, revBearerData.messageId);
- assertEquals(false, revBearerData.hasUserDataHeader);
- assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding);
- assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields);
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.payloadStr = "1234567";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.payloadStr = "";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.payloadStr = "12345678901234567890123456789012345678901234567890" +
- "12345678901234567890123456789012345678901234567890" +
- "12345678901234567890123456789012345678901234567890" +
- "1234567890";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.payloadStr = "Test \u007f illegal \u0000 SMS chars";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals("Test illegal SMS chars", revBearerData.userData.payloadStr);
- userData.payloadStr = "More @ testing\nis great^|^~woohoo";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
- concatRef.refNumber = 0xEE;
- concatRef.msgCount = 2;
- concatRef.seqNumber = 2;
- concatRef.isEightBits = true;
- SmsHeader smsHeader = new SmsHeader();
- smsHeader.concatRef = concatRef;
- byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
- userData.userDataHeader = smsHeader;
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- SmsHeader decodedHeader = revBearerData.userData.userDataHeader;
- assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
- assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
- assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
- }
-
- @SmallTest
- public void testUserDataUtf16Feedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "\u0160u\u1E5B\u0301r\u1ECFg\uD835\uDC1At\u00E9\u4E002\u3042";
- userData.msgEncoding = UserData.ENCODING_UNICODE_16;
- userData.msgEncodingSet = true;
- bearerData.userData = userData;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
- assertEquals(0, revBearerData.messageId);
- assertEquals(false, revBearerData.hasUserDataHeader);
- assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding);
- assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields);
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.msgEncoding = UserData.ENCODING_OCTET;
- userData.msgEncodingSet = false;
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(BearerData.MESSAGE_TYPE_DELIVER, revBearerData.messageType);
- assertEquals(0, revBearerData.messageId);
- assertEquals(false, revBearerData.hasUserDataHeader);
- assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding);
- assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields);
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.payloadStr = "1234567";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- userData.payloadStr = "";
- revBearerData = BearerData.decode(BearerData.encode(bearerData));
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- }
-
- @SmallTest
- public void testMonolithicOne() throws Exception {
- String pdu = "0003200010010410168d2002010503060812011101590501c706069706180000000701c108" +
- "01c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566";
- BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
- assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT);
- assertEquals(bearerData.messageId, 1);
- assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY);
- assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL);
- assertEquals(bearerData.userAckReq, true);
- assertEquals(bearerData.readAckReq, true);
- assertEquals(bearerData.deliveryAckReq, true);
- assertEquals(bearerData.reportReq, false);
- assertEquals(bearerData.numberOfMessages, 3);
- assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO);
- assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW);
- assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
- assertEquals(bearerData.callbackNumber.numberMode,
- CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
- assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN);
- assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN);
- assertEquals(bearerData.callbackNumber.numberOfDigits, 7);
- assertEquals(bearerData.callbackNumber.address, "3598271");
- assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER);
- assertEquals(bearerData.depositIndex, 1382);
- assertEquals(bearerData.userResponseCode, 5);
- assertEquals(bearerData.msgCenterTimeStamp.year, 2008);
- assertEquals(bearerData.msgCenterTimeStamp.month, 11);
- assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1);
- assertEquals(bearerData.msgCenterTimeStamp.hour, 11);
- assertEquals(bearerData.msgCenterTimeStamp.minute, 1);
- assertEquals(bearerData.msgCenterTimeStamp.second, 59);
- assertEquals(bearerData.validityPeriodAbsolute, null);
- assertEquals(bearerData.validityPeriodRelative, 193);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
- assertEquals(bearerData.deferredDeliveryTimeRelative, 199);
- assertEquals(bearerData.hasUserDataHeader, false);
- assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
- assertEquals(bearerData.userData.numFields, 2);
- assertEquals(bearerData.userData.payloadStr, "hi");
- }
-
- @SmallTest
- public void testMonolithicTwo() throws Exception {
- String pdu = "0003200010010410168d200201050306081201110159050192060697061800000007013d0" +
- "801c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566";
- BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu));
- assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT);
- assertEquals(bearerData.messageId, 1);
- assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY);
- assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL);
- assertEquals(bearerData.userAckReq, true);
- assertEquals(bearerData.readAckReq, true);
- assertEquals(bearerData.deliveryAckReq, true);
- assertEquals(bearerData.reportReq, false);
- assertEquals(bearerData.numberOfMessages, 3);
- assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO);
- assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW);
- assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);
- assertEquals(bearerData.callbackNumber.numberMode,
- CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);
- assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN);
- assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN);
- assertEquals(bearerData.callbackNumber.numberOfDigits, 7);
- assertEquals(bearerData.callbackNumber.address, "3598271");
- assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER);
- assertEquals(bearerData.depositIndex, 1382);
- assertEquals(bearerData.userResponseCode, 5);
- assertEquals(bearerData.msgCenterTimeStamp.year, 2008);
- assertEquals(bearerData.msgCenterTimeStamp.month, 11);
- assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1);
- assertEquals(bearerData.msgCenterTimeStamp.hour, 11);
- assertEquals(bearerData.msgCenterTimeStamp.minute, 1);
- assertEquals(bearerData.msgCenterTimeStamp.second, 59);
- assertEquals(bearerData.validityPeriodAbsolute, null);
- assertEquals(bearerData.validityPeriodRelative, 61);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0);
- assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0);
- assertEquals(bearerData.deferredDeliveryTimeRelative, 146);
- assertEquals(bearerData.hasUserDataHeader, false);
- assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII);
- assertEquals(bearerData.userData.numFields, 2);
- assertEquals(bearerData.userData.payloadStr, "hi");
- }
-
- @SmallTest
- public void testUserDataHeaderConcatRefFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 55;
- SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
- concatRef.refNumber = 0xEE;
- concatRef.msgCount = 2;
- concatRef.seqNumber = 2;
- concatRef.isEightBits = true;
- SmsHeader smsHeader = new SmsHeader();
- smsHeader.concatRef = concatRef;
- byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
- SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader);
- assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
- assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
- assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
- assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits);
- assertEquals(decodedHeader.portAddrs, null);
- UserData userData = new UserData();
- userData.payloadStr = "User Data Header (UDH) feedback test";
- userData.userDataHeader = smsHeader;
- bearerData.userData = userData;
- byte[] encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- decodedHeader = revBearerData.userData.userDataHeader;
- assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
- assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
- assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
- assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits);
- assertEquals(decodedHeader.portAddrs, null);
- }
-
- @SmallTest
- public void testUserDataHeaderIllegalConcatRef() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 55;
- SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
- concatRef.refNumber = 0x10;
- concatRef.msgCount = 0;
- concatRef.seqNumber = 2;
- concatRef.isEightBits = true;
- SmsHeader smsHeader = new SmsHeader();
- smsHeader.concatRef = concatRef;
- byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
- SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader);
- assertEquals(decodedHeader.concatRef, null);
- concatRef.isEightBits = false;
- encodedHeader = SmsHeader.toByteArray(smsHeader);
- decodedHeader = SmsHeader.fromByteArray(encodedHeader);
- assertEquals(decodedHeader.concatRef, null);
- concatRef.msgCount = 1;
- concatRef.seqNumber = 2;
- encodedHeader = SmsHeader.toByteArray(smsHeader);
- decodedHeader = SmsHeader.fromByteArray(encodedHeader);
- assertEquals(decodedHeader.concatRef, null);
- concatRef.msgCount = 1;
- concatRef.seqNumber = 0;
- encodedHeader = SmsHeader.toByteArray(smsHeader);
- decodedHeader = SmsHeader.fromByteArray(encodedHeader);
- assertEquals(decodedHeader.concatRef, null);
- concatRef.msgCount = 2;
- concatRef.seqNumber = 1;
- encodedHeader = SmsHeader.toByteArray(smsHeader);
- decodedHeader = SmsHeader.fromByteArray(encodedHeader);
- assertEquals(decodedHeader.concatRef.msgCount, 2);
- assertEquals(decodedHeader.concatRef.seqNumber, 1);
- }
-
- @SmallTest
- public void testUserDataHeaderMixedFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 42;
- SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
- concatRef.refNumber = 0x34;
- concatRef.msgCount = 5;
- concatRef.seqNumber = 2;
- concatRef.isEightBits = false;
- SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
- portAddrs.destPort = 88;
- portAddrs.origPort = 66;
- portAddrs.areEightBits = false;
- SmsHeader smsHeader = new SmsHeader();
- smsHeader.concatRef = concatRef;
- smsHeader.portAddrs = portAddrs;
- byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
- SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader);
- assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
- assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
- assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
- assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits);
- assertEquals(decodedHeader.portAddrs.destPort, portAddrs.destPort);
- assertEquals(decodedHeader.portAddrs.origPort, portAddrs.origPort);
- assertEquals(decodedHeader.portAddrs.areEightBits, portAddrs.areEightBits);
- UserData userData = new UserData();
- userData.payloadStr = "User Data Header (UDH) feedback test";
- userData.userDataHeader = smsHeader;
- bearerData.userData = userData;
- byte[] encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- decodedHeader = revBearerData.userData.userDataHeader;
- assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
- assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
- assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
- assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits);
- assertEquals(decodedHeader.portAddrs.destPort, portAddrs.destPort);
- assertEquals(decodedHeader.portAddrs.origPort, portAddrs.origPort);
- assertEquals(decodedHeader.portAddrs.areEightBits, portAddrs.areEightBits);
- }
-
- @SmallTest
- public void testReplyOption() throws Exception {
- String pdu1 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87450080a0180";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals("Test Acknowledgement 1", bd1.userData.payloadStr);
- assertEquals(true, bd1.userAckReq);
- assertEquals(false, bd1.deliveryAckReq);
- assertEquals(false, bd1.readAckReq);
- assertEquals(false, bd1.reportReq);
- String pdu2 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87490080a0140";
- BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
- assertEquals("Test Acknowledgement 2", bd2.userData.payloadStr);
- assertEquals(false, bd2.userAckReq);
- assertEquals(true, bd2.deliveryAckReq);
- assertEquals(false, bd2.readAckReq);
- assertEquals(false, bd2.reportReq);
- String pdu3 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d874d0080a0120";
- BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
- assertEquals("Test Acknowledgement 3", bd3.userData.payloadStr);
- assertEquals(false, bd3.userAckReq);
- assertEquals(false, bd3.deliveryAckReq);
- assertEquals(true, bd3.readAckReq);
- assertEquals(false, bd3.reportReq);
- String pdu4 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87510080a0110";
- BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
- assertEquals("Test Acknowledgement 4", bd4.userData.payloadStr);
- assertEquals(false, bd4.userAckReq);
- assertEquals(false, bd4.deliveryAckReq);
- assertEquals(false, bd4.readAckReq);
- assertEquals(true, bd4.reportReq);
- }
-
- @SmallTest
- public void testReplyOptionFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "test reply option";
- bearerData.userData = userData;
- bearerData.userAckReq = true;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(true, revBearerData.userAckReq);
- assertEquals(false, revBearerData.deliveryAckReq);
- assertEquals(false, revBearerData.readAckReq);
- assertEquals(false, revBearerData.reportReq);
- bearerData.userAckReq = false;
- bearerData.deliveryAckReq = true;
- encodedSms = BearerData.encode(bearerData);
- revBearerData = BearerData.decode(encodedSms);
- assertEquals(false, revBearerData.userAckReq);
- assertEquals(true, revBearerData.deliveryAckReq);
- assertEquals(false, revBearerData.readAckReq);
- assertEquals(false, revBearerData.reportReq);
- bearerData.deliveryAckReq = false;
- bearerData.readAckReq = true;
- encodedSms = BearerData.encode(bearerData);
- revBearerData = BearerData.decode(encodedSms);
- assertEquals(false, revBearerData.userAckReq);
- assertEquals(false, revBearerData.deliveryAckReq);
- assertEquals(true, revBearerData.readAckReq);
- assertEquals(false, revBearerData.reportReq);
- bearerData.readAckReq = false;
- bearerData.reportReq = true;
- encodedSms = BearerData.encode(bearerData);
- revBearerData = BearerData.decode(encodedSms);
- assertEquals(false, revBearerData.userAckReq);
- assertEquals(false, revBearerData.deliveryAckReq);
- assertEquals(false, revBearerData.readAckReq);
- assertEquals(true, revBearerData.reportReq);
- }
-
- @SmallTest
- public void testNumberOfMessages() throws Exception {
- // Note that the message text below does not properly reflect
- // the message count. The author of these messages was
- // apparently unaware that the values are bcd encoded, and the
- // values being tested against (not the ones in the message
- // text) are actually correct.
- String pdu1 = "000310409001124896a794e07595f69f199540ea759a0dc8e00b0163";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals("Test Voice mail 99", bd1.userData.payloadStr);
- assertEquals(63, bd1.numberOfMessages);
- String pdu2 = "00031040900113489ea794e07595f69f199540ea759a0988c0600b0164";
- BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
- assertEquals("Test Voice mail 100", bd2.userData.payloadStr);
- assertEquals(64, bd2.numberOfMessages);
- }
-
- @SmallTest
- public void testCallbackNum() throws Exception {
- String pdu1 = "00031040900112488ea794e070d436cb638bc5e035ce2f97900e06910431323334";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals("Test Callback nbr", bd1.userData.payloadStr);
- assertEquals(CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR, bd1.callbackNumber.digitMode);
- assertEquals(CdmaSmsAddress.TON_INTERNATIONAL_OR_IP, bd1.callbackNumber.ton);
- assertEquals(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK, bd1.callbackNumber.numberMode);
- assertEquals(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY, bd1.callbackNumber.numberPlan);
- assertEquals("1234", bd1.callbackNumber.address);
- }
-
- @SmallTest
- public void testCallbackNumDtmf() throws Exception {
- String pdu1 = "00031002300109104539b4d052ebb3d00e07052d4c90a55080";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals("SMS Rulz", bd1.userData.payloadStr);
- assertEquals(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF, bd1.callbackNumber.digitMode);
- assertEquals(CdmaSmsAddress.TON_UNKNOWN, bd1.callbackNumber.ton);
- assertEquals(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK, bd1.callbackNumber.numberMode);
- assertEquals(CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN, bd1.callbackNumber.numberPlan);
- assertEquals("5099214001", bd1.callbackNumber.address);
- }
-
- @SmallTest
- public void testCallbackNumFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "test callback number";
- bearerData.userData = userData;
- CdmaSmsAddress addr = new CdmaSmsAddress();
- addr.digitMode = CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR;
- addr.ton = CdmaSmsAddress.TON_NATIONAL_OR_EMAIL;
- addr.numberMode = CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK;
- addr.numberPlan = CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN;
- addr.address = "8005551212";
- addr.numberOfDigits = (byte)addr.address.length();
- bearerData.callbackNumber = addr;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- CdmaSmsAddress revAddr = revBearerData.callbackNumber;
- assertEquals(addr.digitMode, revAddr.digitMode);
- assertEquals(addr.ton, revAddr.ton);
- assertEquals(addr.numberMode, revAddr.numberMode);
- assertEquals(addr.numberPlan, revAddr.numberPlan);
- assertEquals(addr.numberOfDigits, revAddr.numberOfDigits);
- assertEquals(addr.address, revAddr.address);
- addr.address = "8*55#1012";
- addr.numberOfDigits = (byte)addr.address.length();
- addr.digitMode = CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF;
- encodedSms = BearerData.encode(bearerData);
- revBearerData = BearerData.decode(encodedSms);
- revAddr = revBearerData.callbackNumber;
- assertEquals(addr.digitMode, revAddr.digitMode);
- assertEquals(addr.numberOfDigits, revAddr.numberOfDigits);
- assertEquals(addr.address, revAddr.address);
- }
-
- @SmallTest
- public void testPrivacyIndicator() throws Exception {
- String pdu1 = "0003104090010c485f4194dfea34becf61b840090140";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals(bd1.privacy, BearerData.PRIVACY_RESTRICTED);
- String pdu2 = "0003104090010c485f4194dfea34becf61b840090180";
- BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
- assertEquals(bd2.privacy, BearerData.PRIVACY_CONFIDENTIAL);
- String pdu3 = "0003104090010c485f4194dfea34becf61b8400901c0";
- BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
- assertEquals(bd3.privacy, BearerData.PRIVACY_SECRET);
- }
-
- @SmallTest
- public void testPrivacyIndicatorFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "test privacy indicator";
- bearerData.userData = userData;
- bearerData.privacy = BearerData.PRIVACY_SECRET;
- bearerData.privacyIndicatorSet = true;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
- assertEquals(revBearerData.privacyIndicatorSet, true);
- assertEquals(revBearerData.privacy, BearerData.PRIVACY_SECRET);
- bearerData.privacy = BearerData.PRIVACY_RESTRICTED;
- encodedSms = BearerData.encode(bearerData);
- revBearerData = BearerData.decode(encodedSms);
- assertEquals(revBearerData.privacy, BearerData.PRIVACY_RESTRICTED);
- }
-
- @SmallTest
- public void testMsgDeliveryAlert() throws Exception {
- String pdu1 = "0003104090010d4866a794e07055965b91d040300c0100";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals(bd1.alert, 0);
- assertEquals(bd1.userData.payloadStr, "Test Alert 0");
- String pdu2 = "0003104090010d4866a794e07055965b91d140300c0140";
- BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
- assertEquals(bd2.alert, 1);
- assertEquals(bd2.userData.payloadStr, "Test Alert 1");
- String pdu3 = "0003104090010d4866a794e07055965b91d240300c0180";
- BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
- assertEquals(bd3.alert, 2);
- assertEquals(bd3.userData.payloadStr, "Test Alert 2");
- String pdu4 = "0003104090010d4866a794e07055965b91d340300c01c0";
- BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
- assertEquals(bd4.alert, 3);
- assertEquals(bd4.userData.payloadStr, "Test Alert 3");
- String pdu5 = "00031000000126114F4CBCFA20DB979F3C39F2A0C9976" +
- "69ED979794187665E5D1028EFA7A6840E1062D3D39A900C028000";
- BearerData bd5 = BearerData.decode(HexDump.hexStringToByteArray(pdu5));
- assertEquals(bd5.alert, BearerData.ALERT_MEDIUM_PRIO);
- assertEquals(bd5.userData.payloadStr, "test message delivery alert (with 8 bits)");
- String pdu6 = "00031000000126114F4CBCFA20DB979F3C39F2A0C9976" +
- "69ED979794187665E5D1028EFA7A6840C1062D3D39A900C00";
- BearerData bd6 = BearerData.decode(HexDump.hexStringToByteArray(pdu6));
- assertEquals(bd6.userData.payloadStr, "test message delivery alert (with 0 bits)");
- assertEquals(bd6.alertIndicatorSet, false);
- }
-
- @SmallTest
- public void testMiscParams() throws Exception {
- String pdu1 = "00031002400109104539b4d052ebb3d00c0180";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals(bd1.alert, BearerData.ALERT_MEDIUM_PRIO);
- assertEquals(bd1.userData.payloadStr, "SMS Rulz");
- String pdu2 = "00031002500109104539b4d052ebb3d00801800901c0";
- BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
- assertEquals(bd2.priority, BearerData.PRIORITY_URGENT);
- assertEquals(bd2.privacy, BearerData.PRIVACY_SECRET);
- assertEquals(bd2.userData.payloadStr, "SMS Rulz");
- String pdu3 = "00031002600109104539b4d052ebb3d00901400c01c0";
- BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
- assertEquals(bd3.privacy, BearerData.PRIVACY_RESTRICTED);
- assertEquals(bd3.alert, BearerData.ALERT_HIGH_PRIO);
- assertEquals(bd3.userData.payloadStr, "SMS Rulz");
- String pdu4 = "00031002700109104539b4d052ebb3d00f0105";
- BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
- assertEquals(bd4.displayMode, BearerData.DISPLAY_MODE_IMMEDIATE);
- assertEquals(bd4.userData.payloadStr, "SMS Rulz");
- }
- @SmallTest
- public void testMsgDeliveryAlertFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "test message delivery alert";
- bearerData.userData = userData;
- bearerData.alert = BearerData.ALERT_MEDIUM_PRIO;
- bearerData.alertIndicatorSet = true;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
- assertEquals(revBearerData.alertIndicatorSet, true);
- assertEquals(revBearerData.alert, bearerData.alert);
- bearerData.alert = BearerData.ALERT_HIGH_PRIO;
- encodedSms = BearerData.encode(bearerData);
- revBearerData = BearerData.decode(encodedSms);
- assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
- assertEquals(revBearerData.alertIndicatorSet, true);
- assertEquals(revBearerData.alert, bearerData.alert);
- }
-
- @SmallTest
- public void testLanguageIndicator() throws Exception {
- String pdu1 = "0003104090011748bea794e0731436ef3bd7c2e0352eef27a1c263fe58080d0101";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals(bd1.userData.payloadStr, "Test Language indicator");
- assertEquals(bd1.language, BearerData.LANGUAGE_ENGLISH);
- String pdu2 = "0003104090011748bea794e0731436ef3bd7c2e0352eef27a1c263fe58080d0106";
- BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
- assertEquals(bd2.userData.payloadStr, "Test Language indicator");
- assertEquals(bd2.language, BearerData.LANGUAGE_CHINESE);
- }
-
- @SmallTest
- public void testLanguageIndicatorFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "test language indicator";
- bearerData.userData = userData;
- bearerData.language = BearerData.LANGUAGE_ENGLISH;
- bearerData.languageIndicatorSet = true;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
- assertEquals(revBearerData.languageIndicatorSet, true);
- assertEquals(revBearerData.language, bearerData.language);
- bearerData.language = BearerData.LANGUAGE_KOREAN;
- encodedSms = BearerData.encode(bearerData);
- revBearerData = BearerData.decode(encodedSms);
- assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
- assertEquals(revBearerData.languageIndicatorSet, true);
- assertEquals(revBearerData.language, bearerData.language);
- }
-
- @SmallTest
- public void testDisplayMode() throws Exception {
- String pdu1 = "0003104090010c485f4194dfea34becf61b8400f0100";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals(bd1.displayMode, BearerData.DISPLAY_MODE_IMMEDIATE);
- String pdu2 = "0003104090010c485f4194dfea34becf61b8400f0140";
- BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
- assertEquals(bd2.displayMode, BearerData.DISPLAY_MODE_DEFAULT);
- String pdu3 = "0003104090010c485f4194dfea34becf61b8400f0180";
- BearerData bd3 = BearerData.decode(HexDump.hexStringToByteArray(pdu3));
- assertEquals(bd3.displayMode, BearerData.DISPLAY_MODE_USER);
- }
-
- @SmallTest
- public void testDisplayModeFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "test display mode";
- bearerData.userData = userData;
- bearerData.displayMode = BearerData.DISPLAY_MODE_IMMEDIATE;
- bearerData.displayModeSet = true;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
- assertEquals(revBearerData.displayModeSet, true);
- assertEquals(revBearerData.displayMode, bearerData.displayMode);
- bearerData.displayMode = BearerData.DISPLAY_MODE_USER;
- encodedSms = BearerData.encode(bearerData);
- revBearerData = BearerData.decode(encodedSms);
- assertEquals(revBearerData.userData.payloadStr, userData.payloadStr);
- assertEquals(revBearerData.displayModeSet, true);
- assertEquals(revBearerData.displayMode, bearerData.displayMode);
- }
-
- @SmallTest
- public void testIs91() throws Exception {
- String pdu1 = "000320001001070c2039acc13880";
- BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- assertEquals(bd1.callbackNumber.address, "3598271");
- String pdu4 = "000320001001080c283c314724b34e";
- BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4));
- assertEquals(bd4.userData.payloadStr, "ABCDEFG");
- }
-
- @SmallTest
- public void testUserDataHeaderWithEightCharMsg() throws Exception {
- encodeDecodeAssertEquals("01234567", 2, 2, false);
- }
-
- private void encodeDecodeAssertEquals(String payload, int index, int total,
- boolean oddLengthHeader) throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 55;
- SmsHeader smsHeader = new SmsHeader();
- if (oddLengthHeader) {
- // Odd length header to verify correct UTF-16 header padding
- SmsHeader.MiscElt miscElt = new SmsHeader.MiscElt();
- miscElt.id = 0x27; // reserved for future use; ignored on decode
- miscElt.data = new byte[]{0x12, 0x34};
- smsHeader.miscEltList.add(miscElt);
- } else {
- // Even length header normally generated for concatenated SMS.
- SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
- concatRef.refNumber = 0xEE;
- concatRef.msgCount = total;
- concatRef.seqNumber = index;
- concatRef.isEightBits = true;
- smsHeader.concatRef = concatRef;
- }
- byte[] encodeHeader = SmsHeader.toByteArray(smsHeader);
- if (oddLengthHeader) {
- assertEquals(4, encodeHeader.length); // 5 bytes with UDH length
- } else {
- assertEquals(5, encodeHeader.length); // 6 bytes with UDH length
- }
- UserData userData = new UserData();
- userData.payloadStr = payload;
- userData.userDataHeader = smsHeader;
- bearerData.userData = userData;
- byte[] encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
- assertTrue(revBearerData.hasUserDataHeader);
- byte[] header = SmsHeader.toByteArray(revBearerData.userData.userDataHeader);
- if (oddLengthHeader) {
- assertEquals(4, header.length); // 5 bytes with UDH length
- } else {
- assertEquals(5, header.length); // 6 bytes with UDH length
- }
- assertTrue(Arrays.equals(encodeHeader, header));
- }
-
- @SmallTest
- public void testFragmentText() throws Exception {
- boolean isCdmaPhone = (TelephonyManager.getDefault().getPhoneType() ==
- TelephonyManager.PHONE_TYPE_CDMA);
- // Valid 160 character ASCII text.
- String text1 = "123456789012345678901234567890123456789012345678901234567890" +
- "1234567890123456789012345678901234567890123456789012345678901234567890" +
- "12345678901234567890123456789[";
- TextEncodingDetails ted = SmsMessage.calculateLength(text1, false);
- assertEquals(ted.msgCount, 1);
- assertEquals(ted.codeUnitCount, 160);
- assertEquals(ted.codeUnitSize, 1);
- if (isCdmaPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text1);
- assertEquals(fragments.size(), 1);
- }
-
- /*
- This is not a valid test: we will never encode a single-segment
- EMS message. Leaving this here, since we may try to support
- this in the future.
-
- // Valid 160 character GSM text -- the last character is
- // non-ASCII, and so this will currently generate a singleton
- // EMS message, which is not necessarily supported by Verizon.
- String text2 = "123456789012345678901234567890123456789012345678901234567890" +
- "1234567890123456789012345678901234567890123456789012345678901234567890" +
- "12345678901234567890123456789\u00a3"; // Trailing pound-currency sign.
- ted = SmsMessage.calculateLength(text2, false);
- assertEquals(ted.msgCount, 1);
- assertEquals(ted.codeUnitCount, 160);
- assertEquals(ted.codeUnitSize, 1);
- if (isCdmaPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text2);
- assertEquals(fragments.size(), 1);
- }
- */
-
- // *IF* we supported single-segment EMS, this text would result in a
- // single fragment with 7-bit encoding. But we don't, so this text
- // results in three fragments of 16-bit encoding.
- String text2 = "123456789012345678901234567890123456789012345678901234567890" +
- "1234567890123456789012345678901234567890123456789012345678901234567890" +
- "12345678901234567890123456789\u00a3"; // Trailing pound-currency sign.
- ted = SmsMessage.calculateLength(text2, false);
- assertEquals(3, ted.msgCount);
- assertEquals(160, ted.codeUnitCount);
- assertEquals(3, ted.codeUnitSize);
- if (isCdmaPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text2);
- assertEquals(3, fragments.size());
-
- for (int i = 0; i < 3; i++) {
- encodeDecodeAssertEquals(fragments.get(i), i + 1, 3, false);
- encodeDecodeAssertEquals(fragments.get(i), i + 1, 3, true);
- }
- }
-
- // Test case for multi-part UTF-16 message.
- String text3 = sUnicodeChars + sUnicodeChars + sUnicodeChars;
- ted = SmsMessage.calculateLength(text3, false);
- assertEquals(3, ted.msgCount);
- assertEquals(189, ted.codeUnitCount);
- assertEquals(3, ted.codeUnitSize);
- if (isCdmaPhone) {
- ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text3);
- assertEquals(3, fragments.size());
-
- for (int i = 0; i < 3; i++) {
- encodeDecodeAssertEquals(fragments.get(i), i + 1, 3, false);
- encodeDecodeAssertEquals(fragments.get(i), i + 1, 3, true);
- }
- }
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java
deleted file mode 100644
index 485542b..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java
+++ /dev/null
@@ -1,1932 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF GSMTestHandler.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.gsm;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.ServiceState;
-import android.test.AndroidTestCase;
-import android.test.PerformanceTestCase;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.GSMTestHandler;
-import com.android.internal.telephony.gsm.GsmMmiCode;
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-
-import java.util.List;
-
-
-public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase {
- private SimulatedRadioControl mRadioControl;
- private GSMPhone mGSMPhone;
- private GSMTestHandler mGSMTestHandler;
- private Handler mHandler;
-
- private static final int EVENT_PHONE_STATE_CHANGED = 1;
- private static final int EVENT_DISCONNECT = 2;
- private static final int EVENT_RINGING = 3;
- private static final int EVENT_CHANNEL_OPENED = 4;
- private static final int EVENT_POST_DIAL = 5;
- private static final int EVENT_DONE = 6;
- private static final int EVENT_SSN = 7;
- private static final int EVENT_MMI_INITIATE = 8;
- private static final int EVENT_MMI_COMPLETE = 9;
- private static final int EVENT_IN_SERVICE = 10;
- private static final int SUPP_SERVICE_FAILED = 11;
- private static final int SERVICE_STATE_CHANGED = 12;
- private static final int EVENT_OEM_RIL_MESSAGE = 13;
- public static final int ANY_MESSAGE = -1;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mGSMTestHandler = new GSMTestHandler(mContext);
-
- mGSMTestHandler.start();
- synchronized (mGSMTestHandler) {
- do {
- mGSMTestHandler.wait();
- } while (mGSMTestHandler.getGSMPhone() == null);
- }
-
- mGSMPhone = mGSMTestHandler.getGSMPhone();
- mRadioControl = mGSMTestHandler.getSimulatedCommands();
-
- mHandler = mGSMTestHandler.getHandler();
- mGSMPhone.registerForPreciseCallStateChanged(mHandler, EVENT_PHONE_STATE_CHANGED, null);
- mGSMPhone.registerForNewRingingConnection(mHandler, EVENT_RINGING, null);
- mGSMPhone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
-
- mGSMPhone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL, null);
-
- mGSMPhone.registerForSuppServiceNotification(mHandler, EVENT_SSN, null);
- mGSMPhone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
- mGSMPhone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
- mGSMPhone.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null);
-
- mGSMPhone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
-
- // wait until we get phone in both voice and data service
- Message msg;
- ServiceState state;
-
- do {
- msg = mGSMTestHandler.waitForMessage(SERVICE_STATE_CHANGED);
- assertNotNull("Message Time Out", msg);
- state = (ServiceState) ((AsyncResult) msg.obj).result;
- } while (state.getState() != ServiceState.STATE_IN_SERVICE);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mRadioControl.shutdown();
-
- mGSMPhone.unregisterForPreciseCallStateChanged(mHandler);
- mGSMPhone.unregisterForNewRingingConnection(mHandler);
- mGSMPhone.unregisterForDisconnect(mHandler);
- mGSMPhone.setOnPostDialCharacter(mHandler, 0, null);
- mGSMPhone.unregisterForSuppServiceNotification(mHandler);
- mGSMPhone.unregisterForMmiInitiate(mHandler);
- mGSMPhone.unregisterForMmiComplete(mHandler);
-
- mGSMPhone = null;
- mRadioControl = null;
- mHandler = null;
- mGSMTestHandler.cleanup();
-
- super.tearDown();
- }
-
- // These test can only be run once.
- public int startPerformance(Intermediates intermediates) {
- return 1;
- }
-
- public boolean isPerformanceOnly() {
- return false;
- }
-
-
- //This test is causing the emulator screen to turn off. I don't understand
- //why, but I'm removing it until we can figure it out.
- public void brokenTestGeneral() throws Exception {
- Connection cn;
- Message msg;
- AsyncResult ar;
-
- // IDLE state
-
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
- assertFalse(mGSMPhone.canConference());
-
- // One DIALING connection
-
- mRadioControl.setAutoProgressConnectingCall(false);
-
- mGSMPhone.dial("+13125551212");
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
-
- msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.DIALING, mGSMPhone.getForegroundCall().getState());
- assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- /*do {
- mGSMTestHandler.waitForMessage(ANY_MESSAGE);
- } while (mGSMPhone.getForegroundCall().getConnections().size() == 0);*/
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DIALING,
- mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- cn = mGSMPhone.getForegroundCall().getConnections().get(0);
- assertTrue(!cn.isIncoming());
- assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
- assertEquals(Connection.DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause());
-
- assertFalse(mGSMPhone.canConference());
-
- // One ALERTING connection
-
- mRadioControl.progressConnectingCallState();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ALERTING, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- cn = mGSMPhone.getForegroundCall().getConnections().get(0);
- assertTrue(!cn.isIncoming());
- assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
- assertFalse(mGSMPhone.canConference());
-
- // One ACTIVE connection
-
- mRadioControl.progressConnectingCallState();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
- cn = mGSMPhone.getForegroundCall().getConnections().get(0);
- assertTrue(!cn.isIncoming());
- assertEquals(Connection.PostDialState.COMPLETE, cn.getPostDialState());
- assertFalse(mGSMPhone.canConference());
-
- // One disconnected connection
- mGSMPhone.getForegroundCall().hangup();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
- assertFalse(mGSMPhone.canConference());
-
- cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- // Back to idle state
-
- mGSMPhone.clearDisconnected();
-
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- assertFalse(mGSMPhone.canConference());
-
- // cn left over from before phone.clearDisconnected();
-
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- // One ringing (INCOMING) call
-
- mRadioControl.triggerRing("18005551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- ar = (AsyncResult) msg.obj;
- cn = (Connection) ar.result;
- assertTrue(cn.isRinging());
- assertEquals(mGSMPhone.getRingingCall(), cn.getCall());
-
- assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.INCOMING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- cn = mGSMPhone.getRingingCall().getConnections().get(0);
- assertTrue(cn.isIncoming());
- assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
- assertFalse(mGSMPhone.canConference());
-
- // One mobile terminated active call
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getConnections().size() == 1);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE,
- mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
- cn = mGSMPhone.getForegroundCall().getConnections().get(0);
- assertTrue(cn.isIncoming());
- assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
- assertFalse(mGSMPhone.canConference());
-
- // One disconnected (local hangup) call
-
- try {
- Connection conn;
- conn = mGSMPhone.getForegroundCall().getConnections().get(0);
- conn.hangup();
- } catch (CallStateException ex) {
- ex.printStackTrace();
- fail("unexpected ex");
- }
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED,
- mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
- cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-
- assertFalse(mGSMPhone.canConference());
-
- // Back to idle state
-
- mGSMPhone.clearDisconnected();
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- assertFalse(mGSMPhone.canConference());
-
- // cn left over from before phone.clearDisconnected();
-
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- // One ringing call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getConnections().isEmpty());
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.INCOMING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- assertFalse(mGSMPhone.canConference());
-
- // One rejected call
- mGSMPhone.rejectCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.IDLE);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- cn = mGSMPhone.getRingingCall().getEarliestConnection();
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
-
- assertFalse(mGSMPhone.canConference());
-
- // Back to idle state
-
- mGSMPhone.clearDisconnected();
-
- assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- assertFalse(mGSMPhone.canConference());
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- // One ringing call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getConnections().isEmpty());
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
- // Ringing call disconnects
-
- mRadioControl.triggerHangupForeground();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.IDLE);
-
- assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
-
- // One Ringing Call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.RINGING);
-
-
- cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
- // One answered call
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // one holding call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
-
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // one active call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // One disconnected call in the foreground slot
-
- mRadioControl.triggerHangupAll();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.IDLE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause());
-
- // Test missed calls
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.RINGING);
-
- mGSMPhone.rejectCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (msg.what != EVENT_DISCONNECT);
-
- ar = (AsyncResult) msg.obj;
- cn = (Connection) ar.result;
-
- assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
-
- // Test incoming not missed calls
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.RINGING);
-
- cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
- assertEquals(Connection.DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause());
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-
- try {
- mGSMPhone.getForegroundCall().hangup();
- } catch (CallStateException ex) {
- ex.printStackTrace();
- fail("unexpected ex");
- }
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState()
- != Call.State.DISCONNECTED);
-
- assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-
- //
- // Test held and hangup held calls
- //
-
- // One ALERTING call
- mGSMPhone.dial("+13125551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
- assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- mRadioControl.progressConnectingCallState();
- mRadioControl.progressConnectingCallState();
-
- // One ACTIVE call
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- // One ACTIVE call, one ringing call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.RINGING);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- // One HOLDING call, one ACTIVE call
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertTrue(mGSMPhone.canConference());
-
- // Conference the two
- mGSMPhone.conference();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertTrue(mGSMPhone.getForegroundCall().isMultiparty());
- assertFalse(mGSMPhone.canConference());
-
- // Hold the multiparty call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING);
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertTrue(mGSMPhone.getBackgroundCall().isMultiparty());
- assertFalse(mGSMPhone.canConference());
-
- // Multiparty call on hold, call waiting added
-
- mRadioControl.triggerRing("18005558355");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.RINGING);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertTrue(mGSMPhone.getBackgroundCall().isMultiparty());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertFalse(mGSMPhone.canConference());
-
- // Hangup conference call, ringing call still around
- mGSMPhone.getBackgroundCall().hangup();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.DISCONNECTED);
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getBackgroundCall().getState());
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- // Reject waiting call
- mGSMPhone.rejectCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.IDLE);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- }
-
- public void testOutgoingCallFailImmediately() throws Exception {
- Message msg;
-
- // Test outgoing call fail-immediately edge case
- // This happens when a call terminated before ever appearing in a
- // call list
- // This should land the immediately-failing call in the
- // ForegroundCall list as an IDLE call
- mRadioControl.setNextDialFailImmediately(true);
-
- Connection cn = mGSMPhone.dial("+13125551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
- }
-
- public void testHangupOnOutgoing() throws Exception {
- Connection cn;
- Message msg;
-
- mRadioControl.setAutoProgressConnectingCall(false);
-
- // Test 1: local hangup in "DIALING" state
- mGSMPhone.dial("+13125551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getForegroundCall().getState() != Call.State.DIALING);
-
- cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
- mGSMPhone.getForegroundCall().hangup();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-
- // Test 2: local hangup in "ALERTING" state
- mGSMPhone.dial("+13125551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
- mRadioControl.progressConnectingCallState();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING);
-
- cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
- mGSMPhone.getForegroundCall().hangup();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Connection.DisconnectCause.LOCAL, cn.getDisconnectCause());
-
- // Test 3: local immediate hangup before GSM index is
- // assigned (CallTracker.hangupPendingMO case)
-
- mRadioControl.pauseResponses();
-
- cn = mGSMPhone.dial("+13125551212");
-
- cn.hangup();
-
- mRadioControl.resumeResponses();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-
- assertEquals(Connection.DisconnectCause.LOCAL,
- mGSMPhone.getForegroundCall().getEarliestConnection().getDisconnectCause());
- }
-
- public void testHangupOnChannelClose() throws Exception {
- mGSMPhone.dial("+13125551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getConnections().isEmpty());
-
- mRadioControl.shutdown();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- mGSMPhone.clearDisconnected();
- } while (!mGSMPhone.getForegroundCall().getConnections().isEmpty());
- }
-
- public void testIncallMmiCallDeflection() throws Exception {
- Message msg;
-
- // establish an active call
- mGSMPhone.dial("+13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // establish a ringing (WAITING) call
-
- mRadioControl.triggerRing("18005551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 0 followed by SEND: release all held calls
- // or sets UDUB for a waiting call.
- mGSMPhone.handleInCallMmiCommands("0");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // change the active call to holding call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
-
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 0 followed by SEND: release all held calls
- // or sets UDUB for a waiting call.
- mGSMPhone.handleInCallMmiCommands("0");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING);
-
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getBackgroundCall().getState());
- }
-
- public void testIncallMmiCallWaiting() throws Exception {
- Message msg;
-
- // establish an active call
- mGSMPhone.dial("+13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // establish a ringing (WAITING) call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
- assertNotNull("Message Time Out", msg);
- } while (msg.what != EVENT_RINGING);
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 1 followed by SEND: release all active calls
- // (if any exist) and accepts the other (held or waiting) call.
-
- mGSMPhone.handleInCallMmiCommands("1");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
- // change the active call to holding call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 1 followed by SEND: release all active calls
- // (if any exist) and accepts the other (held or waiting) call.
- mGSMPhone.handleInCallMmiCommands("1");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
- // at this point, the active call with number==18005551212 should
- // have the gsm index of 2
-
- mRadioControl.triggerRing("16505550100");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering "12" followed by SEND: release the call with
- // gsm index equals to 2.
- mGSMPhone.handleInCallMmiCommands("12");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != Phone.State.OFFHOOK);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // at this point, the call with number==16505550100 should
- // have the gsm index of 1
- mGSMPhone.dial("+13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE ||
- mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // at this point, the active call with number==13125551212 should
- // have the gsm index of 2
-
- // Simulate entering "11" followed by SEND: release the call with
- // gsm index equals to 1. This should not be allowed, and a
- // Supplementary Service notification must be received.
- mGSMPhone.handleInCallMmiCommands("11");
-
- msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED);
- assertNotNull("Message Time Out", msg);
- assertFalse("IncallMmiCallWaiting: command should not work on holding call", msg == null);
-
- // Simulate entering "12" followed by SEND: release the call with
- // gsm index equals to 2.
- mGSMPhone.handleInCallMmiCommands("12");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 1 followed by SEND: release all active calls
- // (if any exist) and accepts the other (held or waiting) call.
- mGSMPhone.handleInCallMmiCommands("1");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- assertEquals("16505550100",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
- // Simulate entering "11" followed by SEND: release the call with
- // gsm index equals to 1.
- mGSMPhone.handleInCallMmiCommands("11");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- }
-
- public void testIncallMmiCallHold() throws Exception {
- Message msg;
-
- // establish an active call
- mGSMPhone.dial("13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // establish a ringing (WAITING) call
-
- mRadioControl.triggerRing("18005551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // simulate entering 2 followed by SEND: place all active calls
- // (if any exist) on hold and accepts the other (held or waiting)
- // call
-
- mGSMPhone.handleInCallMmiCommands("2");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
-
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE,
- mGSMPhone.getForegroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("13125551212",
- mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
- // swap the active and holding calls
- mGSMPhone.handleInCallMmiCommands("2");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("13125551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
- // merge the calls
- mGSMPhone.conference();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- assertEquals(2, mGSMPhone.getForegroundCall().getConnections().size());
-
- // at this point, we have an active conference call, with
- // call(1) = 13125551212 and call(2) = 18005551212
-
- // Simulate entering "23" followed by SEND: places all active call
- // on hold except call 3. This should fail and a supplementary service
- // failed notification should be received.
-
- mGSMPhone.handleInCallMmiCommands("23");
-
- msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED);
- assertNotNull("Message Time Out", msg);
- assertFalse("IncallMmiCallHold: separate should have failed!", msg == null);
-
- // Simulate entering "21" followed by SEND: places all active call
- // on hold except call 1.
- mGSMPhone.handleInCallMmiCommands("21");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("13125551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
- }
-
- public void testIncallMmiMultipartyServices() throws Exception {
- // establish an active call
- mGSMPhone.dial("13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // dial another call
- mGSMPhone.dial("18005551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- mGSMPhone.handleInCallMmiCommands("3");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals("13125551212",
- mGSMPhone.getForegroundCall().getConnections().get(1).getAddress());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- }
-
- public void testCallIndex() throws Exception {
- Message msg;
-
- // establish the first call
- mGSMPhone.dial("16505550100");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- String baseNumber = "1650555010";
-
- for (int i = 1; i < 6; i++) {
- String number = baseNumber + i;
-
- mGSMPhone.dial(number);
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- if (mGSMPhone.getBackgroundCall().getConnections().size() >= 5) {
- break;
- }
-
- mGSMPhone.conference();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- }
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("16505550105",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // create an incoming call, this call should have the call index
- // of 7
- mRadioControl.triggerRing("18005551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Phone.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // hangup the background call and accept the ringing call
- mGSMPhone.getBackgroundCall().hangup();
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getState() != Call.State.IDLE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("16505550105",
- mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
- mGSMPhone.handleInCallMmiCommands("17");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("16505550105",
- mGSMPhone.getBackgroundCall().getConnections().get(0).
- getAddress());
-
- mGSMPhone.handleInCallMmiCommands("1");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- mGSMPhone.handleInCallMmiCommands("16");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- }
-
- public void testPostDialSequences() throws Exception {
- Message msg;
- AsyncResult ar;
- Connection cn;
-
- mGSMPhone.dial("+13125551212,1234;5N8xx");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(',', msg.arg1);
- assertEquals("1234;5N8", cn.getRemainingPostDialString());
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('1', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('2', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('3', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('4', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals(';', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.WAIT, cn.getPostDialState());
- assertEquals(Connection.PostDialState.WAIT, ar.userObj);
- cn.proceedAfterWaitChar();
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('5', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertEquals('N', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.WILD, cn.getPostDialState());
- assertEquals(Connection.PostDialState.WILD, ar.userObj);
- cn.proceedAfterWildChar(",6;7");
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(',', msg.arg1);
- assertEquals("6;78", cn.getRemainingPostDialString());
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('6', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals(';', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.WAIT, cn.getPostDialState());
- assertEquals(Connection.PostDialState.WAIT, ar.userObj);
- cn.proceedAfterWaitChar();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('7', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('8', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
- // Bogus chars at end should be ignored
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals(0, msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.COMPLETE,
- cn.getPostDialState());
- assertEquals(Connection.PostDialState.COMPLETE, ar.userObj);
- }
-
- public void testPostDialCancel() throws Exception {
- Message msg;
- AsyncResult ar;
- Connection cn;
-
- mGSMPhone.dial("+13125551212,N");
- mRadioControl.progressConnectingToActive();
-
- mRadioControl.progressConnectingToActive();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals(',', msg.arg1);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertEquals('N', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.WILD, cn.getPostDialState());
- cn.cancelPostDial();
-
- assertEquals(Connection.PostDialState.CANCELLED, cn.getPostDialState());
- }
-
- public void testOutgoingCallFail() throws Exception {
- Message msg;
- /*
- * normal clearing
- */
-
- mRadioControl.setNextCallFailCause(CallFailCause.NORMAL_CLEARING);
- mRadioControl.setAutoProgressConnectingCall(false);
-
- Connection cn = mGSMPhone.dial("+13125551212");
-
- mRadioControl.progressConnectingCallState();
-
- // I'm just progressing the call state to
- // ensure getCurrentCalls() gets processed...
- // Normally these failure conditions would happen in DIALING
- // not ALERTING
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (cn.getState() == Call.State.DIALING);
-
-
- mRadioControl.triggerHangupAll();
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- /*
- * busy
- */
-
- mRadioControl.setNextCallFailCause(CallFailCause.USER_BUSY);
- mRadioControl.setAutoProgressConnectingCall(false);
-
- cn = mGSMPhone.dial("+13125551212");
-
- mRadioControl.progressConnectingCallState();
-
- // I'm just progressing the call state to
- // ensure getCurrentCalls() gets processed...
- // Normally these failure conditions would happen in DIALING
- // not ALERTING
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (cn.getState() == Call.State.DIALING);
-
-
- mRadioControl.triggerHangupAll();
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Connection.DisconnectCause.BUSY, cn.getDisconnectCause());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED,
- mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- /*
- * congestion
- */
-
- mRadioControl.setNextCallFailCause(CallFailCause.NO_CIRCUIT_AVAIL);
- mRadioControl.setAutoProgressConnectingCall(false);
-
- cn = mGSMPhone.dial("+13125551212");
-
- mRadioControl.progressConnectingCallState();
-
- // I'm just progressing the call state to
- // ensure getCurrentCalls() gets processed...
- // Normally these failure conditions would happen in DIALING
- // not ALERTING
- do {
- msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
- assertNotNull("Message Time Out", msg);
- } while (cn.getState() == Call.State.DIALING);
-
-
- mRadioControl.triggerHangupAll();
-
- // Unlike the while loops above, this one waits
- // for a "phone state changed" message back to "idle"
- do {
- msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
- assertNotNull("Message Time Out", msg);
- } while (!(msg.what == EVENT_PHONE_STATE_CHANGED
- && mGSMPhone.getState() == Phone.State.IDLE));
-
- assertEquals(Phone.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Connection.DisconnectCause.CONGESTION, cn.getDisconnectCause());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
- }
-
- public void testSSNotification() throws Exception {
- // MO
- runTest(0, SuppServiceNotification.MO_CODE_UNCONDITIONAL_CF_ACTIVE);
- runTest(0, SuppServiceNotification.MO_CODE_CALL_IS_WAITING);
- runTest(0, SuppServiceNotification.MO_CODE_CALL_DEFLECTED);
-
- // MT
- runTest(1, SuppServiceNotification.MT_CODE_FORWARDED_CALL);
- runTest(1, SuppServiceNotification.MT_CODE_CALL_CONNECTED_ECT);
- runTest(1, SuppServiceNotification.MT_CODE_ADDITIONAL_CALL_FORWARDED);
- }
-
- private void runTest(int type, int code) {
- Message msg;
-
- mRadioControl.triggerSsn(type, code);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_SSN);
- assertNotNull("Message Time Out", msg);
- AsyncResult ar = (AsyncResult) msg.obj;
-
- assertNull(ar.exception);
-
- SuppServiceNotification notification =
- (SuppServiceNotification) ar.result;
-
- assertEquals(type, notification.notificationType);
- assertEquals(code, notification.code);
- }
-
- public void testUssd() throws Exception {
- // Quick hack to work around a race condition in this test:
- // We may initiate a USSD MMI before GSMPhone receives its initial
- // GSMTestHandler.EVENT_RADIO_OFF_OR_NOT_AVAILABLE event. When the phone sees this
- // event, it will cancel the just issued USSD MMI, which we don't
- // want. So sleep a little first.
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ex) {
- // do nothing
- }
-
- verifyNormal();
- verifyCancel();
- varifyNetworkInitiated();
- }
-
- private void varifyNetworkInitiated() {
- Message msg;
- AsyncResult ar;
- MmiCode mmi;
-
- // Receive an incoming NOTIFY
- mRadioControl.triggerIncomingUssd("0", "NOTIFY message");
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertFalse(mmi.isUssdRequest());
-
- // Receive a REQUEST and send response
- mRadioControl.triggerIncomingUssd("1", "REQUEST Message");
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertTrue(mmi.isUssdRequest());
-
- mGSMPhone.sendUssdResponse("## TEST: TEST_GSMPhone responding...");
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- GsmMmiCode gsmMmi = (GsmMmiCode) mmi;
- assertTrue(gsmMmi.isPendingUSSD());
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertNull(ar.exception);
- assertFalse(mmi.isUssdRequest());
-
- // Receive a REQUEST and cancel
- mRadioControl.triggerIncomingUssd("1", "REQUEST Message");
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertTrue(mmi.isUssdRequest());
-
- mmi.cancel();
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
-
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertNull(ar.exception);
- assertEquals(MmiCode.State.CANCELLED, mmi.getState());
-
- List mmiList = mGSMPhone.getPendingMmiCodes();
- assertEquals(0, mmiList.size());
- }
-
- private void verifyNormal() throws CallStateException {
- Message msg;
- AsyncResult ar;
- MmiCode mmi;
-
- mGSMPhone.dial("#646#");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
- assertNotNull("Message Time Out", msg);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
-
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
- assertEquals(MmiCode.State.COMPLETE, mmi.getState());
- }
-
-
- private void verifyCancel() throws CallStateException {
- /**
- * This case makes an assumption that dial() will add the USSD
- * to the "pending MMI codes" list before it returns. This seems
- * like reasonable semantics. It also assumes that the USSD
- * request in question won't complete until we get back to the
- * event loop, thus cancel() is safe.
- */
- Message msg;
-
- mGSMPhone.dial("#646#");
-
- List<? extends MmiCode> pendingMmis = mGSMPhone.getPendingMmiCodes();
-
- assertEquals(1, pendingMmis.size());
-
- MmiCode mmi = pendingMmis.get(0);
- assertTrue(mmi.isCancelable());
- mmi.cancel();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
- assertNotNull("Message Time Out", msg);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
-
- AsyncResult ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertEquals(MmiCode.State.CANCELLED, mmi.getState());
- }
-
- public void testRilHooks() throws Exception {
- //
- // These test cases all assume the RIL OEM hooks
- // just echo back their input
- //
-
- Message msg;
- AsyncResult ar;
-
- // null byte array
-
- mGSMPhone.invokeOemRilRequestRaw(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertNull(ar.result);
- assertNull(ar.exception);
-
- // empty byte array
-
- mGSMPhone.invokeOemRilRequestRaw(new byte[0], mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertEquals(0, ((byte[]) (ar.result)).length);
- assertNull(ar.exception);
-
- // byte array with data
-
- mGSMPhone.invokeOemRilRequestRaw("Hello".getBytes("utf-8"),
- mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertEquals("Hello", new String(((byte[]) (ar.result)), "utf-8"));
- assertNull(ar.exception);
-
- // null strings
-
- mGSMPhone.invokeOemRilRequestStrings(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertNull(ar.result);
- assertNull(ar.exception);
-
- // empty byte array
-
- mGSMPhone.invokeOemRilRequestStrings(new String[0],
- mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertEquals(0, ((String[]) (ar.result)).length);
- assertNull(ar.exception);
-
- // Strings with data
-
- String s[] = new String[1];
-
- s[0] = "Hello";
-
- mGSMPhone.invokeOemRilRequestStrings(s, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertEquals("Hello", ((String[]) (ar.result))[0]);
- assertEquals(1, ((String[]) (ar.result)).length);
- assertNull(ar.exception);
- }
-
- public void testMmi() throws Exception {
- mRadioControl.setAutoProgressConnectingCall(false);
-
- // "valid" MMI sequences
- runValidMmi("*#67#", false);
- runValidMmi("##43*11#", false);
- runValidMmi("#33*1234*11#", false);
- runValidMmi("*21*6505551234**5#", false);
- runValidMmi("**03**1234*4321*4321#", false);
- // pound string
- runValidMmi("5308234092307540923#", true);
- // short code
- runValidMmi("22", true);
- // as part of call setup
- runValidMmiWithConnect("*31#6505551234");
-
- // invalid MMI sequences
- runNotMmi("6505551234");
- runNotMmi("1234#*12#34566654");
- runNotMmi("*#*#12#*");
- }
-
- private void runValidMmi(String dialString, boolean cancelable) throws CallStateException {
- Connection c = mGSMPhone.dial(dialString);
- assertNull(c);
- Message msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
- assertNotNull("Message Time Out", msg);
- // Should not be cancelable.
- AsyncResult ar = (AsyncResult) msg.obj;
- MmiCode mmi = (MmiCode) ar.result;
- assertEquals(cancelable, mmi.isCancelable());
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- }
-
- private void runValidMmiWithConnect(String dialString) throws CallStateException {
- mRadioControl.pauseResponses();
-
- Connection c = mGSMPhone.dial(dialString);
- assertNotNull(c);
-
- hangup(c);
- }
-
- private void hangup(Connection cn) throws CallStateException {
- cn.hangup();
-
- mRadioControl.resumeResponses();
- assertNotNull(mGSMTestHandler.waitForMessage(EVENT_DISCONNECT));
-
- }
-
- private void runNotMmi(String dialString) throws CallStateException {
- mRadioControl.pauseResponses();
-
- Connection c = mGSMPhone.dial(dialString);
- assertNotNull(c);
-
- hangup(c);
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java
deleted file mode 100644
index fb8a5d9..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2009 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.gsm;
-
-import android.content.Context;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.test.SimulatedCommands;
-import com.android.internal.telephony.TestPhoneNotifier;
-
-/**
- * This class creates a HandlerThread which waits for the various messages.
- */
-public class GSMTestHandler extends HandlerThread implements Handler.Callback {
-
- private Handler mHandler;
- private Message mCurrentMessage;
-
- private Boolean mMsgConsumed;
- private SimulatedCommands sc;
- private GSMPhone mGSMPhone;
- private Context mContext;
-
- private static final int FAIL_TIMEOUT_MILLIS = 5 * 1000;
-
- public GSMTestHandler(Context context) {
- super("GSMPhoneTest");
- mMsgConsumed = false;
- mContext = context;
- }
-
- @Override
- protected void onLooperPrepared() {
- sc = new SimulatedCommands();
- mGSMPhone = new GSMPhone(mContext, sc, new TestPhoneNotifier(), true);
- mHandler = new Handler(getLooper(), this);
- synchronized (this) {
- notifyAll();
- }
- }
-
- public boolean handleMessage(Message msg) {
- synchronized (this) {
- mCurrentMessage = msg;
- this.notifyAll();
- while(!mMsgConsumed) {
- try {
- this.wait();
- } catch (InterruptedException e) {}
- }
- mMsgConsumed = false;
- }
- return true;
- }
-
-
- public void cleanup() {
- Looper looper = getLooper();
- if (looper != null) looper.quit();
- mHandler = null;
- }
-
- public Handler getHandler() {
- return mHandler;
- }
-
- public SimulatedCommands getSimulatedCommands() {
- return sc;
- }
-
- public GSMPhone getGSMPhone() {
- return mGSMPhone;
- }
-
- public Message waitForMessage(int code) {
- Message msg;
- while(true) {
- msg = null;
- synchronized (this) {
- try {
- this.wait(FAIL_TIMEOUT_MILLIS);
- } catch (InterruptedException e) {
- }
-
- // Check if timeout has occurred.
- if (mCurrentMessage != null) {
- // Consume the message
- msg = Message.obtain();
- msg.copyFrom(mCurrentMessage);
- mCurrentMessage = null;
- mMsgConsumed = true;
- this.notifyAll();
- }
- }
- if (msg == null || code == GSMPhoneTest.ANY_MESSAGE || msg.what == code) return msg;
- }
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java
deleted file mode 100644
index 82c6944..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- * Copyright (C) 2010 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.gsm;
-
-import android.telephony.SmsCbEtwsInfo;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.internal.telephony.IccUtils;
-
-import java.util.Random;
-
-/**
- * Test cases for basic SmsCbMessage operations
- */
-public class GsmSmsCbTest extends AndroidTestCase {
-
- private static final String TAG = "GsmSmsCbTest";
-
- private static final SmsCbLocation sTestLocation = new SmsCbLocation("94040", 1234, 5678);
-
- private static SmsCbMessage createFromPdu(byte[] pdu) {
- try {
- SmsCbHeader header = new SmsCbHeader(pdu);
- byte[][] pdus = new byte[1][];
- pdus[0] = pdu;
- return GsmSmsCbMessage.createSmsCbMessage(header, sTestLocation, pdus);
- } catch (IllegalArgumentException e) {
- return null;
- }
- }
-
- private static void doTestGeographicalScopeValue(byte[] pdu, byte b, int expectedGs) {
- pdu[0] = b;
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected geographical scope decoded", expectedGs, msg
- .getGeographicalScope());
- }
-
- public void testCreateNullPdu() {
- SmsCbMessage msg = createFromPdu(null);
- assertNull("createFromPdu(byte[] with null pdu should return null", msg);
- }
-
- public void testCreateTooShortPdu() {
- byte[] pdu = new byte[4];
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertNull("createFromPdu(byte[] with too short pdu should return null", msg);
- }
-
- public void testGetGeographicalScope() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
- (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
- (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
- (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
- (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
- (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
- (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
- (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
- };
-
- doTestGeographicalScopeValue(pdu, (byte)0x00,
- SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE);
- doTestGeographicalScopeValue(pdu, (byte)0x40, SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE);
- doTestGeographicalScopeValue(pdu, (byte)0x80, SmsCbMessage.GEOGRAPHICAL_SCOPE_LA_WIDE);
- doTestGeographicalScopeValue(pdu, (byte)0xC0, SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE);
- }
-
- public void testGetGeographicalScopeUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
- (byte)0x01,
-
- (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
- (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
- (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
- (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
- (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
- (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
- (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
- (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
- (byte)0x34
- };
-
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected geographical scope decoded",
- SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE, msg.getGeographicalScope());
- }
-
- public void testGetMessageBody7Bit() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
- (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
- (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
- (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
- (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
- (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
- (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
- (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A GSM default alphabet message with carriage return padding",
- msg.getMessageBody());
- }
-
- public void testGetMessageBody7BitUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
- (byte)0x01,
-
- (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
- (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
- (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
- (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
- (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
- (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
- (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
- (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
- (byte)0x34
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A GSM default alphabet message with carriage return padding",
- msg.getMessageBody());
- }
-
- public void testGetMessageBody7BitMultipageUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x00, (byte)0x01, (byte)0xC0, (byte)0x00, (byte)0x40,
-
- (byte)0x02,
-
- (byte)0xC6, (byte)0xB4, (byte)0x7C, (byte)0x4E, (byte)0x07, (byte)0xC1,
- (byte)0xC3, (byte)0xE7, (byte)0xF2, (byte)0xAA, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A,
- (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34,
- (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
- (byte)0x0A,
-
- (byte)0xD3, (byte)0xF2, (byte)0xF8, (byte)0xED, (byte)0x26, (byte)0x83,
- (byte)0xE0, (byte)0xE1, (byte)0x73, (byte)0xB9, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A,
- (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34,
- (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
- (byte)0x0A
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected multipage 7-bit string decoded",
- "First page+Second page",
- msg.getMessageBody());
- }
-
- public void testGetMessageBody7BitFull() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
- (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
- (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
- (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
- (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xC4, (byte)0xE5,
- (byte)0xB4, (byte)0xFB, (byte)0x0C, (byte)0x2A, (byte)0xE3, (byte)0xC3, (byte)0x63,
- (byte)0x3A, (byte)0x3B, (byte)0x0F, (byte)0xCA, (byte)0xCD, (byte)0x40, (byte)0x63,
- (byte)0x74, (byte)0x58, (byte)0x1E, (byte)0x1E, (byte)0xD3, (byte)0xCB, (byte)0xF2,
- (byte)0x39, (byte)0x88, (byte)0xFD, (byte)0x76, (byte)0x9F, (byte)0x59, (byte)0xA0,
- (byte)0x76, (byte)0x39, (byte)0xEC, (byte)0x4E, (byte)0xBB, (byte)0xCF, (byte)0x20,
- (byte)0x3A, (byte)0xBA, (byte)0x2C, (byte)0x2F, (byte)0x83, (byte)0xD2, (byte)0x73,
- (byte)0x90, (byte)0xFB, (byte)0x0D, (byte)0x82, (byte)0x87, (byte)0xC9, (byte)0xE4,
- (byte)0xB4, (byte)0xFB, (byte)0x1C, (byte)0x02
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals(
- "Unexpected 7-bit string decoded",
- "A GSM default alphabet message being exactly 93 characters long, " +
- "meaning there is no padding!",
- msg.getMessageBody());
- }
-
- public void testGetMessageBody7BitFullUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
- (byte)0x01,
-
- (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
- (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
- (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
- (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
- (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xC4, (byte)0xE5, (byte)0xB4,
- (byte)0xFB, (byte)0x0C, (byte)0x2A, (byte)0xE3, (byte)0xC3, (byte)0x63,
- (byte)0x3A, (byte)0x3B, (byte)0x0F, (byte)0xCA, (byte)0xCD, (byte)0x40,
- (byte)0x63, (byte)0x74, (byte)0x58, (byte)0x1E, (byte)0x1E, (byte)0xD3,
- (byte)0xCB, (byte)0xF2, (byte)0x39, (byte)0x88, (byte)0xFD, (byte)0x76,
- (byte)0x9F, (byte)0x59, (byte)0xA0, (byte)0x76, (byte)0x39, (byte)0xEC,
- (byte)0x4E, (byte)0xBB, (byte)0xCF, (byte)0x20, (byte)0x3A, (byte)0xBA,
- (byte)0x2C, (byte)0x2F, (byte)0x83, (byte)0xD2, (byte)0x73, (byte)0x90,
- (byte)0xFB, (byte)0x0D, (byte)0x82, (byte)0x87, (byte)0xC9, (byte)0xE4,
- (byte)0xB4, (byte)0xFB, (byte)0x1C, (byte)0x02,
-
- (byte)0x52
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals(
- "Unexpected 7-bit string decoded",
- "A GSM default alphabet message being exactly 93 characters long, " +
- "meaning there is no padding!",
- msg.getMessageBody());
- }
-
- public void testGetMessageBody7BitWithLanguage() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x04, (byte)0x11, (byte)0x41,
- (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
- (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
- (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
- (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
- (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
- (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
- (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A GSM default alphabet message with carriage return padding",
- msg.getMessageBody());
-
- assertEquals("Unexpected language indicator decoded", "es", msg.getLanguageCode());
- }
-
- public void testGetMessageBody7BitWithLanguageInBody() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x10, (byte)0x11, (byte)0x73,
- (byte)0x7B, (byte)0x23, (byte)0x08, (byte)0x3A, (byte)0x4E, (byte)0x9B, (byte)0x20,
- (byte)0x72, (byte)0xD9, (byte)0x1C, (byte)0xAE, (byte)0xB3, (byte)0xE9, (byte)0xA0,
- (byte)0x30, (byte)0x1B, (byte)0x8E, (byte)0x0E, (byte)0x8B, (byte)0xCB, (byte)0x74,
- (byte)0x50, (byte)0xBB, (byte)0x3C, (byte)0x9F, (byte)0x87, (byte)0xCF, (byte)0x65,
- (byte)0xD0, (byte)0x3D, (byte)0x4D, (byte)0x47, (byte)0x83, (byte)0xC6, (byte)0x61,
- (byte)0xB9, (byte)0x3C, (byte)0x1D, (byte)0x3E, (byte)0x97, (byte)0x41, (byte)0xF2,
- (byte)0x32, (byte)0xBD, (byte)0x2E, (byte)0x77, (byte)0x83, (byte)0xE0, (byte)0x61,
- (byte)0x32, (byte)0x39, (byte)0xED, (byte)0x3E, (byte)0x37, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A GSM default alphabet message with carriage return padding",
- msg.getMessageBody());
-
- assertEquals("Unexpected language indicator decoded", "sv", msg.getLanguageCode());
- }
-
- public void testGetMessageBody7BitWithLanguageInBodyUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x10,
-
- (byte)0x01,
-
- (byte)0x73, (byte)0x7B, (byte)0x23, (byte)0x08, (byte)0x3A, (byte)0x4E,
- (byte)0x9B, (byte)0x20, (byte)0x72, (byte)0xD9, (byte)0x1C, (byte)0xAE,
- (byte)0xB3, (byte)0xE9, (byte)0xA0, (byte)0x30, (byte)0x1B, (byte)0x8E,
- (byte)0x0E, (byte)0x8B, (byte)0xCB, (byte)0x74, (byte)0x50, (byte)0xBB,
- (byte)0x3C, (byte)0x9F, (byte)0x87, (byte)0xCF, (byte)0x65, (byte)0xD0,
- (byte)0x3D, (byte)0x4D, (byte)0x47, (byte)0x83, (byte)0xC6, (byte)0x61,
- (byte)0xB9, (byte)0x3C, (byte)0x1D, (byte)0x3E, (byte)0x97, (byte)0x41,
- (byte)0xF2, (byte)0x32, (byte)0xBD, (byte)0x2E, (byte)0x77, (byte)0x83,
- (byte)0xE0, (byte)0x61, (byte)0x32, (byte)0x39, (byte)0xED, (byte)0x3E,
- (byte)0x37, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
- (byte)0x37
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A GSM default alphabet message with carriage return padding",
- msg.getMessageBody());
-
- assertEquals("Unexpected language indicator decoded", "sv", msg.getLanguageCode());
- }
-
- public void testGetMessageBody8Bit() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x44, (byte)0x11, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
- (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("8-bit message body should be empty", "", msg.getMessageBody());
- }
-
- public void testGetMessageBodyUcs2() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x48, (byte)0x11, (byte)0x00,
- (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55, (byte)0x00, (byte)0x43,
- (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x20, (byte)0x00,
- (byte)0x6D, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73,
- (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, (byte)0x00,
- (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6E,
- (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x69, (byte)0x00,
- (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x67,
- (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x20, (byte)0x04,
- (byte)0x34, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68,
- (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00,
- (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x72,
- (byte)0x00, (byte)0x0D, (byte)0x00, (byte)0x0D
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A UCS2 message containing a \u0434 character", msg.getMessageBody());
- }
-
- public void testGetMessageBodyUcs2Umts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x48,
-
- (byte)0x01,
-
- (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55,
- (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32,
- (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x6D, (byte)0x00, (byte)0x65,
- (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x61,
- (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x20,
- (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6E,
- (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x69,
- (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E,
- (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61,
- (byte)0x00, (byte)0x20, (byte)0x04, (byte)0x34, (byte)0x00, (byte)0x20,
- (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68, (byte)0x00, (byte)0x61,
- (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x63,
- (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x72,
- (byte)0x00, (byte)0x0D, (byte)0x00, (byte)0x0D,
-
- (byte)0x4E
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A UCS2 message containing a \u0434 character", msg.getMessageBody());
- }
-
- public void testGetMessageBodyUcs2MultipageUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x48,
-
- (byte)0x02,
-
- (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x41,
- (byte)0x00, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-
- (byte)0x06,
-
- (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x42,
- (byte)0x00, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
- (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-
- (byte)0x06
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected multipage UCS2 string decoded",
- "AAABBB", msg.getMessageBody());
- }
-
- public void testGetMessageBodyUcs2WithLanguageInBody() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x11, (byte)0x11, (byte)0x78,
- (byte)0x3C, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55,
- (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, (byte)0x00,
- (byte)0x20, (byte)0x00, (byte)0x6D, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73,
- (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00,
- (byte)0x65, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F,
- (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00,
- (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E,
- (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, (byte)0x00,
- (byte)0x20, (byte)0x04, (byte)0x34, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63,
- (byte)0x00, (byte)0x68, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00,
- (byte)0x61, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65,
- (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x0D
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-
- assertEquals("Unexpected language indicator decoded", "xx", msg.getLanguageCode());
- }
-
- public void testGetMessageBodyUcs2WithLanguageInBodyUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x11,
-
- (byte)0x01,
-
- (byte)0x78, (byte)0x3C, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20,
- (byte)0x00, (byte)0x55, (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53,
- (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x6D,
- (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73,
- (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65,
- (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F,
- (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61,
- (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69,
- (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20,
- (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x20, (byte)0x04, (byte)0x34,
- (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68,
- (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61,
- (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65,
- (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x0D,
-
- (byte)0x50
- };
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected 7-bit string decoded",
- "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-
- assertEquals("Unexpected language indicator decoded", "xx", msg.getLanguageCode());
- }
-
- public void testGetMessageIdentifier() {
- byte[] pdu = {
- (byte)0xC0, (byte)0x00, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
- (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
- (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
- (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
- (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
- (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
- (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
- (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
- };
-
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected message identifier decoded", 12345, msg.getServiceCategory());
- }
-
- public void testGetMessageIdentifierUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
- (byte)0x01,
-
- (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
- (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
- (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
- (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
- (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
- (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
- (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
- (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
- (byte)0x34
- };
-
- SmsCbMessage msg = createFromPdu(pdu);
-
- assertEquals("Unexpected message identifier decoded", 12345, msg.getServiceCategory());
- }
-
- public void testGetMessageCode() {
- byte[] pdu = {
- (byte)0x2A, (byte)0xA5, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
- (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
- (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
- (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
- (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
- (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
- (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
- (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
- };
-
- SmsCbMessage msg = createFromPdu(pdu);
- int messageCode = (msg.getSerialNumber() & 0x3ff0) >> 4;
-
- assertEquals("Unexpected message code decoded", 682, messageCode);
- }
-
- public void testGetMessageCodeUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
- (byte)0x01,
-
- (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
- (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
- (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
- (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
- (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
- (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
- (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
- (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
- (byte)0x34
- };
-
- SmsCbMessage msg = createFromPdu(pdu);
- int messageCode = (msg.getSerialNumber() & 0x3ff0) >> 4;
-
- assertEquals("Unexpected message code decoded", 682, messageCode);
- }
-
- public void testGetUpdateNumber() {
- byte[] pdu = {
- (byte)0x2A, (byte)0xA5, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
- (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
- (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
- (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
- (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
- (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
- (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
- (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
- };
-
- SmsCbMessage msg = createFromPdu(pdu);
- int updateNumber = msg.getSerialNumber() & 0x000f;
-
- assertEquals("Unexpected update number decoded", 5, updateNumber);
- }
-
- public void testGetUpdateNumberUmts() {
- byte[] pdu = {
- (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
- (byte)0x01,
-
- (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
- (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
- (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
- (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
- (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
- (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
- (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
- (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
- (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
- (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
- (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
- (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
- (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
- (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
- (byte)0x34
- };
-
- SmsCbMessage msg = createFromPdu(pdu);
- int updateNumber = msg.getSerialNumber() & 0x000f;
-
- assertEquals("Unexpected update number decoded", 5, updateNumber);
- }
-
- /* ETWS Test message including header */
- private static final byte[] etwsMessageNormal = IccUtils.hexStringToBytes("000011001101" +
- "0D0A5BAE57CE770C531790E85C716CBF3044573065B930675730" +
- "9707767A751F30025F37304463FA308C306B5099304830664E0B30553044FF086C178C615E81FF09" +
- "0000000000000000000000000000");
-
- private static final byte[] etwsMessageCancel = IccUtils.hexStringToBytes("000011001101" +
- "0D0A5148307B3069002800310030003A0035" +
- "00320029306E7DCA602557309707901F5831309253D66D883057307E3059FF086C178C615E81FF09" +
- "00000000000000000000000000000000000000000000");
-
- private static final byte[] etwsMessageTest = IccUtils.hexStringToBytes("000011031101" +
- "0D0A5BAE57CE770C531790E85C716CBF3044" +
- "573065B9306757309707300263FA308C306B5099304830664E0B30553044FF086C178C615E81FF09" +
- "00000000000000000000000000000000000000000000");
-
- // FIXME: add example of ETWS primary notification PDU
-
- public void testEtwsMessageNormal() {
- SmsCbMessage msg = createFromPdu(etwsMessageNormal);
- Log.d(TAG, msg.toString());
- assertEquals("GS mismatch", 0, msg.getGeographicalScope());
- assertEquals("serial number mismatch", 0, msg.getSerialNumber());
- assertEquals("message ID mismatch", 0x1100, msg.getServiceCategory());
- assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE,
- msg.getEtwsWarningInfo().getWarningType());
- }
-
- public void testEtwsMessageCancel() {
- SmsCbMessage msg = createFromPdu(etwsMessageCancel);
- Log.d(TAG, msg.toString());
- assertEquals("GS mismatch", 0, msg.getGeographicalScope());
- assertEquals("serial number mismatch", 0, msg.getSerialNumber());
- assertEquals("message ID mismatch", 0x1100, msg.getServiceCategory());
- assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE,
- msg.getEtwsWarningInfo().getWarningType());
- }
-
- public void testEtwsMessageTest() {
- SmsCbMessage msg = createFromPdu(etwsMessageTest);
- Log.d(TAG, msg.toString());
- assertEquals("GS mismatch", 0, msg.getGeographicalScope());
- assertEquals("serial number mismatch", 0, msg.getSerialNumber());
- assertEquals("message ID mismatch", 0x1103, msg.getServiceCategory());
- assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE,
- msg.getEtwsWarningInfo().getWarningType());
- }
-
- // Make sure we don't throw an exception if we feed random data to the PDU parser.
- public void testRandomPdus() {
- Random r = new Random(94040);
- for (int run = 0; run < 10000; run++) {
- int len = r.nextInt(140);
- byte[] data = new byte[len];
- for (int i = 0; i < len; i++) {
- data[i] = (byte) r.nextInt(256);
- }
- try {
- // this should return a SmsCbMessage object or null for invalid data
- SmsCbMessage msg = createFromPdu(data);
- } catch (Exception e) {
- Log.d(TAG, "exception thrown", e);
- fail("Exception in decoder at run " + run + " length " + len + ": " + e);
- }
- }
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java
deleted file mode 100644
index ea6836d..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- * Copyright (C) 2011 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.gsm;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.IccIoResult;
-import com.android.internal.telephony.UUSInfo;
-
-import junit.framework.Assert;
-
-/**
- * Dummy BaseCommands for UsimDataDownloadTest. Only implements UICC envelope and
- * SMS acknowledgement commands.
- */
-class UsimDataDownloadCommands extends BaseCommands {
- private static final String TAG = "UsimDataDownloadCommands";
-
- private boolean mExpectingAcknowledgeGsmSms; // true if expecting ack GSM SMS
- private boolean mExpectingAcknowledgeGsmSmsSuccess; // true if expecting ack SMS success
- private int mExpectingAcknowledgeGsmSmsFailureCause; // expecting ack SMS failure cause
- private String mExpectingAcknowledgeGsmSmsPdu; // expecting ack SMS PDU
-
- private boolean mExpectingSendEnvelope; // true to expect a send envelope command
- private String mExpectingSendEnvelopeContents; // expected string for send envelope
- private int mExpectingSendEnvelopeResponseSw1; // SW1/SW2 response status
- private int mExpectingSendEnvelopeResponseSw2; // SW1/SW2 response status
- private String mExpectingSendEnvelopeResponse; // Response string for Send Envelope
-
- UsimDataDownloadCommands(Context context) {
- super(context);
- }
-
- /**
- * Expect a call to acknowledgeLastIncomingGsmSms with success flag and failure cause.
- * @param success true if expecting success; false if expecting failure
- * @param cause the failure cause, if success is false
- */
- synchronized void expectAcknowledgeGsmSms(boolean success, int cause) {
- Assert.assertFalse("expectAcknowledgeGsmSms called twice", mExpectingAcknowledgeGsmSms);
- mExpectingAcknowledgeGsmSms = true;
- mExpectingAcknowledgeGsmSmsSuccess = success;
- mExpectingAcknowledgeGsmSmsFailureCause = cause;
- }
-
- /**
- * Expect a call to acknowledgeLastIncomingGsmSmsWithPdu with success flag and PDU.
- * @param success true if expecting success; false if expecting failure
- * @param ackPdu the acknowledgement PDU to expect
- */
- synchronized void expectAcknowledgeGsmSmsWithPdu(boolean success, String ackPdu) {
- Assert.assertFalse("expectAcknowledgeGsmSms called twice", mExpectingAcknowledgeGsmSms);
- mExpectingAcknowledgeGsmSms = true;
- mExpectingAcknowledgeGsmSmsSuccess = success;
- mExpectingAcknowledgeGsmSmsPdu = ackPdu;
- }
-
- /**
- * Expect a call to sendEnvelopeWithStatus().
- * @param contents expected envelope contents to send
- * @param sw1 simulated SW1 status to return
- * @param sw2 simulated SW2 status to return
- * @param response simulated envelope response to return
- */
- synchronized void expectSendEnvelope(String contents, int sw1, int sw2, String response) {
- Assert.assertFalse("expectSendEnvelope called twice", mExpectingSendEnvelope);
- mExpectingSendEnvelope = true;
- mExpectingSendEnvelopeContents = contents;
- mExpectingSendEnvelopeResponseSw1 = sw1;
- mExpectingSendEnvelopeResponseSw2 = sw2;
- mExpectingSendEnvelopeResponse = response;
- }
-
- synchronized void assertExpectedMethodsCalled() {
- long stopTime = SystemClock.elapsedRealtime() + 5000;
- while ((mExpectingAcknowledgeGsmSms || mExpectingSendEnvelope)
- && SystemClock.elapsedRealtime() < stopTime) {
- try {
- wait();
- } catch (InterruptedException ignored) {}
- }
- Assert.assertFalse("expecting SMS acknowledge call", mExpectingAcknowledgeGsmSms);
- Assert.assertFalse("expecting send envelope call", mExpectingSendEnvelope);
- }
-
- @Override
- public synchronized void acknowledgeLastIncomingGsmSms(boolean success, int cause,
- Message response) {
- Log.d(TAG, "acknowledgeLastIncomingGsmSms: success=" + success + ", cause=" + cause);
- Assert.assertTrue("unexpected call to acknowledge SMS", mExpectingAcknowledgeGsmSms);
- Assert.assertEquals(mExpectingAcknowledgeGsmSmsSuccess, success);
- Assert.assertEquals(mExpectingAcknowledgeGsmSmsFailureCause, cause);
- mExpectingAcknowledgeGsmSms = false;
- if (response != null) {
- AsyncResult.forMessage(response);
- response.sendToTarget();
- }
- notifyAll(); // wake up assertExpectedMethodsCalled()
- }
-
- @Override
- public synchronized void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
- Message response) {
- Log.d(TAG, "acknowledgeLastIncomingGsmSmsWithPdu: success=" + success
- + ", ackPDU= " + ackPdu);
- Assert.assertTrue("unexpected call to acknowledge SMS", mExpectingAcknowledgeGsmSms);
- Assert.assertEquals(mExpectingAcknowledgeGsmSmsSuccess, success);
- Assert.assertEquals(mExpectingAcknowledgeGsmSmsPdu, ackPdu);
- mExpectingAcknowledgeGsmSms = false;
- if (response != null) {
- AsyncResult.forMessage(response);
- response.sendToTarget();
- }
- notifyAll(); // wake up assertExpectedMethodsCalled()
- }
-
- @Override
- public synchronized void sendEnvelopeWithStatus(String contents, Message response) {
- // Add spaces between hex bytes for readability
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < contents.length(); i += 2) {
- builder.append(contents.charAt(i)).append(contents.charAt(i+1)).append(' ');
- }
- Log.d(TAG, "sendEnvelopeWithStatus: " + builder.toString());
-
- Assert.assertTrue("unexpected call to send envelope", mExpectingSendEnvelope);
- Assert.assertEquals(mExpectingSendEnvelopeContents, contents);
- mExpectingSendEnvelope = false;
-
- IccIoResult result = new IccIoResult(mExpectingSendEnvelopeResponseSw1,
- mExpectingSendEnvelopeResponseSw2, mExpectingSendEnvelopeResponse);
-
- if (response != null) {
- AsyncResult.forMessage(response, result, null);
- response.sendToTarget();
- }
- notifyAll(); // wake up assertExpectedMethodsCalled()
- }
-
- @Override
- public void setSuppServiceNotifications(boolean enable, Message result) {
- }
-
- @Override
- public void supplyIccPin(String pin, Message result) {
- }
-
- @Override
- public void supplyIccPinForApp(String pin, String aid, Message result) {
- }
-
- @Override
- public void supplyIccPuk(String puk, String newPin, Message result) {
- }
-
- @Override
- public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
- }
-
- @Override
- public void supplyIccPin2(String pin2, Message result) {
- }
-
- @Override
- public void supplyIccPin2ForApp(String pin2, String aid, Message result) {
- }
-
- @Override
- public void supplyIccPuk2(String puk2, String newPin2, Message result) {
- }
-
- @Override
- public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result) {
- }
-
- @Override
- public void changeIccPin(String oldPin, String newPin, Message result) {
- }
-
- @Override
- public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result) {
- }
-
- @Override
- public void changeIccPin2(String oldPin2, String newPin2, Message result) {
- }
-
- @Override
- public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result) {
- }
-
- @Override
- public void changeBarringPassword(String facility, String oldPwd, String newPwd,
- Message result) {
- }
-
- @Override
- public void supplyNetworkDepersonalization(String netpin, Message result) {
- }
-
- @Override
- public void getCurrentCalls(Message result) {
- }
-
- @Override
- public void getPDPContextList(Message result) {
- }
-
- @Override
- public void getDataCallList(Message result) {
- }
-
- @Override
- public void dial(String address, int clirMode, Message result) {
- }
-
- @Override
- public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
- }
-
- @Override
- public void getIMSI(Message result) {
- }
-
- @Override
- public void getIMEI(Message result) {
- }
-
- @Override
- public void getIMEISV(Message result) {
- }
-
- @Override
- public void hangupConnection(int gsmIndex, Message result) {
- }
-
- @Override
- public void hangupWaitingOrBackground(Message result) {
- }
-
- @Override
- public void hangupForegroundResumeBackground(Message result) {
- }
-
- @Override
- public void switchWaitingOrHoldingAndActive(Message result) {
- }
-
- @Override
- public void conference(Message result) {
- }
-
- @Override
- public void setPreferredVoicePrivacy(boolean enable, Message result) {
- }
-
- @Override
- public void getPreferredVoicePrivacy(Message result) {
- }
-
- @Override
- public void separateConnection(int gsmIndex, Message result) {
- }
-
- @Override
- public void acceptCall(Message result) {
- }
-
- @Override
- public void rejectCall(Message result) {
- }
-
- @Override
- public void explicitCallTransfer(Message result) {
- }
-
- @Override
- public void getLastCallFailCause(Message result) {
- }
-
- @Override
- public void getLastPdpFailCause(Message result) {
- }
-
- @Override
- public void getLastDataCallFailCause(Message result) {
- }
-
- @Override
- public void setMute(boolean enableMute, Message response) {
- }
-
- @Override
- public void getMute(Message response) {
- }
-
- @Override
- public void getSignalStrength(Message response) {
- }
-
- @Override
- public void getVoiceRegistrationState(Message response) {
- }
-
- @Override
- public void getDataRegistrationState(Message response) {
- }
-
- @Override
- public void getOperator(Message response) {
- }
-
- @Override
- public void sendDtmf(char c, Message result) {
- }
-
- @Override
- public void startDtmf(char c, Message result) {
- }
-
- @Override
- public void stopDtmf(Message result) {
- }
-
- @Override
- public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
- }
-
- @Override
- public void sendSMS(String smscPDU, String pdu, Message response) {
- }
-
- @Override
- public void sendCdmaSms(byte[] pdu, Message response) {
- }
-
- @Override
- public void deleteSmsOnSim(int index, Message response) {
- }
-
- @Override
- public void deleteSmsOnRuim(int index, Message response) {
- }
-
- @Override
- public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
- }
-
- @Override
- public void writeSmsToRuim(int status, String pdu, Message response) {
- }
-
- @Override
- public void setRadioPower(boolean on, Message response) {
- }
-
- @Override
- public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response) {
- }
-
- @Override
- public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data,
- String pin2, Message response) {
- }
-
- @Override
- public void queryCLIP(Message response) {
- }
-
- @Override
- public void getCLIR(Message response) {
- }
-
- @Override
- public void setCLIR(int clirMode, Message response) {
- }
-
- @Override
- public void queryCallWaiting(int serviceClass, Message response) {
- }
-
- @Override
- public void setCallWaiting(boolean enable, int serviceClass, Message response) {
- }
-
- @Override
- public void setCallForward(int action, int cfReason, int serviceClass, String number,
- int timeSeconds, Message response) {
- }
-
- @Override
- public void queryCallForwardStatus(int cfReason, int serviceClass, String number,
- Message response) {
- }
-
- @Override
- public void setNetworkSelectionModeAutomatic(Message response) {
- }
-
- @Override
- public void setNetworkSelectionModeManual(String operatorNumeric, Message response) {
- }
-
- @Override
- public void getNetworkSelectionMode(Message response) {
- }
-
- @Override
- public void getAvailableNetworks(Message response) {
- }
-
- @Override
- public void getBasebandVersion(Message response) {
- }
-
- @Override
- public void queryFacilityLock(String facility, String password, int serviceClass,
- Message response) {
- }
-
- @Override
- public void queryFacilityLockForApp(String facility, String password, int serviceClass,
- String appId, Message response) {
- }
-
- @Override
- public void setFacilityLock(String facility, boolean lockState, String password,
- int serviceClass, Message response) {
- }
-
- @Override
- public void setFacilityLockForApp(String facility, boolean lockState, String password,
- int serviceClass, String appId, Message response) {
- }
-
- @Override
- public void sendUSSD(String ussdString, Message response) {
- }
-
- @Override
- public void cancelPendingUssd(Message response) {
- }
-
- @Override
- public void resetRadio(Message result) {
- }
-
- @Override
- public void setBandMode(int bandMode, Message response) {
- }
-
- @Override
- public void queryAvailableBandMode(Message response) {
- }
-
- @Override
- public void setPreferredNetworkType(int networkType, Message response) {
- }
-
- @Override
- public void getPreferredNetworkType(Message response) {
- }
-
- @Override
- public void getNeighboringCids(Message response) {
- }
-
- @Override
- public void setLocationUpdates(boolean enable, Message response) {
- }
-
- @Override
- public void getSmscAddress(Message result) {
- }
-
- @Override
- public void setSmscAddress(String address, Message result) {
- }
-
- @Override
- public void reportSmsMemoryStatus(boolean available, Message result) {
- }
-
- @Override
- public void reportStkServiceIsRunning(Message result) {
- }
-
- @Override
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- }
-
- @Override
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- }
-
- @Override
- public void sendTerminalResponse(String contents, Message response) {
- }
-
- @Override
- public void sendEnvelope(String contents, Message response) {
- }
-
- @Override
- public void handleCallSetupRequestFromSim(boolean accept, Message response) {
- }
-
- @Override
- public void setGsmBroadcastActivation(boolean activate, Message result) {
- }
-
- @Override
- public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
- }
-
- @Override
- public void getGsmBroadcastConfig(Message response) {
- }
-
- @Override
- public void getDeviceIdentity(Message response) {
- }
-
- @Override
- public void getCDMASubscription(Message response) {
- }
-
- @Override
- public void sendCDMAFeatureCode(String FeatureCode, Message response) {
- }
-
- @Override
- public void setPhoneType(int phoneType) {
- }
-
- @Override
- public void queryCdmaRoamingPreference(Message response) {
- }
-
- @Override
- public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
- }
-
- @Override
- public void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
- }
-
- @Override
- public void getCdmaSubscriptionSource(Message response) {
- }
-
- @Override
- public void setTTYMode(int ttyMode, Message response) {
- }
-
- @Override
- public void queryTTYMode(Message response) {
- }
-
- @Override
- public void setupDataCall(String radioTechnology, String profile, String apn, String user,
- String password, String authType, String protocol, Message result) {
- }
-
- @Override
- public void deactivateDataCall(int cid, int reason, Message result) {
- }
-
- @Override
- public void setCdmaBroadcastActivation(boolean activate, Message result) {
- }
-
- @Override
- public void setCdmaBroadcastConfig(int[] configValuesArray, Message result) {
- }
-
- @Override
- public void getCdmaBroadcastConfig(Message result) {
- }
-
- @Override
- public void exitEmergencyCallbackMode(Message response) {
- }
-
- @Override
- public void getIccCardStatus(Message result) {
- }
-
- @Override
- public void requestIsimAuthentication(String nonce, Message response) {
- }
-
- @Override
- public void getVoiceRadioTechnology(Message response) {
- }
-
- @Override
- public void getIMSIForApp(String aid, Message result) {
- }
-
- @Override
- public void iccIOForApp(int command, int fileid, String path, int p1, int p2, int p3,
- String data, String pin2, String aid, Message response) {
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java
deleted file mode 100644
index 6c8ba5e..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2011 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.gsm;
-
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.nio.charset.Charset;
-
-/**
- * Test SMS-PP data download to UICC.
- * Uses test messages from 3GPP TS 31.124 section 27.22.5.
- */
-public class UsimDataDownloadTest extends AndroidTestCase {
- private static final String TAG = "UsimDataDownloadTest";
-
- class TestHandlerThread extends HandlerThread {
- private UsimDataDownloadHandler mHandler;
-
- TestHandlerThread() {
- super("TestHandlerThread");
- }
-
- @Override
- protected void onLooperPrepared() {
- synchronized (this) {
- mHandler = new UsimDataDownloadHandler(mCm);
- notifyAll();
- }
- }
-
- UsimDataDownloadHandler getHandler() {
- synchronized (this) {
- while (mHandler == null) {
- try {
- wait();
- } catch (InterruptedException ignored) {}
- }
- return mHandler;
- }
- }
- }
-
- private UsimDataDownloadCommands mCm;
- private TestHandlerThread mHandlerThread;
- UsimDataDownloadHandler mHandler;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mCm = new UsimDataDownloadCommands(mContext);
- mHandlerThread = new TestHandlerThread();
- mHandlerThread.start();
- mHandler = mHandlerThread.getHandler();
- Log.d(TAG, "mHandler is constructed");
- }
-
- @Override
- protected void tearDown() throws Exception {
- mHandlerThread.quit();
- super.tearDown();
- }
-
- // SMS-PP Message 3.1.1
- private static final byte[] SMS_PP_MESSAGE_3_1_1 = {
- // Service center address
- 0x09, (byte) 0x91, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0xf8,
-
- 0x04, 0x04, (byte) 0x91, 0x21, 0x43, 0x7f, 0x16, (byte) 0x89, 0x10, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x0d, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61,
- 0x67, 0x65, 0x20, 0x31
- };
-
- // SMS-PP Download Envelope 3.1.1
- private static final String SMS_PP_ENVELOPE_3_1_1 = "d12d8202838106099111223344556677f88b1c04"
- + "049121437f16891010000000000d546573744d6573736167652031";
-
- // SMS-PP Message 3.1.5
- private static final byte[] SMS_PP_MESSAGE_3_1_5 = {
- // Service center address
- 0x09, (byte) 0x91, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0xf8,
-
- 0x44, 0x04, (byte) 0x91, 0x21, 0x43, 0x7f, (byte) 0xf6, (byte) 0x89, 0x10, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x1e, 0x02, 0x70, 0x00, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x00,
- 0x00, 0x00, (byte) 0xbf, (byte) 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc,
- (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc
- };
-
- // SMS-PP Download Envelope 3.1.5
- private static final String SMS_PP_ENVELOPE_3_1_5 = "d13e8202838106099111223344556677f88b2d44"
- + "049121437ff6891010000000001e0270000019000d00000000bfff00000000000100"
- + "dcdcdcdcdcdcdcdcdcdc";
-
- public void testDataDownloadMessage1() {
- SmsMessage message = SmsMessage.createFromPdu(SMS_PP_MESSAGE_3_1_1);
- assertTrue("message is SMS-PP data download", message.isUsimDataDownload());
-
- mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x90, 0x00, "");
- mCm.expectAcknowledgeGsmSms(true, 0);
- mHandler.startDataDownload(message);
- mCm.assertExpectedMethodsCalled();
-
- mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x90, 0x00, "0123456789");
- mCm.expectAcknowledgeGsmSmsWithPdu(true, "00077f16050123456789");
- mHandler.startDataDownload(message);
- mCm.assertExpectedMethodsCalled();
-
- mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x62, 0xff, "0123456789abcdef");
- mCm.expectAcknowledgeGsmSmsWithPdu(false, "00d5077f16080123456789abcdef");
- mHandler.startDataDownload(message);
- mCm.assertExpectedMethodsCalled();
- }
-
- public void testDataDownloadMessage5() {
- SmsMessage message = SmsMessage.createFromPdu(SMS_PP_MESSAGE_3_1_5);
- assertTrue("message is SMS-PP data download", message.isUsimDataDownload());
-
- mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_5, 0x90, 0x00, "9876543210");
- mCm.expectAcknowledgeGsmSmsWithPdu(true, "00077ff6059876543210");
- mHandler.startDataDownload(message);
- mCm.assertExpectedMethodsCalled();
-
- mCm.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_5, 0x93, 0x00, "");
- mCm.expectAcknowledgeGsmSms(false, 0xd4); // SIM toolkit busy
- mHandler.startDataDownload(message);
- mCm.assertExpectedMethodsCalled();
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
deleted file mode 100644
index 56854ed..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimServiceTableTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2011 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.gsm;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * Test UsimServiceTable class.
- */
-public class UsimServiceTableTest extends AndroidTestCase {
-
- @SmallTest
- public void testUsimServiceTable() {
- byte[] noServices = {0x00};
- byte[] service1 = {0x01, 0x00};
- byte[] service8 = {(byte) 0x80, 0x00, 0x00};
- byte[] service8And9 = {(byte) 0x80, 0x01};
- byte[] service28 = {0x00, 0x00, 0x00, 0x08};
- byte[] service89To96 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, (byte) 0xff};
-
- UsimServiceTable testTable1 = new UsimServiceTable(noServices);
- assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
- assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.FDN));
- assertFalse(testTable1.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
- UsimServiceTable testTable2 = new UsimServiceTable(service1);
- assertTrue(testTable2.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
- assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.FDN));
- assertFalse(testTable2.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
- UsimServiceTable testTable3 = new UsimServiceTable(service8);
- assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
- assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
- assertTrue(testTable3.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
- assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
- assertFalse(testTable3.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
- UsimServiceTable testTable4 = new UsimServiceTable(service8And9);
- assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
- assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.BDN_EXTENSION));
- assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.OUTGOING_CALL_INFO));
- assertTrue(testTable4.isAvailable(UsimServiceTable.UsimService.INCOMING_CALL_INFO));
- assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.SM_STORAGE));
- assertFalse(testTable4.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
- UsimServiceTable testTable5 = new UsimServiceTable(service28);
- assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
- assertTrue(testTable5.isAvailable(UsimServiceTable.UsimService.DATA_DL_VIA_SMS_PP));
- assertFalse(testTable5.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
-
- UsimServiceTable testTable6 = new UsimServiceTable(service89To96);
- assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.PHONEBOOK));
- assertFalse(testTable6.isAvailable(UsimServiceTable.UsimService.HPLMN_DIRECT_ACCESS));
- assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.ECALL_DATA));
- assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.SM_OVER_IP));
- assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.UICC_ACCESS_TO_IMS));
- assertTrue(testTable6.isAvailable(UsimServiceTable.UsimService.NAS_CONFIG_BY_USIM));
- }
-}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java
deleted file mode 100644
index 3149ee1..0000000
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/mockril/MockRilTest.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2010 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.mockril;
-
-import android.util.Log;
-import android.test.InstrumentationTestCase;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import com.android.internal.communication.MsgHeader;
-import com.android.internal.communication.Msg;
-import com.android.internal.telephony.RilChannel;
-import com.android.internal.telephony.ril_proto.RilCtrlCmds;
-import com.android.internal.telephony.ril_proto.RilCmds;
-
-import com.android.frameworks.telephonytests.TelephonyMockRilTestRunner;
-import com.google.protobuf.micro.InvalidProtocolBufferMicroException;
-
-// Test suite for test ril
-public class MockRilTest extends InstrumentationTestCase {
- private static final String TAG = "MockRilTest";
-
- RilChannel mMockRilChannel;
- TelephonyMockRilTestRunner mRunner;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mRunner = (TelephonyMockRilTestRunner)getInstrumentation();
- mMockRilChannel = mRunner.mMockRilChannel;
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- static void log(String s) {
- Log.v(TAG, s);
- }
-
- /**
- * Test Case 1: Test protobuf serialization and deserialization
- * @throws InvalidProtocolBufferMicroException
- */
- public void testProtobufSerDes() throws InvalidProtocolBufferMicroException {
- log("testProtobufSerdes E");
-
- RilCtrlCmds.CtrlRspRadioState rs = new RilCtrlCmds.CtrlRspRadioState();
- assertTrue(String.format("expected rs.state == 0 was %d", rs.getState()),
- rs.getState() == 0);
- rs.setState(1);
- assertTrue(String.format("expected rs.state == 1 was %d", rs.getState()),
- rs.getState() == 1);
-
- byte[] rs_ser = rs.toByteArray();
- RilCtrlCmds.CtrlRspRadioState rsNew = RilCtrlCmds.CtrlRspRadioState.parseFrom(rs_ser);
- assertTrue(String.format("expected rsNew.state == 1 was %d", rs.getState()),
- rs.getState() == 1);
-
- log("testProtobufSerdes X");
- }
-
- /**
- * Test case 2: Test echo command works using writeMsg & readMsg
- */
- public void testEchoMsg() throws IOException {
- log("testEchoMsg E");
-
- MsgHeader mh = new MsgHeader();
- mh.setCmd(0);
- mh.setToken(1);
- mh.setStatus(2);
- ByteBuffer data = ByteBuffer.allocate(3);
- data.put((byte)3);
- data.put((byte)4);
- data.put((byte)5);
- Msg.send(mMockRilChannel, mh, data);
-
- Msg respMsg = Msg.recv(mMockRilChannel);
- assertTrue(String.format("expected mhd.header.cmd == 0 was %d",respMsg.getCmd()),
- respMsg.getCmd() == 0);
- assertTrue(String.format("expected mhd.header.token == 1 was %d",respMsg.getToken()),
- respMsg.getToken() == 1);
- assertTrue(String.format("expected mhd.header.status == 2 was %d", respMsg.getStatus()),
- respMsg.getStatus() == 2);
- assertTrue(String.format("expected mhd.data[0] == 3 was %d", respMsg.getData(0)),
- respMsg.getData(0) == 3);
- assertTrue(String.format("expected mhd.data[1] == 4 was %d", respMsg.getData(1)),
- respMsg.getData(1) == 4);
- assertTrue(String.format("expected mhd.data[2] == 5 was %d", respMsg.getData(2)),
- respMsg.getData(2) == 5);
-
- log("testEchoMsg X");
- }
-
- /**
- * Test case 3: Test get as
- */
- public void testGetAs() {
- log("testGetAs E");
-
- // Use a message header as the protobuf data content
- MsgHeader mh = new MsgHeader();
- mh.setCmd(12345);
- mh.setToken(9876);
- mh.setStatus(7654);
- mh.setLengthData(4321);
- byte[] data = mh.toByteArray();
- MsgHeader mhResult = Msg.getAs(MsgHeader.class, data);
-
- assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()),
- mhResult.getCmd() == 12345);
- assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()),
- mhResult.getToken() == 9876);
- assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()),
- mhResult.getStatus() == 7654);
- assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()),
- mhResult.getLengthData() == 4321);
-
- Msg msg = Msg.obtain();
- msg.setData(ByteBuffer.wrap(data));
-
- mhResult = msg.getDataAs(MsgHeader.class);
-
- assertTrue(String.format("expected cmd == 12345 was %d", mhResult.getCmd()),
- mhResult.getCmd() == 12345);
- assertTrue(String.format("expected token == 9876 was %d", mhResult.getToken()),
- mhResult.getToken() == 9876);
- assertTrue(String.format("expected status == 7654 was %d", mhResult.getStatus()),
- mhResult.getStatus() == 7654);
- assertTrue(String.format("expected lengthData == 4321 was %d", mhResult.getLengthData()),
- mhResult.getLengthData() == 4321);
-
- log("testGetAs X");
- }
-
- /**
- * Test case 3: test get radio state
- */
- public void testGetRadioState() throws IOException {
- log("testGetRadioState E");
-
- Msg.send(mMockRilChannel, 1, 9876, 0, null);
-
- Msg resp = Msg.recv(mMockRilChannel);
- //resp.printHeader("testGetRadioState");
-
- assertTrue(String.format("expected cmd == 1 was %d", resp.getCmd()),
- resp.getCmd() == 1);
- assertTrue(String.format("expected token == 9876 was %d", resp.getToken()),
- resp.getToken() == 9876);
- assertTrue(String.format("expected status == 0 was %d", resp.getStatus()),
- resp.getStatus() == 0);
-
- RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
-
- int state = rsp.getState();
- log("testGetRadioState state=" + state);
- assertTrue(String.format("expected RadioState >= 0 && RadioState <= 9 was %d", state),
- ((state >= 0) && (state <= 9)));
-
- log("testGetRadioState X");
- }
-
- /**
- * Test case 5: test set radio state
- */
- public void testSetRadioState() throws IOException {
- log("testSetRadioState E");
-
- RilCtrlCmds.CtrlReqRadioState cmdrs = new RilCtrlCmds.CtrlReqRadioState();
- assertEquals(0, cmdrs.getState());
-
- cmdrs.setState(RilCmds.RADIOSTATE_SIM_NOT_READY);
- assertEquals(2, cmdrs.getState());
-
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, cmdrs);
-
- Msg resp = Msg.recv(mMockRilChannel);
- log("get response status :" + resp.getStatus());
- log("get response for command: " + resp.getCmd());
- log("get command token: " + resp.getToken());
-
- RilCtrlCmds.CtrlRspRadioState rsp = resp.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
-
- int state = rsp.getState();
- log("get response for testSetRadioState: " + state);
- assertTrue(RilCmds.RADIOSTATE_SIM_NOT_READY == state);
- }
-
- /**
- * Test case 6: test start incoming call and hangup it.
- */
- public void testStartIncomingCallAndHangup() throws IOException {
- log("testStartIncomingCallAndHangup");
- RilCtrlCmds.CtrlReqSetMTCall cmd = new RilCtrlCmds.CtrlReqSetMTCall();
- String incomingCall = "6502889108";
- // set the MT call
- cmd.setPhoneNumber(incomingCall);
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, cmd);
- // get response
- Msg resp = Msg.recv(mMockRilChannel);
- log("Get response status: " + resp.getStatus());
- assertTrue("The ril is not in a proper state to set MT calls.",
- resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
- // allow the incoming call alerting for some time
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {}
-
- // we are playing a trick to assume the current is 1
- RilCtrlCmds.CtrlHangupConnRemote hangupCmd = new RilCtrlCmds.CtrlHangupConnRemote();
- hangupCmd.setConnectionId(1);
- hangupCmd.setCallFailCause(16); // normal hangup
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, hangupCmd);
-
- // get response
- resp = Msg.recv(mMockRilChannel);
- log("Get response for hangup connection: " + resp.getStatus());
- assertTrue("CTRL_CMD_HANGUP_CONN_REMOTE failed",
- resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
- }
-
- /**
- * Test case 7: test set call transition flag
- */
- public void testSetCallTransitionFlag() throws IOException {
- log("testSetCallTransitionFlag");
- // Set flag to true:
- RilCtrlCmds.CtrlSetCallTransitionFlag cmd = new RilCtrlCmds.CtrlSetCallTransitionFlag();
- cmd.setFlag(true);
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, cmd);
-
- Msg resp = Msg.recv(mMockRilChannel);
- log("Get response status: " + resp.getStatus());
- assertTrue("Set call transition flag failed",
- resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
- // add a dialing call
- RilCtrlCmds.CtrlReqAddDialingCall cmdDialCall = new RilCtrlCmds.CtrlReqAddDialingCall();
- String phoneNumber = "5102345678";
- cmdDialCall.setPhoneNumber(phoneNumber);
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_ADD_DIALING_CALL, 0, 0, cmdDialCall);
- resp = Msg.recv(mMockRilChannel);
- log("Get response status for adding a dialing call: " + resp.getStatus());
- assertTrue("add dialing call failed",
- resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {}
-
- // send command to force call state change
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null);
- resp = Msg.recv(mMockRilChannel);
- log("Get response status: " + resp.getStatus());
- assertTrue("Set call alert failed",
- resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {}
-
- // send command to force call state change
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null);
- resp = Msg.recv(mMockRilChannel);
- log("Get response status: " + resp.getStatus());
- assertTrue("Set call active failed",
- resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
- // hangup the active all remotely
- RilCtrlCmds.CtrlHangupConnRemote hangupCmd = new RilCtrlCmds.CtrlHangupConnRemote();
- hangupCmd.setConnectionId(1);
- hangupCmd.setCallFailCause(16); // normal hangup
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, hangupCmd);
- resp = Msg.recv(mMockRilChannel);
- log("Get response for hangup connection: " + resp.getStatus());
- assertTrue("CTRL_CMD_HANGUP_CONN_REMOTE failed",
- resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
-
- // set the flag to false
- cmd.setFlag(false);
- Msg.send(mMockRilChannel, RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, cmd);
- resp = Msg.recv(mMockRilChannel);
- assertTrue("Set call transition flag failed",
- resp.getStatus() == RilCtrlCmds.CTRL_STATUS_OK);
- }
-}
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsView.java b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsView.java
index b3b3756..041782d 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsView.java
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsView.java
@@ -105,7 +105,7 @@
}
void setAccel(float x, float y, float z) {
- if (mRender == null) {
+ if ((mRender == null) || (mRS == null)) {
return;
}
mRender.setAccel(x, -y);
diff --git a/tests/permission/Android.mk b/tests/permission/Android.mk
index a6df98e..31a0daf 100644
--- a/tests/permission/Android.mk
+++ b/tests/permission/Android.mk
@@ -7,7 +7,7 @@
# Include all test java files.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
LOCAL_PACKAGE_NAME := FrameworkPermissionTests
include $(BUILD_PACKAGE)
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index f2fa3f5..46b8a27 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -58,7 +58,7 @@
// The default to use if no other ignore pattern is defined.
const char * const gDefaultIgnoreAssets =
- "!.svn:!.git:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~";
+ "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~";
// The ignore pattern that can be passed via --ignore-assets in Main.cpp
const char * gUserIgnoreAssets = NULL;
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index d0a81dc..d9b0681 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -29,8 +29,11 @@
LOCAL_CFLAGS += -Wno-format-y2k
+ifeq (darwin,$(HOST_OS))
+LOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS
+endif
-LOCAL_C_INCLUDES += external/expat/lib
+
LOCAL_C_INCLUDES += external/libpng
LOCAL_C_INCLUDES += external/zlib
LOCAL_C_INCLUDES += build/libs/host/include
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 8e0be1c..fde3bd6 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -51,9 +51,8 @@
mUpdate(false), mExtending(false),
mRequireLocalization(false), mPseudolocalize(false),
mWantUTF16(false), mValues(false),
- mCompressionMethod(0), mOutputAPKFile(NULL),
+ mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),
mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
- mIsOverlayPackage(false),
mAutoAddOverlay(false), mGenDependencies(false),
mAssetSourceDir(NULL),
mCrunchedOutputDir(NULL), mProguardFile(NULL),
@@ -108,8 +107,6 @@
void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; }
const char* getInstrumentationPackageNameOverride() const { return mInstrumentationPackageNameOverride; }
void setInstrumentationPackageNameOverride(const char * val) { mInstrumentationPackageNameOverride = val; }
- bool getIsOverlayPackage() const { return mIsOverlayPackage; }
- void setIsOverlayPackage(bool val) { mIsOverlayPackage = val; }
bool getAutoAddOverlay() { return mAutoAddOverlay; }
void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
bool getGenDependencies() { return mGenDependencies; }
@@ -255,7 +252,6 @@
const char* mOutputAPKFile;
const char* mManifestPackageNameOverride;
const char* mInstrumentationPackageNameOverride;
- bool mIsOverlayPackage;
bool mAutoAddOverlay;
bool mGenDependencies;
const char* mAssetSourceDir;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index d48394a..f398de0 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -69,7 +69,6 @@
" [-F apk-file] [-J R-file-dir] \\\n"
" [--product product1,product2,...] \\\n"
" [-c CONFIGS] [--preferred-configurations CONFIGS] \\\n"
- " [-o] \\\n"
" [raw-files-dir [raw-files-dir] ...] \\\n"
" [--output-text-symbols DIR]\n"
"\n"
@@ -111,7 +110,6 @@
" -j specify a jar or zip file containing classes to include\n"
" -k junk path of file(s) added\n"
" -m make package directories under location specified by -J\n"
- " -o create overlay package (ie only resources; expects <overlay-package> in manifest)\n"
#if 0
" -p pseudolocalize the default configuration\n"
#endif
@@ -305,9 +303,6 @@
case 'm':
bundle.setMakePackageDirs(true);
break;
- case 'o':
- bundle.setIsOverlayPackage(true);
- break;
#if 0
case 'p':
bundle.setPseudolocalize(true);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 0195727..d98fe65 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2749,6 +2749,12 @@
const bool filterable = (typeName != mipmap16);
const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0;
+
+ // Until a non-NO_ENTRY value has been written for a resource,
+ // that resource is invalid; validResources[i] represents
+ // the item at t->getOrderedConfigs().itemAt(i).
+ Vector<bool> validResources;
+ validResources.insertAt(false, 0, N);
// First write the typeSpec chunk, containing information about
// each resource entry in this type.
@@ -2885,6 +2891,7 @@
if (amt < 0) {
return amt;
}
+ validResources.editItemAt(ei) = true;
} else {
index[ei] = htodl(ResTable_type::NO_ENTRY);
}
@@ -2895,6 +2902,14 @@
(((uint8_t*)data->editData()) + typeStart);
tHeader->header.size = htodl(data->getSize()-typeStart);
}
+
+ for (size_t i = 0; i < N; ++i) {
+ if (!validResources[i]) {
+ sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
+ fprintf(stderr, "warning: no entries written for %s/%s\n",
+ String8(typeName).string(), String8(c->getName()).string());
+ }
+ }
}
// Fill in the rest of the package information.
@@ -3723,9 +3738,7 @@
{
sp<Package> p = mPackages.valueFor(package);
if (p == NULL) {
- if (mBundle->getIsOverlayPackage()) {
- p = new Package(package, 0x00);
- } else if (mIsAppPackage) {
+ if (mIsAppPackage) {
if (mHaveAppPackage) {
fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n"
"Use -x to create extended resources.\n");
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index d501008..16050b2 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -21,7 +21,7 @@
#include <ctype.h>
#include <errno.h>
-#include <expat.h>
+#include <libexpat/expat.h>
using namespace android;
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 0dba950..dcbe7db 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -511,7 +511,8 @@
namespaces.pop();
} else if (code == ResXMLTree::TEXT) {
size_t len;
- printf("%sC: \"%s\"\n", prefix.string(), String8(block->getText(&len)).string());
+ printf("%sC: \"%s\"\n", prefix.string(),
+ ResTable::normalizeForOutput(String8(block->getText(&len)).string()).string());
}
}
diff --git a/tools/aidl/generate_java_binder.cpp b/tools/aidl/generate_java_binder.cpp
index 2e459a8..f80a388 100644
--- a/tools/aidl/generate_java_binder.cpp
+++ b/tools/aidl/generate_java_binder.cpp
@@ -54,7 +54,7 @@
// asBinder
Method* asBinder = new Method;
- asBinder->modifiers = PUBLIC;
+ asBinder->modifiers = PUBLIC | OVERRIDE;
asBinder->returnType = IBINDER_TYPE;
asBinder->name = "asBinder";
asBinder->statements = new StatementBlock;
@@ -117,7 +117,7 @@
queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
IInterfaceType* iinType = new IInterfaceType();
Variable *iin = new Variable(iinType, "iin");
- VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, iinType);
+ VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, NULL);
m->statements->Add(iinVd);
// Ensure the instance type of the local object is as expected.
@@ -181,7 +181,7 @@
// IBinder asBinder()
Method* asBinder = new Method;
- asBinder->modifiers = PUBLIC;
+ asBinder->modifiers = PUBLIC | OVERRIDE;
asBinder->returnType = IBINDER_TYPE;
asBinder->name = "asBinder";
asBinder->statements = new StatementBlock;
@@ -384,7 +384,7 @@
// == the proxy method ===================================================
Method* proxy = new Method;
proxy->comment = gather_comments(method->comments_token->extra);
- proxy->modifiers = PUBLIC;
+ proxy->modifiers = PUBLIC | OVERRIDE;
proxy->returnType = NAMES.Search(method->type.type.data);
proxy->returnTypeDimension = method->type.dimension;
proxy->name = method->name.data;
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 9fb000e..a5db7b1 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -3,7 +3,7 @@
<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/ninepatch/ninepatch-prebuilt.jar"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/tools-common/tools-common-prebuilt.jar"/>
diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath
index 027bc67..2b32e09 100644
--- a/tools/layoutlib/bridge/tests/.classpath
+++ b/tools/layoutlib/bridge/tests/.classpath
@@ -4,7 +4,7 @@
<classpathentry kind="src" path="res"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="output" path="bin"/>
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
new file mode 100755
index 0000000..c988c70
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
@@ -0,0 +1,787 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+import com.android.tools.layoutlib.annotations.VisibleForTesting;
+import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.signature.SignatureReader;
+import org.objectweb.asm.signature.SignatureVisitor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Analyzes the input JAR using the ASM java bytecode manipulation library
+ * to list the classes and their dependencies. A "dependency" is a class
+ * used by another class.
+ */
+public class DependencyFinder {
+
+ // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
+
+ /** Output logger. */
+ private final Log mLog;
+
+ /**
+ * Creates a new analyzer.
+ *
+ * @param log The log output.
+ */
+ public DependencyFinder(Log log) {
+ mLog = log;
+ }
+
+ /**
+ * Starts the analysis using parameters from the constructor.
+ *
+ * @param osJarPath The input source JARs to parse.
+ * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }.
+ * [1]: map { missing class FQCN => set of FQCN class that uses it. }
+ */
+ public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException {
+
+ Map<String, ClassReader> zipClasses = parseZip(osJarPath);
+ mLog.info("Found %d classes in input JAR%s.",
+ zipClasses.size(),
+ osJarPath.size() > 1 ? "s" : "");
+
+ Map<String, Set<String>> deps = findClassesDeps(zipClasses);
+
+ Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet());
+
+ List<Map<String, Set<String>>> result = new ArrayList<Map<String,Set<String>>>(2);
+ result.add(deps);
+ result.add(missing);
+ return result;
+ }
+
+ /**
+ * Prints dependencies to the current logger, found stuff and missing stuff.
+ */
+ public void printAllDeps(List<Map<String, Set<String>>> result) {
+ assert result.size() == 2;
+ Map<String, Set<String>> deps = result.get(0);
+ Map<String, Set<String>> missing = result.get(1);
+
+ // Print all dependences found in the format:
+ // +Found: <FQCN from zip>
+ // uses: FQCN
+
+ mLog.info("++++++ %d Entries found in source JARs", deps.size());
+ mLog.info("");
+
+ for (Entry<String, Set<String>> entry : deps.entrySet()) {
+ mLog.info( "+Found : %s", entry.getKey());
+ for (String dep : entry.getValue()) {
+ mLog.info(" uses: %s", dep);
+ }
+
+ mLog.info("");
+ }
+
+
+ // Now print all missing dependences in the format:
+ // -Missing <FQCN>:
+ // used by: <FQCN>
+
+ mLog.info("");
+ mLog.info("------ %d Entries missing from source JARs", missing.size());
+ mLog.info("");
+
+ for (Entry<String, Set<String>> entry : missing.entrySet()) {
+ mLog.info( "-Missing : %s", entry.getKey());
+ for (String dep : entry.getValue()) {
+ mLog.info(" used by: %s", dep);
+ }
+
+ mLog.info("");
+ }
+ }
+
+ /**
+ * Prints only a summary of the missing dependencies to the current logger.
+ */
+ public void printMissingDeps(List<Map<String, Set<String>>> result) {
+ assert result.size() == 2;
+ @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0);
+ Map<String, Set<String>> missing = result.get(1);
+
+ for (String fqcn : missing.keySet()) {
+ mLog.info("%s", fqcn);
+ }
+ }
+
+ // ----------------
+
+ /**
+ * Parses a JAR file and returns a list of all classes founds using a map
+ * class name => ASM ClassReader. Class names are in the form "android.view.View".
+ */
+ Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
+ TreeMap<String, ClassReader> classes = new TreeMap<String, ClassReader>();
+
+ for (String jarPath : jarPathList) {
+ ZipFile zip = new ZipFile(jarPath);
+ Enumeration<? extends ZipEntry> entries = zip.entries();
+ ZipEntry entry;
+ while (entries.hasMoreElements()) {
+ entry = entries.nextElement();
+ if (entry.getName().endsWith(".class")) {
+ ClassReader cr = new ClassReader(zip.getInputStream(entry));
+ String className = classReaderToClassName(cr);
+ classes.put(className, cr);
+ }
+ }
+ }
+
+ return classes;
+ }
+
+ /**
+ * Utility that returns the fully qualified binary class name for a ClassReader.
+ * E.g. it returns something like android.view.View.
+ */
+ static String classReaderToClassName(ClassReader classReader) {
+ if (classReader == null) {
+ return null;
+ } else {
+ return classReader.getClassName().replace('/', '.');
+ }
+ }
+
+ /**
+ * Utility that returns the fully qualified binary class name from a path-like FQCN.
+ * E.g. it returns android.view.View from android/view/View.
+ */
+ static String internalToBinaryClassName(String className) {
+ if (className == null) {
+ return null;
+ } else {
+ return className.replace('/', '.');
+ }
+ }
+
+ /**
+ * Finds all dependencies for all classes in keepClasses which are also
+ * listed in zipClasses. Returns a map of all the dependencies found.
+ */
+ Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) {
+
+ // The dependencies that we'll collect.
+ // It's a map Class name => uses class names.
+ Map<String, Set<String>> dependencyMap = new TreeMap<String, Set<String>>();
+
+ DependencyVisitor visitor = getVisitor();
+
+ int count = 0;
+ try {
+ for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
+ String name = entry.getKey();
+
+ TreeSet<String> set = new TreeSet<String>();
+ dependencyMap.put(name, set);
+ visitor.setDependencySet(set);
+
+ ClassReader cr = entry.getValue();
+ cr.accept(visitor, 0 /* flags */);
+
+ visitor.setDependencySet(null);
+
+ mLog.debugNoln("Visited %d classes\r", ++count);
+ }
+ } finally {
+ mLog.debugNoln("\n");
+ }
+
+ return dependencyMap;
+ }
+
+ /**
+ * Computes which classes FQCN were found as dependencies that are NOT listed
+ * in the original JAR classes.
+ *
+ * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}.
+ * @param zipClasses The set of all classes FQCN found in the JAR files.
+ * @return A map { FQCN not found in the zipClasses => classes using it }
+ */
+ private Map<String, Set<String>> findMissingClasses(
+ Map<String, Set<String>> deps,
+ Set<String> zipClasses) {
+ Map<String, Set<String>> missing = new TreeMap<String, Set<String>>();
+
+ for (Entry<String, Set<String>> entry : deps.entrySet()) {
+ String name = entry.getKey();
+
+ for (String dep : entry.getValue()) {
+ if (!zipClasses.contains(dep)) {
+ // This dependency doesn't exist in the zip classes.
+ Set<String> set = missing.get(dep);
+ if (set == null) {
+ set = new TreeSet<String>();
+ missing.put(dep, set);
+ }
+ set.add(name);
+ }
+ }
+
+ }
+
+ return missing;
+ }
+
+
+ // ----------------------------------
+
+ /**
+ * Instantiates a new DependencyVisitor. Useful for unit tests.
+ */
+ @VisibleForTesting(visibility=Visibility.PRIVATE)
+ DependencyVisitor getVisitor() {
+ return new DependencyVisitor();
+ }
+
+ /**
+ * Visitor to collect all the type dependencies from a class.
+ */
+ public class DependencyVisitor extends ClassVisitor {
+
+ private Set<String> mCurrentDepSet;
+
+ /**
+ * Creates a new visitor that will find all the dependencies for the visited class.
+ */
+ public DependencyVisitor() {
+ super(Opcodes.ASM4);
+ }
+
+ /**
+ * Sets the {@link Set} where to record direct dependencies for this class.
+ * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call.
+ */
+ public void setDependencySet(Set<String> set) {
+ mCurrentDepSet = set;
+ }
+
+ /**
+ * Considers the given class name as a dependency.
+ */
+ public void considerName(String className) {
+ if (className == null) {
+ return;
+ }
+
+ className = internalToBinaryClassName(className);
+
+ try {
+ // exclude classes that are part of the default JRE (the one executing this program)
+ if (getClass().getClassLoader().loadClass(className) != null) {
+ return;
+ }
+ } catch (ClassNotFoundException e) {
+ // ignore
+ }
+
+ // Add it to the dependency set for the currently visited class, as needed.
+ assert mCurrentDepSet != null;
+ if (mCurrentDepSet != null) {
+ mCurrentDepSet.add(className);
+ }
+ }
+
+ /**
+ * Considers this array of names using considerName().
+ */
+ public void considerNames(String[] classNames) {
+ if (classNames != null) {
+ for (String className : classNames) {
+ considerName(className);
+ }
+ }
+ }
+
+ /**
+ * Considers this signature or type signature by invoking the {@link SignatureVisitor}
+ * on it.
+ */
+ public void considerSignature(String signature) {
+ if (signature != null) {
+ SignatureReader sr = new SignatureReader(signature);
+ // SignatureReader.accept will call accessType so we don't really have
+ // to differentiate where the signature comes from.
+ sr.accept(new MySignatureVisitor());
+ }
+ }
+
+ /**
+ * Considers this {@link Type}. For arrays, the element type is considered.
+ * If the type is an object, it's internal name is considered.
+ */
+ public void considerType(Type t) {
+ if (t != null) {
+ if (t.getSort() == Type.ARRAY) {
+ t = t.getElementType();
+ }
+ if (t.getSort() == Type.OBJECT) {
+ considerName(t.getInternalName());
+ }
+ }
+ }
+
+ /**
+ * Considers a descriptor string. The descriptor is converted to a {@link Type}
+ * and then considerType() is invoked.
+ */
+ public boolean considerDesc(String desc) {
+ if (desc != null) {
+ try {
+ if (desc.length() > 0 && desc.charAt(0) == '(') {
+ // This is a method descriptor with arguments and a return type.
+ Type t = Type.getReturnType(desc);
+ considerType(t);
+
+ for (Type arg : Type.getArgumentTypes(desc)) {
+ considerType(arg);
+ }
+
+ } else {
+ Type t = Type.getType(desc);
+ considerType(t);
+ }
+ return true;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // ignore, not a valid type.
+ }
+ }
+ return false;
+ }
+
+
+ // ---------------------------------------------------
+ // --- ClassVisitor, FieldVisitor
+ // ---------------------------------------------------
+
+ // Visits a class header
+ @Override
+ public void visit(int version, int access, String name,
+ String signature, String superName, String[] interfaces) {
+ // signature is the signature of this class. May be null if the class is not a generic
+ // one, and does not extend or implement generic classes or interfaces.
+
+ if (signature != null) {
+ considerSignature(signature);
+ }
+
+ // superName is the internal of name of the super class (see getInternalName).
+ // For interfaces, the super class is Object. May be null but only for the Object class.
+ considerName(superName);
+
+ // interfaces is the internal names of the class's interfaces (see getInternalName).
+ // May be null.
+ considerNames(interfaces);
+ }
+
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ // desc is the class descriptor of the annotation class.
+ considerDesc(desc);
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public void visitAttribute(Attribute attr) {
+ // pass
+ }
+
+ // Visits the end of a class
+ @Override
+ public void visitEnd() {
+ // pass
+ }
+
+ private class MyFieldVisitor extends FieldVisitor {
+
+ public MyFieldVisitor() {
+ super(Opcodes.ASM4);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ // desc is the class descriptor of the annotation class.
+ considerDesc(desc);
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public void visitAttribute(Attribute attr) {
+ // pass
+ }
+
+ // Visits the end of a class
+ @Override
+ public void visitEnd() {
+ // pass
+ }
+ }
+
+ @Override
+ public FieldVisitor visitField(int access, String name, String desc,
+ String signature, Object value) {
+ // desc is the field's descriptor (see Type).
+ considerDesc(desc);
+
+ // signature is the field's signature. May be null if the field's type does not use
+ // generic types.
+ considerSignature(signature);
+
+ return new MyFieldVisitor();
+ }
+
+ @Override
+ public void visitInnerClass(String name, String outerName, String innerName, int access) {
+ // name is the internal name of an inner class (see getInternalName).
+ // Note: outerName/innerName seems to be null when we're reading the
+ // _Original_ClassName classes generated by layoutlib_create.
+ if (outerName != null) {
+ considerName(name);
+ }
+ }
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc,
+ String signature, String[] exceptions) {
+ // desc is the method's descriptor (see Type).
+ considerDesc(desc);
+ // signature is the method's signature. May be null if the method parameters, return
+ // type and exceptions do not use generic types.
+ considerSignature(signature);
+
+ return new MyMethodVisitor();
+ }
+
+ @Override
+ public void visitOuterClass(String owner, String name, String desc) {
+ // pass
+ }
+
+ @Override
+ public void visitSource(String source, String debug) {
+ // pass
+ }
+
+
+ // ---------------------------------------------------
+ // --- MethodVisitor
+ // ---------------------------------------------------
+
+ private class MyMethodVisitor extends MethodVisitor {
+
+ public MyMethodVisitor() {
+ super(Opcodes.ASM4);
+ }
+
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public void visitCode() {
+ // pass
+ }
+
+ // field instruction
+ @Override
+ public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+ // name is the field's name.
+ // desc is the field's descriptor (see Type).
+ considerDesc(desc);
+ }
+
+ @Override
+ public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
+ // pass
+ }
+
+ @Override
+ public void visitIincInsn(int var, int increment) {
+ // pass -- an IINC instruction
+ }
+
+ @Override
+ public void visitInsn(int opcode) {
+ // pass -- a zero operand instruction
+ }
+
+ @Override
+ public void visitIntInsn(int opcode, int operand) {
+ // pass -- a single int operand instruction
+ }
+
+ @Override
+ public void visitJumpInsn(int opcode, Label label) {
+ // pass -- a jump instruction
+ }
+
+ @Override
+ public void visitLabel(Label label) {
+ // pass -- a label target
+ }
+
+ // instruction to load a constant from the stack
+ @Override
+ public void visitLdcInsn(Object cst) {
+ if (cst instanceof Type) {
+ considerType((Type) cst);
+ }
+ }
+
+ @Override
+ public void visitLineNumber(int line, Label start) {
+ // pass
+ }
+
+ @Override
+ public void visitLocalVariable(String name, String desc,
+ String signature, Label start, Label end, int index) {
+ // desc is the type descriptor of this local variable.
+ considerDesc(desc);
+ // signature is the type signature of this local variable. May be null if the local
+ // variable type does not use generic types.
+ considerSignature(signature);
+ }
+
+ @Override
+ public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+ // pass -- a lookup switch instruction
+ }
+
+ @Override
+ public void visitMaxs(int maxStack, int maxLocals) {
+ // pass
+ }
+
+ // instruction that invokes a method
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+
+ // owner is the internal name of the method's owner class
+ if (!considerDesc(owner) && owner.indexOf('/') != -1) {
+ considerName(owner);
+ }
+ // desc is the method's descriptor (see Type).
+ considerDesc(desc);
+ }
+
+ // instruction multianewarray, whatever that is
+ @Override
+ public void visitMultiANewArrayInsn(String desc, int dims) {
+
+ // desc an array type descriptor.
+ considerDesc(desc);
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
+ boolean visible) {
+ // desc is the class descriptor of the annotation class.
+ considerDesc(desc);
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
+ // pass -- table switch instruction
+
+ }
+
+ @Override
+ public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+ // type is the internal name of the type of exceptions handled by the handler,
+ // or null to catch any exceptions (for "finally" blocks).
+ considerName(type);
+ }
+
+ // type instruction
+ @Override
+ public void visitTypeInsn(int opcode, String type) {
+ // type is the operand of the instruction to be visited. This operand must be the
+ // internal name of an object or array class.
+ considerName(type);
+ }
+
+ @Override
+ public void visitVarInsn(int opcode, int var) {
+ // pass -- local variable instruction
+ }
+ }
+
+ private class MySignatureVisitor extends SignatureVisitor {
+
+ public MySignatureVisitor() {
+ super(Opcodes.ASM4);
+ }
+
+ // ---------------------------------------------------
+ // --- SignatureVisitor
+ // ---------------------------------------------------
+
+ private String mCurrentSignatureClass = null;
+
+ // Starts the visit of a signature corresponding to a class or interface type
+ @Override
+ public void visitClassType(String name) {
+ mCurrentSignatureClass = name;
+ considerName(name);
+ }
+
+ // Visits an inner class
+ @Override
+ public void visitInnerClassType(String name) {
+ if (mCurrentSignatureClass != null) {
+ mCurrentSignatureClass += "$" + name;
+ considerName(mCurrentSignatureClass);
+ }
+ }
+
+ @Override
+ public SignatureVisitor visitArrayType() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public void visitBaseType(char descriptor) {
+ // pass -- a primitive type, ignored
+ }
+
+ @Override
+ public SignatureVisitor visitClassBound() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitExceptionType() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public void visitFormalTypeParameter(String name) {
+ // pass
+ }
+
+ @Override
+ public SignatureVisitor visitInterface() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitInterfaceBound() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitParameterType() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitReturnType() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitSuperclass() {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public SignatureVisitor visitTypeArgument(char wildcard) {
+ return new MySignatureVisitor();
+ }
+
+ @Override
+ public void visitTypeVariable(String name) {
+ // pass
+ }
+
+ @Override
+ public void visitTypeArgument() {
+ // pass
+ }
+ }
+
+
+ // ---------------------------------------------------
+ // --- AnnotationVisitor
+ // ---------------------------------------------------
+
+ private class MyAnnotationVisitor extends AnnotationVisitor {
+
+ public MyAnnotationVisitor() {
+ super(Opcodes.ASM4);
+ }
+
+ // Visits a primitive value of an annotation
+ @Override
+ public void visit(String name, Object value) {
+ // value is the actual value, whose type must be Byte, Boolean, Character, Short,
+ // Integer, Long, Float, Double, String or Type
+ if (value instanceof Type) {
+ considerType((Type) value);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String name, String desc) {
+ // desc is the class descriptor of the nested annotation class.
+ considerDesc(desc);
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(String name) {
+ return new MyAnnotationVisitor();
+ }
+
+ @Override
+ public void visitEnum(String name, String desc, String value) {
+ // desc is the class descriptor of the enumeration class.
+ considerDesc(desc);
+ }
+ }
+ }
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
index 8efd871..c3ba591 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
@@ -33,11 +33,19 @@
}
}
+ /** Similar to debug() but doesn't do a \n automatically. */
+ public void debugNoln(String format, Object... args) {
+ if (mVerbose) {
+ String s = String.format(format, args);
+ System.out.print(s);
+ }
+ }
+
public void info(String format, Object... args) {
String s = String.format(format, args);
outPrintln(s);
}
-
+
public void error(String format, Object... args) {
String s = String.format(format, args);
errPrintln(s);
@@ -50,15 +58,15 @@
pw.flush();
error(format + "\n" + sw.toString(), args);
}
-
+
/** for unit testing */
protected void errPrintln(String msg) {
System.err.println(msg);
}
-
+
/** for unit testing */
protected void outPrintln(String msg) {
System.out.println(msg);
}
-
+
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index 0dd43c1..28cd023 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -19,6 +19,8 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
@@ -48,6 +50,8 @@
public static class Options {
public boolean generatePublicAccess = true;
+ public boolean listAllDeps = false;
+ public boolean listOnlyMissingDeps = false;
}
public static final Options sOptions = new Options();
@@ -61,10 +65,23 @@
if (!processArgs(log, args, osJarPath, osDestJar)) {
log.error("Usage: layoutlib_create [-v] [-p] output.jar input.jar ...");
+ log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
System.exit(1);
}
- log.info("Output: %1$s", osDestJar[0]);
+ if (sOptions.listAllDeps || sOptions.listOnlyMissingDeps) {
+ System.exit(listDeps(osJarPath, log));
+
+ } else {
+ System.exit(createLayoutLib(osDestJar[0], osJarPath, log));
+ }
+
+
+ System.exit(1);
+ }
+
+ private static int createLayoutLib(String osDestJar, ArrayList<String> osJarPath, Log log) {
+ log.info("Output: %1$s", osDestJar);
for (String path : osJarPath) {
log.info("Input : %1$s", path);
}
@@ -72,7 +89,7 @@
try {
CreateInfo info = new CreateInfo();
Set<String> excludeClasses = getExcludedClasses(info);
- AsmGenerator agen = new AsmGenerator(log, osDestJar[0], info);
+ AsmGenerator agen = new AsmGenerator(log, osDestJar, info);
AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
new String[] { // derived from
@@ -121,17 +138,33 @@
for (String path : osJarPath) {
log.info("- Input JAR : %1$s", path);
}
- System.exit(1);
+ return 1;
}
- System.exit(0);
+ return 0;
} catch (IOException e) {
log.exception(e, "Failed to load jar");
} catch (LogAbortException e) {
e.error(log);
}
- System.exit(1);
+ return 1;
+ }
+
+ private static int listDeps(ArrayList<String> osJarPath, Log log) {
+ DependencyFinder df = new DependencyFinder(log);
+ try {
+ List<Map<String, Set<String>>> result = df.findDeps(osJarPath);
+ if (sOptions.listAllDeps) {
+ df.printAllDeps(result);
+ } else if (sOptions.listOnlyMissingDeps) {
+ df.printMissingDeps(result);
+ }
+ } catch (IOException e) {
+ log.exception(e, "Failed to load jar");
+ }
+
+ return 0;
}
private static Set<String> getExcludedClasses(CreateInfo info) {
@@ -153,14 +186,21 @@
*/
private static boolean processArgs(Log log, String[] args,
ArrayList<String> osJarPath, String[] osDestJar) {
+ boolean needs_dest = true;
for (int i = 0; i < args.length; i++) {
String s = args[i];
if (s.equals("-v")) {
log.setVerbose(true);
} else if (s.equals("-p")) {
sOptions.generatePublicAccess = false;
+ } else if (s.equals("--list-deps")) {
+ sOptions.listAllDeps = true;
+ needs_dest = false;
+ } else if (s.equals("--missing-deps")) {
+ sOptions.listOnlyMissingDeps = true;
+ needs_dest = false;
} else if (!s.startsWith("-")) {
- if (osDestJar[0] == null) {
+ if (needs_dest && osDestJar[0] == null) {
osDestJar[0] = s;
} else {
osJarPath.add(s);
@@ -175,7 +215,7 @@
log.error("Missing parameter: path to input jar");
return false;
}
- if (osDestJar[0] == null) {
+ if (needs_dest && osDestJar[0] == null) {
log.error("Missing parameter: path to output jar");
return false;
}
diff --git a/voip/java/android/net/sip/SimpleSessionDescription.java b/voip/java/android/net/sip/SimpleSessionDescription.java
index 29166dc..9fcd21d 100644
--- a/voip/java/android/net/sip/SimpleSessionDescription.java
+++ b/voip/java/android/net/sip/SimpleSessionDescription.java
@@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Locale;
/**
* An object used to manipulate messages of Session Description Protocol (SDP).
@@ -66,7 +67,7 @@
public SimpleSessionDescription(long sessionId, String address) {
address = (address.indexOf(':') < 0 ? "IN IP4 " : "IN IP6 ") + address;
mFields.parse("v=0");
- mFields.parse(String.format("o=- %d %d %s", sessionId,
+ mFields.parse(String.format(Locale.US, "o=- %d %d %s", sessionId,
System.currentTimeMillis(), address));
mFields.parse("s=-");
mFields.parse("t=0 0");
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index a447c86..17c930b 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -20,6 +20,8 @@
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pGroup;
+import android.net.wifi.p2p.WifiP2pService;
+import android.net.wifi.p2p.WifiP2pService.P2pStatus;
import android.net.wifi.p2p.WifiP2pProvDiscEvent;
import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
import android.net.wifi.StateChangeResult;
@@ -186,7 +188,7 @@
/* P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
[psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|passphrase="fKG4jMe3"]
- go_dev_addr=fa:7b:7a:42:02:13 */
+ go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT] */
private static final String P2P_GROUP_STARTED_STR = "P2P-GROUP-STARTED";
/* P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED */
@@ -594,7 +596,13 @@
if (tokens.length != 2) return;
String[] nameValue = tokens[1].split("=");
if (nameValue.length != 2) return;
- mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, nameValue[1]);
+ P2pStatus err = P2pStatus.UNKNOWN;
+ try {
+ err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, err);
} else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
new WifiP2pProvDiscEvent(dataString));
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 4bf1ca3..e520185 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -547,10 +547,9 @@
break;
}
- //TODO: Add persist behavior once the supplicant interaction is fixed for both
- // group and client scenarios
- /* Persist unless there is an explicit request to not do so*/
- //if (config.persist != WifiP2pConfig.Persist.NO) args.add("persistent");
+ if (config.netId == WifiP2pGroup.PERSISTENT_NET_ID) {
+ args.add("persistent");
+ }
if (joinExistingGroup) {
args.add("join");
@@ -592,10 +591,17 @@
return false;
}
- public boolean p2pGroupAdd() {
+ public boolean p2pGroupAdd(boolean persistent) {
+ if (persistent) {
+ return doBooleanCommand("P2P_GROUP_ADD persistent");
+ }
return doBooleanCommand("P2P_GROUP_ADD");
}
+ public boolean p2pGroupAdd(int netId) {
+ return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
+ }
+
public boolean p2pGroupRemove(String iface) {
if (TextUtils.isEmpty(iface)) return false;
return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
@@ -624,6 +630,9 @@
return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
}
+ public String p2pGetSsid(String deviceAddress) {
+ return p2pGetParam(deviceAddress, "oper_ssid");
+ }
public String p2pGetDeviceAddress() {
String status = status();
@@ -665,6 +674,24 @@
return doStringCommand("P2P_PEER " + deviceAddress);
}
+ private String p2pGetParam(String deviceAddress, String key) {
+ if (deviceAddress == null) return null;
+
+ String peerInfo = p2pPeer(deviceAddress);
+ if (peerInfo == null) return null;
+ String[] tokens= peerInfo.split("\n");
+
+ key += "=";
+ for (String token : tokens) {
+ if (token.startsWith(key)) {
+ String[] nameValue = token.split("=");
+ if (nameValue.length != 2) break;
+ return nameValue[1];
+ }
+ }
+ return null;
+ }
+
public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
/*
* P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 54f47be..a5cb855 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -697,7 +697,7 @@
setInitialState(mInitialState);
- setProcessedMessagesSize(100);
+ setLogRecSize(100);
if (DBG) setDbg(true);
//start the state machine
@@ -1151,7 +1151,7 @@
}
@Override
- protected boolean recordProcessedMessage(Message msg) {
+ protected boolean recordLogRec(Message msg) {
//Ignore screen on/off & common messages when driver has started
if (getCurrentState() == mConnectedState || getCurrentState() == mDisconnectedState) {
switch (msg.what) {
@@ -1240,14 +1240,14 @@
ip settings */
InterfaceConfiguration ifcg = null;
try {
- ifcg = mNwService.getInterfaceConfig(mInterfaceName);
+ ifcg = mNwService.getInterfaceConfig(mTetherInterfaceName);
if (ifcg != null) {
ifcg.setLinkAddress(
new LinkAddress(NetworkUtils.numericToInetAddress("0.0.0.0"), 0));
- mNwService.setInterfaceConfig(mInterfaceName, ifcg);
+ mNwService.setInterfaceConfig(mTetherInterfaceName, ifcg);
}
} catch (Exception e) {
- loge("Error resetting interface " + mInterfaceName + ", :" + e);
+ loge("Error resetting interface " + mTetherInterfaceName + ", :" + e);
}
if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
@@ -1653,7 +1653,7 @@
handlePostDhcpSetup();
mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
- mDhcpStateMachine.quit();
+ mDhcpStateMachine.doQuit();
mDhcpStateMachine = null;
}
@@ -3538,6 +3538,13 @@
if (DBG) log("Network connection lost");
handleNetworkDisconnect();
break;
+ case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
+ // Disregard auth failure events during WPS connection. The
+ // EAP sequence is retried several times, and there might be
+ // failures (especially for wps pin). We will get a WPS_XXX
+ // event at the end of the sequence anyway.
+ if (DBG) log("Ignore auth failure during WPS connection");
+ break;
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
//Throw away supplicant state changes when WPS is running.
//We will start getting supplicant state changes once we get
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 45efe3e..c6d3eae 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -881,8 +881,8 @@
//test to avoid any wifi connectivity issues
loge("ARP test initiation failure: " + se);
success = true;
- } catch (IllegalArgumentException e) {
- // ArpPeer throws exception for IPv6 address
+ } catch (IllegalArgumentException ae) {
+ log("ARP test initiation failure: " + ae);
success = true;
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index 6aea090..100e062 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -46,18 +46,8 @@
*/
public int groupOwnerIntent = -1;
- /**
- * Indicates whether the configuration is saved
- * @hide
- */
- public enum Persist {
- SYSTEM_DEFAULT,
- YES,
- NO
- }
-
/** @hide */
- public Persist persist = Persist.SYSTEM_DEFAULT;
+ public int netId = WifiP2pGroup.PERSISTENT_NET_ID;
public WifiP2pConfig() {
//set defaults
@@ -110,7 +100,7 @@
sbuf.append("\n address: ").append(deviceAddress);
sbuf.append("\n wps: ").append(wps);
sbuf.append("\n groupOwnerIntent: ").append(groupOwnerIntent);
- sbuf.append("\n persist: ").append(persist.toString());
+ sbuf.append("\n persist: ").append(netId);
return sbuf.toString();
}
@@ -125,7 +115,7 @@
deviceAddress = source.deviceAddress;
wps = new WpsInfo(source.wps);
groupOwnerIntent = source.groupOwnerIntent;
- persist = source.persist;
+ netId = source.netId;
}
}
@@ -134,7 +124,7 @@
dest.writeString(deviceAddress);
dest.writeParcelable(wps, flags);
dest.writeInt(groupOwnerIntent);
- dest.writeString(persist.name());
+ dest.writeInt(netId);
}
/** Implement the Parcelable interface */
@@ -145,7 +135,7 @@
config.deviceAddress = in.readString();
config.wps = (WpsInfo) in.readParcelable(null);
config.groupOwnerIntent = in.readInt();
- config.persist = Persist.valueOf(in.readString());
+ config.netId = in.readInt();
return config;
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index afdc9be..c86ec8b 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -231,11 +231,26 @@
return (deviceCapability & DEVICE_CAPAB_SERVICE_DISCOVERY) != 0;
}
+ /** Returns true if the device is capable of invitation {@hide}*/
+ public boolean isInvitationCapable() {
+ return (deviceCapability & DEVICE_CAPAB_INVITATION_PROCEDURE) != 0;
+ }
+
+ /** Returns true if the device reaches the limit. {@hide}*/
+ public boolean isDeviceLimit() {
+ return (deviceCapability & DEVICE_CAPAB_DEVICE_LIMIT) != 0;
+ }
+
/** Returns true if the device is a group owner */
public boolean isGroupOwner() {
return (groupCapability & GROUP_CAPAB_GROUP_OWNER) != 0;
}
+ /** Returns true if the group reaches the limit. {@hide}*/
+ public boolean isGroupLimit() {
+ return (groupCapability & GROUP_CAPAB_GROUP_LIMIT) != 0;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
index c30cc73..bc492b3 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -33,6 +33,16 @@
*/
public class WifiP2pGroup implements Parcelable {
+ /** The temporary network id.
+ * {@hide} */
+ public static final int TEMPORARY_NET_ID = -1;
+
+ /** The persistent network id.
+ * If a matching persistent profile is found, use it.
+ * Otherwise, create a new persistent profile.
+ * {@hide} */
+ public static final int PERSISTENT_NET_ID = -2;
+
/** The network name */
private String mNetworkName;
@@ -50,13 +60,17 @@
private String mInterface;
+ /** The network id in the wpa_supplicant */
+ private int mNetId;
+
/** P2P group started string pattern */
private static final Pattern groupStartedPattern = Pattern.compile(
"ssid=\"(.+)\" " +
"freq=(\\d+) " +
"(?:psk=)?([0-9a-fA-F]{64})?" +
"(?:passphrase=)?(?:\"(.{8,63})\")? " +
- "go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
+ "go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})" +
+ " ?(\\[PERSISTENT\\])?"
);
public WifiP2pGroup() {
@@ -67,13 +81,15 @@
*
* P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
* [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|
- * passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13
+ * passphrase="fKG4jMe3"] go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT]
*
* P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED
*
* P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
* bssid=fa:7b:7a:42:82:13 unknown-network
*
+ * P2P-INVITATION-RECEIVED sa=b8:f9:34:2a:c7:9d persistent=0
+ *
* Note: The events formats can be looked up in the wpa_supplicant code
* @hide
*/
@@ -100,16 +116,38 @@
//String psk = match.group(3);
mPassphrase = match.group(4);
mOwner = new WifiP2pDevice(match.group(5));
-
+ if (match.group(6) != null) {
+ mNetId = PERSISTENT_NET_ID;
+ } else {
+ mNetId = TEMPORARY_NET_ID;
+ }
} else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) {
+ String sa = null;
+ mNetId = PERSISTENT_NET_ID;
for (String token : tokens) {
String[] nameValue = token.split("=");
if (nameValue.length != 2) continue;
+ if (nameValue[0].equals("sa")) {
+ sa = nameValue[1];
+
+ // set source address into the client list.
+ WifiP2pDevice dev = new WifiP2pDevice();
+ dev.deviceAddress = nameValue[1];
+ mClients.add(dev);
+ continue;
+ }
+
if (nameValue[0].equals("go_dev_addr")) {
mOwner = new WifiP2pDevice(nameValue[1]);
continue;
}
+
+ if (nameValue[0].equals("persistent")) {
+ mOwner = new WifiP2pDevice(sa);
+ mNetId = Integer.parseInt(nameValue[1]);
+ continue;
+ }
}
} else {
throw new IllegalArgumentException("Malformed supplicant event");
@@ -212,6 +250,16 @@
return mInterface;
}
+ /** @hide */
+ public int getNetworkId() {
+ return mNetId;
+ }
+
+ /** @hide */
+ public void setNetworkId(int netId) {
+ this.mNetId = netId;
+ }
+
public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append("network: ").append(mNetworkName);
@@ -221,6 +269,7 @@
sbuf.append("\n Client: ").append(client);
}
sbuf.append("\n interface: ").append(mInterface);
+ sbuf.append("\n networkId: ").append(mNetId);
return sbuf.toString();
}
@@ -238,6 +287,7 @@
for (WifiP2pDevice d : source.getClientList()) mClients.add(d);
mPassphrase = source.getPassphrase();
mInterface = source.getInterface();
+ mNetId = source.getNetworkId();
}
}
@@ -252,6 +302,7 @@
}
dest.writeString(mPassphrase);
dest.writeString(mInterface);
+ dest.writeInt(mNetId);
}
/** Implement the Parcelable interface */
@@ -268,6 +319,7 @@
}
group.setPassphrase(in.readString());
group.setInterface(in.readString());
+ group.setNetworkId(in.readInt());
return group;
}
diff --git a/telephony/java/com/android/internal/telephony/IccException.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl
similarity index 62%
copy from telephony/java/com/android/internal/telephony/IccException.java
copy to wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl
index 1659a4e..3d8a476 100644
--- a/telephony/java/com/android/internal/telephony/IccException.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
+/**
+ * Copyright (c) 2012, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,17 +14,6 @@
* limitations under the License.
*/
-package com.android.internal.telephony;
+package android.net.wifi.p2p;
-/**
- * {@hide}
- */
-public class IccException extends Exception {
- public IccException() {
-
- }
-
- public IccException(String s) {
- super(s);
- }
-}
+parcelable WifiP2pGroupList;
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
new file mode 100644
index 0000000..3459a5a
--- /dev/null
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net.wifi.p2p;
+
+import java.util.Collection;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.LruCache;
+
+
+/**
+ * A class representing a Wi-Fi P2p group list
+ *
+ * {@see WifiP2pManager}
+ * @hide
+ */
+public class WifiP2pGroupList implements Parcelable {
+
+ private static final int CREDENTIAL_MAX_NUM = 32;
+
+ private LruCache<Integer, WifiP2pGroup> mGroups;
+ private GroupDeleteListener mListener;
+ private boolean isClearCalled = false;
+
+ public interface GroupDeleteListener {
+ public void onDeleteGroup(int netId);
+ }
+
+ WifiP2pGroupList() {
+ this(null);
+ }
+
+ WifiP2pGroupList(GroupDeleteListener listener) {
+ mListener = listener;
+ mGroups = new LruCache<Integer, WifiP2pGroup>(CREDENTIAL_MAX_NUM) {
+ @Override
+ protected void entryRemoved(boolean evicted, Integer netId,
+ WifiP2pGroup oldValue, WifiP2pGroup newValue) {
+ if (mListener != null && !isClearCalled) {
+ mListener.onDeleteGroup(oldValue.getNetworkId());
+ }
+ }
+ };
+ }
+
+ /**
+ * Return the list of p2p group.
+ *
+ * @return the list of p2p group.
+ */
+ public Collection<WifiP2pGroup> getGroupList() {
+ return mGroups.snapshot().values();
+ }
+
+ /**
+ * Add the specified group to this group list.
+ *
+ * @param group
+ */
+ void add(WifiP2pGroup group) {
+ mGroups.put(group.getNetworkId(), group);
+ }
+
+ /**
+ * Remove the group with the specified network id from this group list.
+ *
+ * @param netId
+ */
+ void remove(int netId) {
+ mGroups.remove(netId);
+ }
+
+ /**
+ * Remove the group with the specified device address from this group list.
+ *
+ * @param deviceAddress
+ */
+ void remove(String deviceAddress) {
+ remove(getNetworkId(deviceAddress));
+ }
+
+ /**
+ * Clear the group.
+ */
+ boolean clear() {
+ if (mGroups.size() == 0) return false;
+ isClearCalled = true;
+ mGroups.evictAll();
+ isClearCalled = false;
+ return true;
+ }
+
+ /**
+ * Return the network id of the group owner profile with the specified p2p device
+ * address.
+ * If more than one persistent group of the same address is present in the list,
+ * return the first one.
+ *
+ * @param deviceAddress p2p device address.
+ * @return the network id. if not found, return -1.
+ */
+ int getNetworkId(String deviceAddress) {
+ if (deviceAddress == null) return -1;
+
+ final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+ for (WifiP2pGroup grp: groups) {
+ if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress)) {
+ // update cache ordered.
+ mGroups.get(grp.getNetworkId());
+ return grp.getNetworkId();
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Return the network id of the group with the specified p2p device address
+ * and the ssid.
+ *
+ * @param deviceAddress p2p device address.
+ * @param ssid ssid.
+ * @return the network id. if not found, return -1.
+ */
+ int getNetworkId(String deviceAddress, String ssid) {
+ if (deviceAddress == null || ssid == null) {
+ return -1;
+ }
+
+ final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+ for (WifiP2pGroup grp: groups) {
+ if (deviceAddress.equalsIgnoreCase(grp.getOwner().deviceAddress) &&
+ ssid.equals(grp.getNetworkName())) {
+ // update cache ordered.
+ mGroups.get(grp.getNetworkId());
+ return grp.getNetworkId();
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Return the group owner address of the group with the specified network id
+ *
+ * @param netId network id.
+ * @return the address. if not found, return null.
+ */
+ String getOwnerAddr(int netId) {
+ WifiP2pGroup grp = mGroups.get(netId);
+ if (grp != null) {
+ return grp.getOwner().deviceAddress;
+ }
+ return null;
+ }
+
+ /**
+ * Return true if this group list contains the specified network id.
+ * This function does NOT update LRU information.
+ * It means the internal queue is NOT reordered.
+ *
+ * @param netId network id.
+ * @return true if the specified network id is present in this group list.
+ */
+ boolean contains(int netId) {
+ final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+ for (WifiP2pGroup grp: groups) {
+ if (netId == grp.getNetworkId()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String toString() {
+ StringBuffer sbuf = new StringBuffer();
+
+ final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+ for (WifiP2pGroup grp: groups) {
+ sbuf.append(grp).append("\n");
+ }
+ return sbuf.toString();
+ }
+
+ /** Implement the Parcelable interface */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface */
+ public void writeToParcel(Parcel dest, int flags) {
+ final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
+ dest.writeInt(groups.size());
+ for(WifiP2pGroup group : groups) {
+ dest.writeParcelable(group, flags);
+ }
+ }
+
+ /** Implement the Parcelable interface */
+ public static final Creator<WifiP2pGroupList> CREATOR =
+ new Creator<WifiP2pGroupList>() {
+ public WifiP2pGroupList createFromParcel(Parcel in) {
+ WifiP2pGroupList grpList = new WifiP2pGroupList();
+
+ int deviceCount = in.readInt();
+ for (int i = 0; i < deviceCount; i++) {
+ grpList.add((WifiP2pGroup)in.readParcelable(null));
+ }
+ return grpList;
+ }
+
+ public WifiP2pGroupList[] newArray(int size) {
+ return new WifiP2pGroupList[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 2c25e9d..96d3a7f 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -34,10 +34,10 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.WorkSource;
-import android.os.Messenger;
import android.util.Log;
import com.android.internal.util.AsyncChannel;
@@ -267,6 +267,13 @@
public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
/**
+ * Broadcast intent action indicating that remembered persistent groups have changed.
+ * @hide
+ */
+ public static final String WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION =
+ "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED";
+
+ /**
* The lookup key for a {@link #String} object.
* Retrieve with {@link android.os.Bundle#getString(String)}.
* @hide
@@ -436,6 +443,18 @@
/** @hide */
public static final int SHOW_PIN_REQUESTED = BASE + 58;
+ /** @hide */
+ public static final int DELETE_PERSISTENT_GROUP = BASE + 59;
+ /** @hide */
+ public static final int DELETE_PERSISTENT_GROUP_FAILED = BASE + 60;
+ /** @hide */
+ public static final int DELETE_PERSISTENT_GROUP_SUCCEEDED = BASE + 61;
+
+ /** @hide */
+ public static final int REQUEST_PERSISTENT_GROUP_INFO = BASE + 62;
+ /** @hide */
+ public static final int RESPONSE_PERSISTENT_GROUP_INFO = BASE + 63;
+
/**
* Create a new WifiP2pManager instance. Applications use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -657,6 +676,15 @@
public void onDetached(int reason);
}
+ /** Interface for callback invocation when stored group info list is available {@hide}*/
+ public interface PersistentGroupInfoListener {
+ /**
+ * The requested stored p2p group info list is available
+ * @param groups Wi-Fi p2p group info list
+ */
+ public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups);
+ }
+
/**
* A channel that connects the application to the Wifi p2p framework.
* Most p2p operations require a Channel as an argument. An instance of Channel is obtained
@@ -713,6 +741,7 @@
case WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED:
case WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED:
case WifiP2pManager.SET_DEVICE_NAME_FAILED:
+ case WifiP2pManager.DELETE_PERSISTENT_GROUP_FAILED:
if (listener != null) {
((ActionListener) listener).onFailure(message.arg1);
}
@@ -732,6 +761,7 @@
case WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED:
case WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED:
case WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED:
+ case WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED:
if (listener != null) {
((ActionListener) listener).onSuccess();
}
@@ -786,6 +816,13 @@
mDialogListener = null;
}
break;
+ case WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO:
+ WifiP2pGroupList groups = (WifiP2pGroupList) message.obj;
+ if (listener != null) {
+ ((PersistentGroupInfoListener) listener).
+ onPersistentGroupInfoAvailable(groups);
+ }
+ break;
default:
Log.d(TAG, "Ignored " + message);
break;
@@ -995,7 +1032,8 @@
*/
public void createGroup(Channel c, ActionListener listener) {
checkChannel(c);
- c.mAsyncChannel.sendMessage(CREATE_GROUP, 0, c.putListener(listener));
+ c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.PERSISTENT_NET_ID,
+ c.putListener(listener));
}
/**
@@ -1297,6 +1335,40 @@
}
/**
+ * Delete a stored persistent group from the system settings.
+ *
+ * <p> The function call immediately returns after sending a persistent group removal request
+ * to the framework. The application is notified of a success or failure to initiate
+ * group removal through listener callbacks {@link ActionListener#onSuccess} or
+ * {@link ActionListener#onFailure}.
+ *
+ * <p>The persistent p2p group list stored in the system can be obtained by
+ * {@link #requestPersistentGroupInfo(Channel, PersistentGroupInfoListener)} and
+ * a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}.
+ *
+ * @param c is the channel created at {@link #initialize}
+ * @param netId he network id of the p2p group.
+ * @param listener for callbacks on success or failure. Can be null.
+ * @hide
+ */
+ public void deletePersistentGroup(Channel c, int netId, ActionListener listener) {
+ checkChannel(c);
+ c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener));
+ }
+
+ /**
+ * Request a list of all the persistent p2p groups stored in system.
+ *
+ * @param c is the channel created at {@link #initialize}
+ * @param listener for callback when persistent group info list is available. Can be null.
+ * @hide
+ */
+ public void requestPersistentGroupInfo(Channel c, PersistentGroupInfoListener listener) {
+ checkChannel(c);
+ c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener));
+ }
+
+ /**
* Get a reference to WifiP2pService handler. This is used to establish
* an AsyncChannel communication with WifiService
*
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 9e004d0..0be2b27 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -45,6 +45,7 @@
import android.net.wifi.WifiNative;
import android.net.wifi.WifiStateMachine;
import android.net.wifi.WpsInfo;
+import android.net.wifi.p2p.WifiP2pGroupList.GroupDeleteListener;
import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
@@ -118,6 +119,13 @@
private static final Boolean JOIN_GROUP = true;
private static final Boolean FORM_GROUP = false;
+ private static final Boolean TRY_REINVOCATION = true;;
+ private static final Boolean NO_REINVOCATION = false;
+
+ private static final int CONNECT_FAILURE = -1;
+ private static final int CONNECT_SUCCESS = 0;
+ private static final int NEEDS_PROVISION_REQ = 1;
+
/* Two minutes comes from the wpa_supplicant setting */
private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
private static int mGroupCreatingTimeoutIndex = 0;
@@ -191,6 +199,84 @@
private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
private static final String SERVER_ADDRESS = "192.168.49.1";
+ /**
+ * Error code definition.
+ * see the Table.8 in the WiFi Direct specification for the detail.
+ */
+ public static enum P2pStatus {
+ /* Success. */
+ SUCCESS,
+
+ /* The target device is currently unavailable. */
+ INFORMATION_IS_CURRENTLY_UNAVAILABLE,
+
+ /* Protocol error. */
+ INCOMPATIBLE_PARAMETERS,
+
+ /* The target device reached the limit of the number of the connectable device.
+ * For example, device limit or group limit is set. */
+ LIMIT_REACHED,
+
+ /* Protocol error. */
+ INVALID_PARAMETER,
+
+ /* Unable to accommodate request. */
+ UNABLE_TO_ACCOMMODATE_REQUEST,
+
+ /* Previous protocol error, or disruptive behavior. */
+ PREVIOUS_PROTOCOL_ERROR,
+
+ /* There is no common channels the both devices can use. */
+ NO_COMMON_CHANNE,
+
+ /* Unknown p2p group. For example, Device A tries to invoke the previous persistent group,
+ * but device B has removed the specified credential already. */
+ UNKNOWN_P2P_GROUP,
+
+ /* Both p2p devices indicated an intent of 15 in group owner negotiation. */
+ BOTH_GO_INTENT_15,
+
+ /* Incompatible provisioning method. */
+ INCOMPATIBLE_PROVISIONING_METHOD,
+
+ /* Rejected by user */
+ REJECTED_BY_USER,
+
+ /* Unknown error */
+ UNKNOWN;
+
+ public static P2pStatus valueOf(int error) {
+ switch(error) {
+ case 0 :
+ return SUCCESS;
+ case 1:
+ return INFORMATION_IS_CURRENTLY_UNAVAILABLE;
+ case 2:
+ return INCOMPATIBLE_PARAMETERS;
+ case 3:
+ return LIMIT_REACHED;
+ case 4:
+ return INVALID_PARAMETER;
+ case 5:
+ return UNABLE_TO_ACCOMMODATE_REQUEST;
+ case 6:
+ return PREVIOUS_PROTOCOL_ERROR;
+ case 7:
+ return NO_COMMON_CHANNE;
+ case 8:
+ return UNKNOWN_P2P_GROUP;
+ case 9:
+ return BOTH_GO_INTENT_15;
+ case 10:
+ return INCOMPATIBLE_PROVISIONING_METHOD;
+ case 11:
+ return REJECTED_BY_USER;
+ default:
+ return UNKNOWN;
+ }
+ }
+ }
+
public WifiP2pService(Context context) {
mContext = context;
@@ -273,6 +359,16 @@
private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
private WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
+ private WifiP2pGroupList mGroups = new WifiP2pGroupList(
+ new GroupDeleteListener() {
+ @Override
+ public void onDeleteGroup(int netId) {
+ if (DBG) logd("called onDeleteGroup() netId=" + netId);
+ mWifiNative.removeNetwork(netId);
+ mWifiNative.saveConfig();
+ sendP2pPersistentGroupsChangedBroadcast();
+ }
+ });
private WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
private WifiP2pGroup mGroup;
@@ -395,6 +491,10 @@
replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
WifiP2pManager.BUSY);
break;
+ case WifiP2pManager.DELETE_PERSISTENT_GROUP:
+ replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
+ WifiP2pManager.BUSY);
+ break;
case WifiP2pManager.REQUEST_PEERS:
replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
break;
@@ -404,6 +504,10 @@
case WifiP2pManager.REQUEST_GROUP_INFO:
replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO, mGroup);
break;
+ case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
+ replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
+ mGroups);
+ break;
case WifiP2pManager.SET_DIALOG_LISTENER:
String appPkgName = (String)message.getData().getString(
WifiP2pManager.APP_PKG_BUNDLE_KEY);
@@ -520,6 +624,10 @@
replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
WifiP2pManager.P2P_UNSUPPORTED);
break;
+ case WifiP2pManager.DELETE_PERSISTENT_GROUP:
+ replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
+ WifiP2pManager.P2P_UNSUPPORTED);
+ break;
default:
return NOT_HANDLED;
}
@@ -626,6 +734,8 @@
break;
case WifiStateMachine.CMD_DISABLE_P2P:
if (mPeers.clear()) sendP2pPeersChangedBroadcast();
+ if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
+
mWifiNative.closeSupplicantConnection();
transitionTo(mP2pDisablingState);
break;
@@ -734,6 +844,11 @@
sendServiceResponse(resp);
}
break;
+ case WifiP2pManager.DELETE_PERSISTENT_GROUP:
+ if (DBG) logd(getName() + " delete persistent group");
+ mGroups.remove(message.arg1);
+ replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED);
+ break;
default:
return NOT_HANDLED;
}
@@ -768,47 +883,35 @@
/* Update group capability before connect */
int gc = mWifiNative.getGroupCapability(config.deviceAddress);
mPeers.updateGroupCapability(config.deviceAddress, gc);
-
- if (mSavedPeerConfig != null && config.deviceAddress.equals(
- mSavedPeerConfig.deviceAddress)) {
- mSavedPeerConfig = config;
-
- //Stop discovery before issuing connect
- mWifiNative.p2pStopFind();
- if (mPeers.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
- p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
- } else {
- p2pConnectWithPinDisplay(mSavedPeerConfig, FORM_GROUP);
- }
- transitionTo(mGroupNegotiationState);
- } else {
- mSavedPeerConfig = config;
- int netId = configuredNetworkId(mSavedPeerConfig.deviceAddress);
- if (netId >= 0) {
- //TODO: if failure, remove config and do a regular p2pConnect()
- mWifiNative.p2pReinvoke(netId, mSavedPeerConfig.deviceAddress);
- } else {
- //Stop discovery before issuing connect
- mWifiNative.p2pStopFind();
- //If peer is a GO, we do not need to send provisional discovery,
- //the supplicant takes care of it.
- if (mPeers.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
- if (DBG) logd("Sending join to GO");
- p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
- transitionTo(mGroupNegotiationState);
- } else {
- if (DBG) logd("Sending prov disc");
- transitionTo(mProvisionDiscoveryState);
- }
- }
+ int connectRet = connect(config, TRY_REINVOCATION);
+ if (connectRet == CONNECT_FAILURE) {
+ replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
+ break;
}
mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
sendP2pPeersChangedBroadcast();
replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+ if (connectRet == NEEDS_PROVISION_REQ) {
+ if (DBG) logd("Sending prov disc");
+ transitionTo(mProvisionDiscoveryState);
+ break;
+ }
+ transitionTo(mGroupNegotiationState);
+ break;
+ case WifiP2pManager.STOP_DISCOVERY:
+ if (mWifiNative.p2pStopFind()) {
+ // When discovery stops in inactive state, flush to clear
+ // state peer data
+ mWifiNative.p2pFlush();
+ mServiceDiscReqId = null;
+ replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
+ } else {
+ replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
+ WifiP2pManager.ERROR);
+ }
break;
case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
mSavedPeerConfig = (WifiP2pConfig) message.obj;
-
mAutonomousGroup = false;
mJoinExistingGroup = false;
if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
@@ -848,13 +951,6 @@
transitionTo(mUserAuthorizingInvitationState);
}
break;
- case WifiMonitor.P2P_FIND_STOPPED_EVENT:
- // When discovery stops in inactive state, flush to clear
- // state peer data
- mWifiNative.p2pFlush();
- mServiceDiscReqId = null;
- sendP2pDiscoveryChangedBroadcast(false);
- break;
case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
@@ -865,16 +961,44 @@
break;
case WifiP2pManager.CREATE_GROUP:
mAutonomousGroup = true;
- if (mWifiNative.p2pGroupAdd()) {
- replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
+ int netId = message.arg1;
+ boolean ret = false;
+ if (netId == WifiP2pGroup.PERSISTENT_NET_ID) {
+ // check if the go persistent group is present.
+ netId = mGroups.getNetworkId(mThisDevice.deviceAddress);
+ if (netId != -1) {
+ ret = mWifiNative.p2pGroupAdd(netId);
+ } else {
+ ret = mWifiNative.p2pGroupAdd(true);
+ }
+ } else {
+ ret = mWifiNative.p2pGroupAdd(false);
+ }
+
+ if (ret) {
+ replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
+ transitionTo(mGroupNegotiationState);
+ } else {
+ replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
+ WifiP2pManager.ERROR);
+ // remain at this state.
+ }
+ break;
+ case WifiMonitor.P2P_GROUP_STARTED_EVENT:
+ mGroup = (WifiP2pGroup) message.obj;
+ if (DBG) logd(getName() + " group started");
+
+ if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
+ // This is an invocation case.
+ mAutonomousGroup = false;
+ deferMessage(message);
+ transitionTo(mGroupNegotiationState);
} else {
- replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
- WifiP2pManager.ERROR);
+ return NOT_HANDLED;
}
- transitionTo(mGroupNegotiationState);
break;
default:
- return NOT_HANDLED;
+ return NOT_HANDLED;
}
return HANDLED;
}
@@ -941,10 +1065,7 @@
@Override
public void enter() {
if (DBG) logd(getName());
- if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
- mSavedPeerConfig)) {
- notifyInvitationReceived();
- }
+ notifyInvitationReceived();
}
@Override
@@ -953,11 +1074,10 @@
boolean ret = HANDLED;
switch (message.what) {
case PEER_CONNECTION_USER_ACCEPT:
- //TODO: handle persistence
- if (mJoinExistingGroup) {
- p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
- } else {
- p2pConnectWithPinDisplay(mSavedPeerConfig, FORM_GROUP);
+ if (connect(mSavedPeerConfig, TRY_REINVOCATION) == CONNECT_FAILURE) {
+ handleGroupCreationFailure();
+ transitionTo(mInactiveState);
+ break;
}
mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
sendP2pPeersChangedBroadcast();
@@ -1000,7 +1120,7 @@
if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
if (DBG) logd("Found a match " + mSavedPeerConfig);
- mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+ p2pConnectWithPinDisplay(mSavedPeerConfig);
transitionTo(mGroupNegotiationState);
}
break;
@@ -1013,11 +1133,14 @@
if (DBG) logd("Found a match " + mSavedPeerConfig);
/* we already have the pin */
if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
- mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+ p2pConnectWithPinDisplay(mSavedPeerConfig);
transitionTo(mGroupNegotiationState);
} else {
mJoinExistingGroup = false;
- transitionTo(mUserAuthorizingInvitationState);
+ if (!sendConnectNoticeToApp(mPeers.get(mSavedPeerConfig.deviceAddress),
+ mSavedPeerConfig)) {
+ transitionTo(mUserAuthorizingInvitationState);
+ }
}
}
break;
@@ -1029,7 +1152,7 @@
if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
if (DBG) logd("Found a match " + mSavedPeerConfig);
mSavedPeerConfig.wps.pin = provDisc.pin;
- mWifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+ p2pConnectWithPinDisplay(mSavedPeerConfig);
if (!sendShowPinReqToFrontApp(provDisc.pin)) {
notifyInvitationSent(provDisc.pin, device.deviceAddress);
}
@@ -1062,6 +1185,17 @@
case WifiMonitor.P2P_GROUP_STARTED_EVENT:
mGroup = (WifiP2pGroup) message.obj;
if (DBG) logd(getName() + " group started");
+
+ if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
+ /*
+ * update cache information and set network id to mGroup.
+ */
+ updatePersistentNetworks();
+ String devAddr = mGroup.getOwner().deviceAddress;
+ mGroup.setNetworkId(mGroups.getNetworkId(devAddr,
+ mGroup.getNetworkName()));
+ }
+
if (mGroup.isGroupOwner()) {
startDhcpServer(mGroup.getInterface());
} else {
@@ -1090,6 +1224,29 @@
// failure causes supplicant issues. Ignore right now.
case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
break;
+ case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
+ P2pStatus status = (P2pStatus)message.obj;
+ if (status == P2pStatus.SUCCESS) {
+ // invocation was succeeded.
+ // wait P2P_GROUP_STARTED_EVENT.
+ break;
+ } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
+ // target device has already removed the credential.
+ // So, remove this credential accordingly.
+ int netId = mSavedPeerConfig.netId;
+ if (netId >= 0) {
+ if (DBG) logd("Remove unknown client from the list");
+ removeClientFromList(netId, mSavedPeerConfig.deviceAddress, true);
+ }
+ }
+
+ // invocation is failed or deferred. Try another way to connect.
+ mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
+ if (connect(mSavedPeerConfig, NO_REINVOCATION) == CONNECT_FAILURE) {
+ handleGroupCreationFailure();
+ transitionTo(mInactiveState);
+ }
+ break;
default:
return NOT_HANDLED;
}
@@ -1152,7 +1309,7 @@
}
}
sendP2pPeersChangedBroadcast();
- if (DBG) loge(getName() + " ap sta disconnected");
+ if (DBG) logd(getName() + " ap sta disconnected");
} else {
loge("Disconnect on unknown device: " + device);
}
@@ -1172,7 +1329,7 @@
}
break;
case WifiP2pManager.REMOVE_GROUP:
- if (DBG) loge(getName() + " remove group");
+ if (DBG) logd(getName() + " remove group");
if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
} else {
@@ -1181,7 +1338,7 @@
}
break;
case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
- if (DBG) loge(getName() + " group removed");
+ if (DBG) logd(getName() + " group removed");
Collection <WifiP2pDevice> devices = mGroup.getClientList();
boolean changed = false;
for (WifiP2pDevice d : mPeers.getDeviceList()) {
@@ -1196,7 +1353,7 @@
} else {
if (DBG) logd("stop DHCP client");
mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
- mDhcpStateMachine.quit();
+ mDhcpStateMachine.doQuit();
mDhcpStateMachine = null;
}
@@ -1252,6 +1409,7 @@
replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
} else {
logd("Inviting device : " + config.deviceAddress);
+ mSavedPeerConfig = config;
if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
sendP2pPeersChangedBroadcast();
@@ -1263,6 +1421,29 @@
}
// TODO: figure out updating the status to declined when invitation is rejected
break;
+ case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
+ P2pStatus status = (P2pStatus)message.obj;
+ logd("===> INVITATION RESULT EVENT : " + status);
+ if (status == P2pStatus.SUCCESS) {
+ // invocation was succeeded.
+ break;
+ } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
+ // target device has already removed the credential.
+ // So, remove this credential accordingly.
+ int netId = mGroup.getNetworkId();
+ if (netId >= 0) {
+ if (DBG) logd("Remove unknown client from the list");
+ if (!removeClientFromList(netId,
+ mSavedPeerConfig.deviceAddress, false)) {
+ // not found the client on the list
+ Slog.e(TAG, "Already removed the client, ignore");
+ break;
+ }
+ // try invitation.
+ sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
+ }
+ }
+ break;
case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
@@ -1304,7 +1485,6 @@
@Override
public void enter() {
if (DBG) logd(getName());
-
notifyInvitationReceived();
}
@@ -1394,6 +1574,13 @@
mContext.sendStickyBroadcast(intent);
}
+ private void sendP2pPersistentGroupsChangedBroadcast() {
+ if (DBG) logd("sending p2p persistent groups changed broadcast");
+ Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ mContext.sendStickyBroadcast(intent);
+ }
+
private void startDhcpServer(String intf) {
InterfaceConfiguration ifcg = null;
try {
@@ -1520,11 +1707,246 @@
dialog.show();
}
- //TODO: implement when wpa_supplicant is fixed
- private int configuredNetworkId(String deviceAddress) {
+ /**
+ * Synchronize the persistent group list between
+ * wpa_supplicant and mGroups.
+ */
+ private void updatePersistentNetworks() {
+ String listStr = mWifiNative.listNetworks();
+
+ boolean isSaveRequired = false;
+ String[] lines = listStr.split("\n");
+ // Skip the first line, which is a header
+ for (int i = 1; i < lines.length; i++) {
+ String[] result = lines[i].split("\t");
+ if (result == null || result.length < 4) {
+ continue;
+ }
+ // network-id | ssid | bssid | flags
+ int netId = -1;
+ String ssid = result[1];
+ String bssid = result[2];
+ String flags = result[3];
+ try {
+ netId = Integer.parseInt(result[0]);
+ } catch(NumberFormatException e) {
+ e.printStackTrace();
+ continue;
+ }
+
+ if (flags.indexOf("[CURRENT]") != -1) {
+ continue;
+ }
+ if (flags.indexOf("[P2P-PERSISTENT]") == -1) {
+ /*
+ * The unused profile is sometimes remained when the p2p group formation is failed.
+ * So, we clean up the p2p group here.
+ */
+ if (DBG) logd("clean up the unused persistent group. netId=" + netId);
+ mWifiNative.removeNetwork(netId);
+ isSaveRequired = true;
+ continue;
+ }
+
+ if (mGroups.contains(netId)) {
+ continue;
+ }
+
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkId(netId);
+ group.setNetworkName(ssid);
+ String mode = mWifiNative.getNetworkVariable(netId, "mode");
+ if (mode != null && mode.equals("3")) {
+ group.setIsGroupOwner(true);
+ }
+ if (bssid.equalsIgnoreCase(mThisDevice.deviceAddress)) {
+ group.setOwner(mThisDevice);
+ } else {
+ WifiP2pDevice device = new WifiP2pDevice();
+ device.deviceAddress = bssid;
+ group.setOwner(device);
+ }
+ mGroups.add(group);
+ isSaveRequired = true;
+ }
+
+ if (isSaveRequired) {
+ sendP2pPersistentGroupsChangedBroadcast();
+ mWifiNative.saveConfig();
+ }
+ }
+
+ /**
+ * Try to connect to the target device.
+ *
+ * Use the persistent credential if it has been stored.
+ *
+ * @param config
+ * @param tryInvocation if true, try to invoke. Otherwise, never try to invoke.
+ * @return
+ */
+ private int connect(WifiP2pConfig config, boolean tryInvocation) {
+
+ if (config == null) {
+ loge("invalid argument.");
+ return CONNECT_FAILURE;
+ }
+
+ boolean isResp = (mSavedPeerConfig != null &&
+ config.deviceAddress.equals(mSavedPeerConfig.deviceAddress));
+ mSavedPeerConfig = config;
+
+ WifiP2pDevice dev = mPeers.get(config.deviceAddress);
+ if (dev == null) {
+ loge("target device is not found.");
+ return CONNECT_FAILURE;
+ }
+
+ boolean join = dev.isGroupOwner();
+ String ssid = mWifiNative.p2pGetSsid(dev.deviceAddress);
+ if (DBG) logd("target ssid is " + ssid + " join:" + join);
+
+ if (join && dev.isGroupLimit()) {
+ if (DBG) logd("target device reaches group limit.");
+
+ // if the target group has reached the limit,
+ // try group formation.
+ join = false;
+ } else if (join) {
+ int netId = mGroups.getNetworkId(dev.deviceAddress, ssid);
+ if (netId >= 0) {
+ // Skip WPS and start 4way handshake immediately.
+ if (!mWifiNative.p2pGroupAdd(netId)) {
+ return CONNECT_FAILURE;
+ }
+ return CONNECT_SUCCESS;
+ }
+ }
+
+ if (!join && dev.isDeviceLimit()) {
+ loge("target device reaches the device limit.");
+ return CONNECT_FAILURE;
+ }
+
+ if (!join && tryInvocation && dev.isInvitationCapable()) {
+ int netId = WifiP2pGroup.PERSISTENT_NET_ID;
+ if (config.netId >= 0) {
+ if (config.deviceAddress.equals(mGroups.getOwnerAddr(config.netId))) {
+ netId = config.netId;
+ }
+ } else {
+ netId = mGroups.getNetworkId(dev.deviceAddress);
+ }
+ if (netId < 0) {
+ netId = getNetworkIdFromClientList(dev.deviceAddress);
+ }
+ if (DBG) logd("netId related with " + dev.deviceAddress + " = " + netId);
+ if (netId >= 0) {
+
+ // Invoke the persistent group.
+ if (!mWifiNative.p2pReinvoke(netId, dev.deviceAddress)) {
+ loge("p2pReinvoke() failed");
+ return CONNECT_FAILURE;
+ }
+ // Save network id. It'll be used when an invitation result event is received.
+ mSavedPeerConfig.netId = netId;
+ return CONNECT_SUCCESS;
+ }
+ }
+
+ //Stop discovery before issuing connect
+ mWifiNative.p2pStopFind();
+
+ if (!isResp) {
+ return NEEDS_PROVISION_REQ;
+ }
+
+ p2pConnectWithPinDisplay(config);
+ return CONNECT_SUCCESS;
+ }
+
+ /**
+ * Return the network id of the group owner profile which has the p2p client with
+ * the specified device address in it's client list.
+ * If more than one persistent group of the same address is present in its client
+ * lists, return the first one.
+ *
+ * @param deviceAddress p2p device address.
+ * @return the network id. if not found, return -1.
+ */
+ private int getNetworkIdFromClientList(String deviceAddress) {
+ if (deviceAddress == null) return -1;
+
+ Collection<WifiP2pGroup> groups = mGroups.getGroupList();
+ for (WifiP2pGroup group : groups) {
+ int netId = group.getNetworkId();
+ String[] p2pClientList = getClientList(netId);
+ if (p2pClientList == null) continue;
+ for (String client : p2pClientList) {
+ if (deviceAddress.equalsIgnoreCase(client)) {
+ return netId;
+ }
+ }
+ }
return -1;
}
+ /**
+ * Return p2p client list associated with the specified network id.
+ * @param netId network id.
+ * @return p2p client list. if not found, return null.
+ */
+ private String[] getClientList(int netId) {
+ String p2pClients = mWifiNative.getNetworkVariable(netId, "p2p_client_list");
+ if (p2pClients == null) {
+ return null;
+ }
+ return p2pClients.split(" ");
+ }
+
+ /**
+ * Remove the specified p2p client from the specified profile.
+ * @param netId network id of the profile.
+ * @param addr p2p client address to be removed.
+ * @param isRemovable if true, remove the specified profile if its client list becomes empty.
+ * @return whether removing the specified p2p client is successful or not.
+ */
+ private boolean removeClientFromList(int netId, String addr, boolean isRemovable) {
+ StringBuilder modifiedClientList = new StringBuilder();
+ String[] currentClientList = getClientList(netId);
+ boolean isClientRemoved = false;
+ if (currentClientList != null) {
+ for (String client : currentClientList) {
+ if (!client.equalsIgnoreCase(addr)) {
+ modifiedClientList.append(" ");
+ modifiedClientList.append(client);
+ } else {
+ isClientRemoved = true;
+ }
+ }
+ }
+ if (modifiedClientList.length() == 0 && isRemovable) {
+ // the client list is empty. so remove it.
+ if (DBG) logd("Remove unknown network");
+ mGroups.remove(netId);
+ return true;
+ }
+
+ if (!isClientRemoved) {
+ // specified p2p client is not found. already removed.
+ return false;
+ }
+
+ if (DBG) logd("Modified client list: " + modifiedClientList);
+ if (modifiedClientList.length() == 0) {
+ modifiedClientList.append("\"\"");
+ }
+ mWifiNative.setNetworkVariable(netId,
+ "p2p_client_list", modifiedClientList.toString());
+ mWifiNative.saveConfig();
+ return true;
+ }
+
private void setWifiP2pInfoOnGroupFormation(String serverAddress) {
mWifiP2pInfo.groupFormed = true;
mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
@@ -1546,8 +1968,14 @@
return deviceAddress;
}
- private void p2pConnectWithPinDisplay(WifiP2pConfig config, boolean join) {
- String pin = mWifiNative.p2pConnect(config, join);
+ private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
+ WifiP2pDevice dev = mPeers.get(config.deviceAddress);
+ if (dev == null) {
+ loge("target device is not found " + config.deviceAddress);
+ return;
+ }
+
+ String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
try {
Integer.parseInt(pin);
if (!sendShowPinReqToFrontApp(pin)) {
@@ -1610,6 +2038,8 @@
mWifiNative.p2pServiceFlush();
mServiceTransactionId = 0;
mServiceDiscReqId = null;
+
+ updatePersistentNetworks();
}
private void updateThisDevice(int status) {
@@ -1738,7 +2168,7 @@
//Application does not have transaction id information
//go through stored requests to remove
boolean removed = false;
- for (int i=0; i < clientInfo.mReqList.size(); i++) {
+ for (int i=0; i<clientInfo.mReqList.size(); i++) {
if (req.equals(clientInfo.mReqList.valueAt(i))) {
removed = true;
clientInfo.mReqList.removeAt(i);
@@ -2077,5 +2507,4 @@
mServList = new ArrayList<WifiP2pServiceInfo>();
}
}
-
}