summaryrefslogtreecommitdiffstats
path: root/telephony/java/android/telephony
diff options
context:
space:
mode:
Diffstat (limited to 'telephony/java/android/telephony')
-rw-r--r--telephony/java/android/telephony/CellLocation.java73
-rw-r--r--telephony/java/android/telephony/JapanesePhoneNumberFormatter.java216
-rw-r--r--telephony/java/android/telephony/NeighboringCellInfo.aidl20
-rw-r--r--telephony/java/android/telephony/NeighboringCellInfo.java123
-rw-r--r--telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java98
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java1231
-rw-r--r--telephony/java/android/telephony/PhoneStateListener.java265
-rw-r--r--telephony/java/android/telephony/ServiceState.aidl21
-rw-r--r--telephony/java/android/telephony/ServiceState.java331
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java689
-rw-r--r--telephony/java/android/telephony/gsm/GsmCellLocation.java126
-rw-r--r--telephony/java/android/telephony/gsm/SmsManager.java432
-rw-r--r--telephony/java/android/telephony/gsm/SmsMessage.java1598
-rw-r--r--telephony/java/android/telephony/gsm/package.html6
-rw-r--r--telephony/java/android/telephony/package.html7
15 files changed, 0 insertions, 5236 deletions
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
deleted file mode 100644
index 464085f..0000000
--- a/telephony/java/android/telephony/CellLocation.java
+++ /dev/null
@@ -1,73 +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.telephony;
-
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.gsm.GsmCellLocation;
-import com.android.internal.telephony.ITelephony;
-
-/**
- * Abstract class that represents the location of the device. Currently the only
- * subclass is {@link android.telephony.gsm.GsmCellLocation}. {@more}
- */
-public abstract class CellLocation {
-
- /**
- * Request an update of the current location. If the location has changed,
- * a broadcast will be sent to everyone registered with {@link
- * PhoneStateListener#LISTEN_CELL_LOCATION}.
- */
- public static void requestLocationUpdate() {
- try {
- ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.getService("phone"));
- if (phone != null) {
- phone.updateServiceLocation();
- }
- } catch (RemoteException ex) {
- // ignore it
- }
- }
-
- /**
- * Create a new CellLocation from a intent notifier Bundle
- *
- * This method is used by PhoneStateIntentReceiver and maybe by
- * external applications.
- *
- * @param bundle Bundle from intent notifier
- * @return newly created CellLocation
- *
- * @hide
- */
- public static CellLocation newFromBundle(Bundle bundle) {
- return new GsmCellLocation(bundle);
- }
-
- /**
- * @hide
- */
- public abstract void fillInNotifierBundle(Bundle bundle);
-
- /**
- * Return a new CellLocation object representing an unknown location.
- */
- public static CellLocation getEmpty() {
- return new GsmCellLocation();
- }
-}
diff --git a/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java b/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java
deleted file mode 100644
index 8a82966..0000000
--- a/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java
+++ /dev/null
@@ -1,216 +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.text.Editable;
-
-/*
- * Japanese Phone number formatting rule is a bit complicated.
- * Here are some valid examples:
- *
- * 022-229-1234 0223-23-1234 022-301-9876 015-482-7849 0154-91-3478
- * 01547-5-4534 090-1234-1234 080-0123-6789
- * 0800-000-9999 0570-000-000 0276-00-0000
- *
- * As you can see, there is no straight-forward rule here.
- * In order to handle this, a big array is prepared.
- */
-/* package */ class JapanesePhoneNumberFormatter {
- private static short FORMAT_MAP[] = {
- -100, 10, 220, -15, 410, 530, -15, 670, 780, 1060,
- -100, -25, 20, 40, 70, 100, 150, 190, 200, 210,
- -36, -100, -100, -35, -35, -35, 30, -100, -100, -100,
- -35, -35, -35, -35, -35, -35, -35, -45, -35, -35,
- -100, -100, -100, -35, -35, -35, -35, 50, -35, 60,
- -35, -35, -45, -35, -45, -35, -35, -45, -35, -35,
- -35, -35, -45, -35, -35, -35, -35, -45, -45, -35,
- -100, -100, -35, -35, -35, 80, 90, -100, -100, -100,
- -35, -35, -35, -35, -35, -35, -45, -45, -35, -35,
- -35, -35, -35, -35, -35, -35, -45, -35, -35, -35,
- -25, -25, -35, -35, 110, 120, 130, -35, 140, -25,
- -35, -25, -35, -35, -35, -35, -35, -45, -25, -35,
- -35, -25, -35, -35, -35, -35, -35, -25, -45, -35,
- -35, -35, -35, -35, -45, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -45, -45, -35, -35,
- -100, -100, -35, 160, 170, 180, -35, -35, -100, -100,
- -35, -35, -45, -35, -45, -45, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -45, -35,
- -35, -35, -35, -35, -45, -45, -45, -35, -45, -35,
- -25, -25, -35, -35, -35, -35, -35, -25, -35, -35,
- -25, -25, -35, -35, -35, -35, -35, -35, -25, -25,
- -25, -35, -35, -35, -35, -35, -25, -35, -35, -25,
- -100, -100, 230, 250, 260, 270, 320, 340, 360, 390,
- -35, -25, -25, 240, -35, -35, -35, -25, -35, -35,
- -25, -35, -35, -35, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -35, -35, -35, -25, -35, -35, -25,
- -35, -35, -35, -35, -35, -25, -35, -35, -35, -25,
- -35, -25, -25, -25, -35, 280, 290, 300, 310, -35,
- -25, -25, -25, -25, -25, -25, -25, -35, -35, -25,
- -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -25, -25, -35, -35, -35, -25, -25, -25, -25, -25,
- -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -25, -35, 330, -35, -35, -35, -35, -35,
- -25, -35, -35, -35, -35, -35, -25, -25, -25, -25,
- -35, -25, -25, -25, -35, -25, -35, -35, 350, -35,
- -25, -35, -35, -35, -35, -35, -35, -35, -25, -25,
- -35, -25, -35, 370, -35, -35, -25, -35, -35, 380,
- -25, -35, -35, -25, -25, -35, -35, -35, -35, -35,
- -25, -35, -25, -25, -25, -25, -35, -35, -35, -35,
- -25, -35, -25, 400, -35, -35, -35, -35, -25, -35,
- -25, -35, -35, -35, -35, -25, -25, -25, -25, -25,
- -15, -15, 420, 460, -25, -25, 470, 480, 500, 510,
- -15, -25, 430, -25, -25, -25, -25, -25, 440, 450,
- -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -25, -25, -35, -35, -25, -25, -25, -35, -35, -35,
- -15, -25, -15, -15, -15, -15, -15, -25, -25, -15,
- -25, -25, -25, -25, -25, -25, -35, -25, -35, -35,
- -35, -25, -25, -35, -25, -35, -35, -35, -25, -25,
- 490, -15, -25, -25, -25, -35, -35, -25, -35, -35,
- -15, -35, -35, -35, -35, -35, -35, -35, -35, -15,
- -35, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -35, -35, -35, -25, -25, -25, 520,
- -100, -100, -45, -100, -45, -100, -45, -100, -45, -100,
- -25, -100, -25, 540, 580, 590, 600, 610, 630, 640,
- -25, -35, -35, -35, -25, -25, -35, -35, -35, 550,
- -35, -35, -25, -25, -25, -25, 560, 570, -25, -35,
- -35, -35, -35, -35, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, -25, -35, -25, -25, -35, -25, -25,
- -25, -25, -25, -25, -35, -35, -25, -35, -35, -25,
- -35, -35, -25, -35, -35, -35, -35, -35, -35, -25,
- -100, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -36, -100, -35, -35, -35, -35, 620, -35, -35, -100,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -45,
- -25, -35, -25, -25, -35, -35, -35, -35, -25, -25,
- -25, -25, -25, -25, -35, -35, -35, 650, -35, 660,
- -35, -35, -35, -35, -45, -35, -35, -35, -35, -45,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -25,
- -26, -100, 680, 690, 700, -25, 720, 730, -25, 740,
- -25, -35, -25, -25, -25, -35, -25, -25, -25, -25,
- -25, -25, -25, -25, -25, -35, -35, -35, -35, -35,
- -35, -100, -35, -35, -35, -35, 710, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -45, -35,
- -25, -35, -25, -35, -25, -35, -35, -35, -35, -25,
- -35, -35, -35, -35, -35, -25, -35, -25, -35, -35,
- -35, -35, -25, -25, 750, 760, 770, -35, -35, -35,
- -25, -35, -25, -25, -25, -25, -35, -35, -35, -25,
- -25, -35, -35, -35, -35, -25, -25, -35, -35, -25,
- -25, -35, -35, -35, -35, -35, -25, -25, -35, -35,
- 790, -100, 800, 850, 900, 920, 940, 1030, 1040, 1050,
- -36, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -35, -25, -25, -35, 810, -25, -35, -35, -25, 820,
- -25, -35, -25, -25, -35, -35, -35, -35, -35, -25,
- -25, -35, 830, -35, 840, -35, -25, -35, -35, -25,
- -35, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -100, -25, -25, -25, -100, -100, -100, -100, -100, -100,
- -25, -25, -35, -35, -35, -35, 860, -35, 870, 880,
- -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -45, -45, -35,
- -100, -100, -100, -100, -100, -100, 890, -100, -100, -100,
- -25, -45, -45, -25, -45, -45, -25, -45, -45, -45,
- -25, -25, -25, -25, -25, -35, -35, 910, -35, -25,
- -35, -35, -35, -35, -35, -35, -35, -45, -35, -35,
- -100, 930, -35, -35, -35, -35, -35, -35, -35, -35,
- -100, -100, -45, -100, -45, -100, -100, -100, -100, -100,
- -25, -25, -25, 950, -25, 970, 990, -35, 1000, 1010,
- -35, -35, -35, -35, -35, -35, 960, -35, -35, -35,
- -45, -45, -45, -45, -45, -45, -35, -45, -45, -45,
- -35, -35, -25, -35, -35, 980, -35, -35, -35, -35,
- -100, -100, -25, -25, -100, -100, -100, -100, -100, -100,
- -25, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -25, -35, -35, -35, -35, -35, -35, -35, -35, -25,
- -25, -35, -35, -35, -25, -25, -35, -35, -35, 1020,
- -45, -45, -35, -35, -45, -45, -45, -45, -45, -45,
- -25, -25, -25, -25, -25, -35, -25, -35, -25, -35,
- -35, -25, -25, -35, -35, -35, -25, -35, -25, -35,
- -25, -25, -35, -35, -35, -35, -35, -35, -35, -25,
- -26, -100, 1070, 1080, 1090, 1110, 1120, 1130, 1140, 1160,
- -35, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -35, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -35, -100, -35, -35, -35, -100, -35, -35, -35, 1100,
- -35, -35, -35, -35, -35, -35, -45, -35, -35, -35,
- -35, -25, -35, -25, -35, -35, -35, -35, -25, -35,
- -25, -25, -25, -25, -35, -35, -35, -35, -35, -35,
- -25, -25, -35, -35, -35, -25, -25, -35, -35, -35,
- 1150, -25, -35, -35, -35, -35, -35, -35, -25, -25,
- -35, -35, -45, -35, -35, -35, -35, -35, -35, -35,
- -35, 1170, -25, -35, 1180, -35, 1190, -35, -25, -25,
- -100, -100, -45, -45, -100, -100, -100, -100, -100, -100,
- -25, -35, -35, -35, -35, -35, -35, -25, -25, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -45};
-
- public static void format(Editable text) {
- // Here, "root" means the position of "'":
- // 0'3, 0'90, and +81'-90
- // (dash will be deleted soon, so it is actually +81'90).
- int rootIndex = 1;
- int length = text.length();
- if (length > 3
- && text.subSequence(0, 3).toString().equals("+81")) {
- rootIndex = 3;
- } else if (length < 1 || text.charAt(0) != '0') {
- return;
- }
-
- CharSequence saved = text.subSequence(0, length);
-
- // Strip the dashes first, as we're going to add them back
- int i = 0;
- while (i < text.length()) {
- if (text.charAt(i) == '-') {
- text.delete(i, i + 1);
- } else {
- i++;
- }
- }
-
- length = text.length();
- int dashposition;
-
- i = rootIndex;
- int base = 0;
- while (i < length) {
- char ch = text.charAt(i);
- if (!Character.isDigit(ch)) {
- text.replace(0, length, saved);
- return;
- }
- short value = FORMAT_MAP[base + ch - '0'];
- if (value < 0) {
- if (value <= -100) {
- text.replace(0, length, saved);
- return;
- }
- int dashPos2 = rootIndex + (Math.abs(value) % 10);
- if (length > dashPos2) {
- text.insert(dashPos2, "-");
- }
- int dashPos1 = rootIndex + (Math.abs(value) / 10);
- if (length > dashPos1) {
- text.insert(dashPos1, "-");
- }
- break;
- } else {
- base = value;
- i++;
- }
- }
-
- if (length > 3 && rootIndex == 3) {
- text.insert(rootIndex, "-");
- }
- }
-} \ No newline at end of file
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.aidl b/telephony/java/android/telephony/NeighboringCellInfo.aidl
deleted file mode 100644
index a7e709e..0000000
--- a/telephony/java/android/telephony/NeighboringCellInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/content/Intent.aidl
-**
-** 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 android.telephony;
-
-parcelable NeighboringCellInfo; \ No newline at end of file
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
deleted file mode 100644
index 326401a..0000000
--- a/telephony/java/android/telephony/NeighboringCellInfo.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 android.telephony;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents the neighboring cell information, including
- * Received Signal Strength and Cell ID location.
- */
-public class NeighboringCellInfo implements Parcelable
-{
- /**
- * Signal strength is not available
- */
- static final public int UNKNOWN_RSSI = 99;
- /**
- * Cell location is not available
- */
- static final public int UNKNOWN_CID = -1;
-
- private int mRssi;
- private int mCid;
-
- /**
- * Empty constructor. Initializes the RSSI and CID.
- */
- public NeighboringCellInfo() {
- mRssi = UNKNOWN_RSSI;
- mCid = UNKNOWN_CID;
- }
-
- /**
- * Initialize the object from rssi and cid.
- */
- public NeighboringCellInfo(int rssi, int cid) {
- mRssi = rssi;
- mCid = cid;
- }
-
- /**
- * Initialize the object from a parcel.
- */
- public NeighboringCellInfo(Parcel in) {
- mRssi = in.readInt();
- mCid = in.readInt();
- }
-
- /**
- * @return received signal strength in "asu", ranging from 0 - 31,
- * or UNKNOWN_RSSI if unknown
- *
- * For GSM, dBm = -113 + 2*asu,
- * 0 means "-113 dBm or less" and 31 means "-51 dBm or greater"
- */
- public int getRssi() {
- return mRssi;
- }
-
- /**
- * @return cell id, UNKNOWN_CID if unknown, 0xffffffff max legal value
- */
- public int getCid() {
- return mCid;
- }
-
- /**
- * Set the cell id.
- */
- public void setCid(int cid) {
- mCid = cid;
- }
-
- /**
- * Set the signal strength of the cell.
- */
- public void setRssi(int rssi) {
- mRssi = rssi;
- }
-
- @Override
- public String toString() {
- return "["+ ((mCid == UNKNOWN_CID) ? "/" : Integer.toHexString(mCid))
- + " at " + ((mRssi == UNKNOWN_RSSI)? "/" : mRssi) + "]";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mRssi);
- dest.writeInt(mCid);
- }
-
- public static final Parcelable.Creator<NeighboringCellInfo> CREATOR
- = new Parcelable.Creator<NeighboringCellInfo>() {
- public NeighboringCellInfo createFromParcel(Parcel in) {
- return new NeighboringCellInfo(in);
- }
-
- public NeighboringCellInfo[] newArray(int size) {
- return new NeighboringCellInfo[size];
- }
- };
-}
-
-
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
deleted file mode 100644
index 0bc6c04..0000000
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ /dev/null
@@ -1,98 +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.text.Editable;
-import android.text.Selection;
-import android.text.TextWatcher;
-import android.widget.TextView;
-
-import java.util.Locale;
-
-/**
- * Watches a {@link TextView} and if a phone number is entered will format it using
- * {@link PhoneNumberUtils#formatNumber(Editable, int)}. The formatting is based on
- * the current system locale when this object is created and future locale changes
- * may not take effect on this instance.
- */
-public class PhoneNumberFormattingTextWatcher implements TextWatcher {
-
- static private int sFormatType;
- static private Locale sCachedLocale;
- private boolean mFormatting;
- private boolean mDeletingHyphen;
- private int mHyphenStart;
- private boolean mDeletingBackward;
-
- public PhoneNumberFormattingTextWatcher() {
- if (sCachedLocale == null || sCachedLocale != Locale.getDefault()) {
- sCachedLocale = Locale.getDefault();
- sFormatType = PhoneNumberUtils.getFormatTypeForLocale(sCachedLocale);
- }
- }
-
- public synchronized void afterTextChanged(Editable text) {
- // Make sure to ignore calls to afterTextChanged caused by the work done below
- if (!mFormatting) {
- mFormatting = true;
-
- // If deleting the hyphen, also delete the char before or after that
- if (mDeletingHyphen && mHyphenStart > 0) {
- if (mDeletingBackward) {
- if (mHyphenStart - 1 < text.length()) {
- text.delete(mHyphenStart - 1, mHyphenStart);
- }
- } else if (mHyphenStart < text.length()) {
- text.delete(mHyphenStart, mHyphenStart + 1);
- }
- }
-
- PhoneNumberUtils.formatNumber(text, sFormatType);
-
- mFormatting = false;
- }
- }
-
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // Check if the user is deleting a hyphen
- if (!mFormatting) {
- // Make sure user is deleting one char, without a selection
- final int selStart = Selection.getSelectionStart(s);
- final int selEnd = Selection.getSelectionEnd(s);
- if (s.length() > 1 // Can delete another character
- && count == 1 // Deleting only one character
- && after == 0 // Deleting
- && s.charAt(start) == '-' // a hyphen
- && selStart == selEnd) { // no selection
- mDeletingHyphen = true;
- mHyphenStart = start;
- // Check if the user is deleting forward or backward
- if (selStart == start + 1) {
- mDeletingBackward = true;
- } else {
- mDeletingBackward = false;
- }
- } else {
- mDeletingHyphen = false;
- }
- }
- }
-
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // Does nothing
- }
-}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
deleted file mode 100644
index d3942fc..0000000
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ /dev/null
@@ -1,1231 +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.telephony;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.SystemProperties;
-import android.provider.Contacts;
-import android.text.Editable;
-import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.util.SparseIntArray;
-
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Various utilities for dealing with phone number strings.
- */
-public class PhoneNumberUtils
-{
- /*
- * Special characters
- *
- * (See "What is a phone number?" doc)
- * 'p' --- GSM pause character, same as comma
- * 'n' --- GSM wild character
- * 'w' --- GSM wait character
- */
- public static final char PAUSE = ',';
- public static final char WAIT = ';';
- public static final char WILD = 'N';
-
- /*
- * TOA = TON + NPI
- * See TS 24.008 section 10.5.4.7 for details.
- * These are the only really useful TOA values
- */
- public static final int TOA_International = 0x91;
- public static final int TOA_Unknown = 0x81;
-
- /*
- * global-phone-number = ["+"] 1*( DIGIT / written-sep )
- * written-sep = ("-"/".")
- */
- private static final Pattern GLOBAL_PHONE_NUMBER_PATTERN =
- Pattern.compile("[\\+]?[0-9.-]+");
-
- /** True if c is ISO-LATIN characters 0-9 */
- public static boolean
- isISODigit (char c) {
- return c >= '0' && c <= '9';
- }
-
- /** True if c is ISO-LATIN characters 0-9, *, # */
- public final static boolean
- is12Key(char c) {
- return (c >= '0' && c <= '9') || c == '*' || c == '#';
- }
-
- /** True if c is ISO-LATIN characters 0-9, *, # , +, WILD */
- public final static boolean
- isDialable(char c) {
- return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == WILD;
- }
-
- /** True if c is ISO-LATIN characters 0-9, *, # , + (no WILD) */
- public final static boolean
- isReallyDialable(char c) {
- return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+';
- }
-
- /** True if c is ISO-LATIN characters 0-9, *, # , +, WILD, WAIT, PAUSE */
- public final static boolean
- isNonSeparator(char c) {
- return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+'
- || c == WILD || c == WAIT || c == PAUSE;
- }
-
- /** This any anything to the right of this char is part of the
- * post-dial string (eg this is PAUSE or WAIT)
- */
- public final static boolean
- isStartsPostDial (char c) {
- return c == PAUSE || c == WAIT;
- }
-
- /** Extracts the phone number from an Intent.
- *
- * @param intent the intent to get the number of
- * @param context a context to use for database access
- *
- * @return the phone number that would be called by the intent, or
- * <code>null</code> if the number cannot be found.
- */
- public static String getNumberFromIntent(Intent intent, Context context) {
- String number = null;
-
- Uri uri = intent.getData();
- String scheme = uri.getScheme();
-
- if (scheme.equals("tel")) {
- return uri.getSchemeSpecificPart();
- }
-
- if (scheme.equals("voicemail")) {
- return TelephonyManager.getDefault().getVoiceMailNumber();
- }
-
- if (context == null) {
- return null;
- }
-
- String type = intent.resolveType(context);
-
- Cursor c = context.getContentResolver().query(
- uri, new String[]{ Contacts.People.Phones.NUMBER },
- null, null, null);
- if (c != null) {
- try {
- if (c.moveToFirst()) {
- number = c.getString(
- c.getColumnIndex(Contacts.People.Phones.NUMBER));
- }
- } finally {
- c.close();
- }
- }
-
- return number;
- }
-
- /** Extracts the network address portion and canonicalizes
- * (filters out separators.)
- * Network address portion is everything up to DTMF control digit
- * separators (pause or wait), but without non-dialable characters.
- *
- * Please note that the GSM wild character is allowed in the result.
- * This must be resolved before dialing.
- *
- * Allows + only in the first position in the result string.
- *
- * Returns null if phoneNumber == null
- */
- public static String
- extractNetworkPortion(String phoneNumber) {
- if (phoneNumber == null) {
- return null;
- }
-
- int len = phoneNumber.length();
- StringBuilder ret = new StringBuilder(len);
- boolean firstCharAdded = false;
-
- for (int i = 0; i < len; i++) {
- char c = phoneNumber.charAt(i);
- if (isDialable(c) && (c != '+' || !firstCharAdded)) {
- firstCharAdded = true;
- ret.append(c);
- } else if (isStartsPostDial (c)) {
- break;
- }
- }
-
- return ret.toString();
- }
-
- /**
- * Strips separators from a phone number string.
- * @param phoneNumber phone number to strip.
- * @return phone string stripped of separators.
- */
- public static String stripSeparators(String phoneNumber) {
- if (phoneNumber == null) {
- return null;
- }
- int len = phoneNumber.length();
- StringBuilder ret = new StringBuilder(len);
-
- for (int i = 0; i < len; i++) {
- char c = phoneNumber.charAt(i);
- if (isNonSeparator(c)) {
- ret.append(c);
- }
- }
-
- return ret.toString();
- }
-
- /** or -1 if both are negative */
- static private int
- minPositive (int a, int b) {
- if (a >= 0 && b >= 0) {
- return (a < b) ? a : b;
- } else if (a >= 0) { /* && b < 0 */
- return a;
- } else if (b >= 0) { /* && a < 0 */
- return b;
- } else { /* a < 0 && b < 0 */
- return -1;
- }
- }
-
- /** index of the last character of the network portion
- * (eg anything after is a post-dial string)
- */
- static private int
- indexOfLastNetworkChar(String a) {
- int pIndex, wIndex;
- int origLength;
- int trimIndex;
-
- origLength = a.length();
-
- pIndex = a.indexOf(PAUSE);
- wIndex = a.indexOf(WAIT);
-
- trimIndex = minPositive(pIndex, wIndex);
-
- if (trimIndex < 0) {
- return origLength - 1;
- } else {
- return trimIndex - 1;
- }
- }
-
- /**
- * Extracts the post-dial sequence of DTMF control digits, pauses, and
- * waits. Strips separators. This string may be empty, but will not be null
- * unless phoneNumber == null.
- *
- * Returns null if phoneNumber == null
- */
-
- public static String
- extractPostDialPortion(String phoneNumber) {
- if (phoneNumber == null) return null;
-
- int trimIndex;
- StringBuilder ret = new StringBuilder();
-
- trimIndex = indexOfLastNetworkChar (phoneNumber);
-
- for (int i = trimIndex + 1, s = phoneNumber.length()
- ; i < s; i++
- ) {
- char c = phoneNumber.charAt(i);
- if (isNonSeparator(c)) {
- ret.append(c);
- }
- }
-
- return ret.toString();
- }
-
- /**
- * Compare phone numbers a and b, return true if they're identical
- * enough for caller ID purposes.
- *
- * - Compares from right to left
- * - requires MIN_MATCH (5) characters to match
- * - handles common trunk prefixes and international prefixes
- * (basically, everything except the Russian trunk prefix)
- *
- * Tolerates nulls
- */
- public static boolean
- compare(String a, String b) {
- int ia, ib;
- int matched;
-
- if (a == null || b == null) return a == b;
-
- if (a.length() == 0 || b.length() == 0) {
- return false;
- }
-
- ia = indexOfLastNetworkChar (a);
- ib = indexOfLastNetworkChar (b);
- matched = 0;
-
- while (ia >= 0 && ib >=0) {
- char ca, cb;
- boolean skipCmp = false;
-
- ca = a.charAt(ia);
-
- if (!isDialable(ca)) {
- ia--;
- skipCmp = true;
- }
-
- cb = b.charAt(ib);
-
- if (!isDialable(cb)) {
- ib--;
- skipCmp = true;
- }
-
- if (!skipCmp) {
- if (cb != ca && ca != WILD && cb != WILD) {
- break;
- }
- ia--; ib--; matched++;
- }
- }
-
- if (matched < MIN_MATCH) {
- int aLen = a.length();
-
- // if the input strings match, but their lengths < MIN_MATCH,
- // treat them as equal.
- if (aLen == b.length() && aLen == matched) {
- return true;
- }
- return false;
- }
-
- // At least one string has matched completely;
- if (matched >= MIN_MATCH && (ia < 0 || ib < 0)) {
- return true;
- }
-
- /*
- * Now, what remains must be one of the following for a
- * match:
- *
- * - a '+' on one and a '00' or a '011' on the other
- * - a '0' on one and a (+,00)<country code> on the other
- * (for this, a '0' and a '00' prefix would have succeeded above)
- */
-
- if (matchIntlPrefix(a, ia + 1)
- && matchIntlPrefix (b, ib +1)
- ) {
- return true;
- }
-
- if (matchTrunkPrefix(a, ia + 1)
- && matchIntlPrefixAndCC(b, ib +1)
- ) {
- return true;
- }
-
- if (matchTrunkPrefix(b, ib + 1)
- && matchIntlPrefixAndCC(a, ia +1)
- ) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Returns the rightmost MIN_MATCH (5) characters in the network portion
- * in *reversed* order
- *
- * This can be used to do a database lookup against the column
- * that stores getStrippedReversed()
- *
- * Returns null if phoneNumber == null
- */
- public static String
- toCallerIDMinMatch(String phoneNumber) {
- String np = extractNetworkPortion(phoneNumber);
- return internalGetStrippedReversed(np, MIN_MATCH);
- }
-
- /**
- * Returns the network portion reversed.
- * This string is intended to go into an index column for a
- * database lookup.
- *
- * Returns null if phoneNumber == null
- */
- public static String
- getStrippedReversed(String phoneNumber) {
- String np = extractNetworkPortion(phoneNumber);
-
- if (np == null) return null;
-
- return internalGetStrippedReversed(np, np.length());
- }
-
- /**
- * Returns the last numDigits of the reversed phone number
- * Returns null if np == null
- */
- private static String
- internalGetStrippedReversed(String np, int numDigits) {
- if (np == null) return null;
-
- StringBuilder ret = new StringBuilder(numDigits);
- int length = np.length();
-
- for (int i = length - 1, s = length
- ; i >= 0 && (s - i) <= numDigits ; i--
- ) {
- char c = np.charAt(i);
-
- ret.append(c);
- }
-
- return ret.toString();
- }
-
- /**
- * Basically: makes sure there's a + in front of a
- * TOA_International number
- *
- * Returns null if s == null
- */
- public static String
- stringFromStringAndTOA(String s, int TOA) {
- if (s == null) return null;
-
- if (TOA == TOA_International && s.length() > 0 && s.charAt(0) != '+') {
- return "+" + s;
- }
-
- return s;
- }
-
- /**
- * Returns the TOA for the given dial string
- * Basically, returns TOA_International if there's a + prefix
- */
-
- public static int
- toaFromString(String s) {
- if (s != null && s.length() > 0 && s.charAt(0) == '+') {
- return TOA_International;
- }
-
- return TOA_Unknown;
- }
-
- /**
- * Phone numbers are stored in "lookup" form in the database
- * as reversed strings to allow for caller ID lookup
- *
- * This method takes a phone number and makes a valid SQL "LIKE"
- * string that will match the lookup form
- *
- */
- /** all of a up to len must be an international prefix or
- * separators/non-dialing digits
- */
- private static boolean
- matchIntlPrefix(String a, int len) {
- /* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */
- /* 0 1 2 3 45 */
-
- int state = 0;
- for (int i = 0 ; i < len ; i++) {
- char c = a.charAt(i);
-
- switch (state) {
- case 0:
- if (c == '+') state = 1;
- else if (c == '0') state = 2;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 2:
- if (c == '0') state = 3;
- else if (c == '1') state = 4;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 4:
- if (c == '1') state = 5;
- else if (isNonSeparator(c)) return false;
- break;
-
- default:
- if (isNonSeparator(c)) return false;
- break;
-
- }
- }
-
- return state == 1 || state == 3 || state == 5;
- }
-
- /**
- * 3GPP TS 24.008 10.5.4.7
- * Called Party BCD Number
- *
- * See Also TS 51.011 10.5.1 "dialing number/ssc string"
- * and TS 11.11 "10.3.1 EF adn (Abbreviated dialing numbers)"
- *
- * @param bytes the data buffer
- * @param offset should point to the TOA (aka. TON/NPI) octet after the length byte
- * @param length is the number of bytes including TOA byte
- * and must be at least 2
- *
- * @return partial string on invalid decode
- *
- * FIXME(mkf) support alphanumeric address type
- * currently implemented in SMSMessage.getAddress()
- */
- public static String
- calledPartyBCDToString (byte[] bytes, int offset, int length) {
- boolean prependPlus = false;
- StringBuilder ret = new StringBuilder(1 + length * 2);
-
- if (length < 2) {
- return "";
- }
-
- if ((bytes[offset] & 0xff) == TOA_International) {
- prependPlus = true;
- }
-
- internalCalledPartyBCDFragmentToString(
- ret, bytes, offset + 1, length - 1);
-
- if (prependPlus && ret.length() == 0) {
- // If the only thing there is a prepended plus, return ""
- return "";
- }
-
- if (prependPlus) {
- // This is an "international number" and should have
- // a plus prepended to the dialing number. But there
- // can also be Gsm MMI codes as defined in TS 22.030 6.5.2
- // so we need to handle those also.
- //
- // http://web.telia.com/~u47904776/gsmkode.htm is a
- // has a nice list of some of these GSM codes.
- //
- // Examples are:
- // **21*+886988171479#
- // **21*8311234567#
- // *21#
- // #21#
- // *#21#
- // *31#+11234567890
- // #31#+18311234567
- // #31#8311234567
- // 18311234567
- // +18311234567#
- // +18311234567
- // Odd ball cases that some phones handled
- // where there is no dialing number so they
- // append the "+"
- // *21#+
- // **21#+
- String retString = ret.toString();
- Pattern p = Pattern.compile("(^[#*])(.*)([#*])(.*)(#)$");
- Matcher m = p.matcher(retString);
- if (m.matches()) {
- if ("".equals(m.group(2))) {
- // Started with two [#*] ends with #
- // So no dialing number and we'll just
- // append a +, this handles **21#+
- ret = new StringBuilder();
- ret.append(m.group(1));
- ret.append(m.group(3));
- ret.append(m.group(4));
- ret.append(m.group(5));
- ret.append("+");
- } else {
- // Starts with [#*] and ends with #
- // Assume group 4 is a dialing number
- // such as *21*+1234554#
- ret = new StringBuilder();
- ret.append(m.group(1));
- ret.append(m.group(2));
- ret.append(m.group(3));
- ret.append("+");
- ret.append(m.group(4));
- ret.append(m.group(5));
- }
- } else {
- p = Pattern.compile("(^[#*])(.*)([#*])(.*)");
- m = p.matcher(retString);
- if (m.matches()) {
- // Starts with [#*] and only one other [#*]
- // Assume the data after last [#*] is dialing
- // number (i.e. group 4) such as *31#+11234567890.
- // This also includes the odd ball *21#+
- ret = new StringBuilder();
- ret.append(m.group(1));
- ret.append(m.group(2));
- ret.append(m.group(3));
- ret.append("+");
- ret.append(m.group(4));
- } else {
- // Does NOT start with [#*] just prepend '+'
- ret = new StringBuilder();
- ret.append('+');
- ret.append(retString);
- }
- }
- }
-
- return ret.toString();
- }
-
- private static void
- internalCalledPartyBCDFragmentToString(
- StringBuilder sb, byte [] bytes, int offset, int length) {
- for (int i = offset ; i < length + offset ; i++) {
- byte b;
- char c;
-
- c = bcdToChar((byte)(bytes[i] & 0xf));
-
- if (c == 0) {
- return;
- }
- sb.append(c);
-
- // FIXME(mkf) TS 23.040 9.1.2.3 says
- // "if a mobile receives 1111 in a position prior to
- // the last semi-octet then processing shall commense with
- // the next semi-octet and the intervening
- // semi-octet shall be ignored"
- // How does this jive with 24,008 10.5.4.7
-
- b = (byte)((bytes[i] >> 4) & 0xf);
-
- if (b == 0xf && i + 1 == length + offset) {
- //ignore final 0xf
- break;
- }
-
- c = bcdToChar(b);
- if (c == 0) {
- return;
- }
-
- sb.append(c);
- }
-
- }
-
- /**
- * Like calledPartyBCDToString, but field does not start with a
- * TOA byte. For example: SIM ADN extension fields
- */
-
- public static String
- calledPartyBCDFragmentToString(byte [] bytes, int offset, int length) {
- StringBuilder ret = new StringBuilder(length * 2);
-
- internalCalledPartyBCDFragmentToString(ret, bytes, offset, length);
-
- return ret.toString();
- }
-
- /** returns 0 on invalid value */
- private static char
- bcdToChar(byte b) {
- if (b < 0xa) {
- return (char)('0' + b);
- } else switch (b) {
- case 0xa: return '*';
- case 0xb: return '#';
- case 0xc: return PAUSE;
- case 0xd: return WILD;
-
- default: return 0;
- }
- }
-
- private static int
- charToBCD(char c) {
- if (c >= '0' && c <= '9') {
- return c - '0';
- } else if (c == '*') {
- return 0xa;
- } else if (c == '#') {
- return 0xb;
- } else if (c == PAUSE) {
- return 0xc;
- } else if (c == WILD) {
- return 0xd;
- } else {
- throw new RuntimeException ("invalid char for BCD " + c);
- }
- }
-
- /**
- * Note: calls extractNetworkPortion(), so do not use for
- * SIM EF[ADN] style records
- *
- * Exceptions thrown if extractNetworkPortion(s).length() == 0
- */
- public static byte[]
- networkPortionToCalledPartyBCD(String s) {
- return numberToCalledPartyBCD(extractNetworkPortion(s));
- }
-
- /**
- * Return true iff the network portion of <code>address</code> is,
- * as far as we can tell on the device, suitable for use as an SMS
- * destination address.
- */
- public static boolean isWellFormedSmsAddress(String address) {
- String networkPortion =
- PhoneNumberUtils.extractNetworkPortion(address);
-
- return (!(networkPortion.equals("+")
- || TextUtils.isEmpty(networkPortion)))
- && isDialable(networkPortion);
- }
-
- public static boolean isGlobalPhoneNumber(String phoneNumber) {
- if (TextUtils.isEmpty(phoneNumber)) {
- return false;
- }
-
- Matcher match = GLOBAL_PHONE_NUMBER_PATTERN.matcher(phoneNumber);
- return match.matches();
- }
-
- private static boolean isDialable(String address) {
- for (int i = 0, count = address.length(); i < count; i++) {
- if (!isDialable(address.charAt(i))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Same as {@link #networkPortionToCalledPartyBCD}, but includes a
- * one-byte length prefix.
- */
- public static byte[]
- networkPortionToCalledPartyBCDWithLength(String s) {
- return numberToCalledPartyBCDWithLength(extractNetworkPortion(s));
- }
-
- /**
- * Convert a dialing number to BCD byte array
- *
- * @param number dialing number string
- * if the dialing number starts with '+', set to internationl TOA
- * @return BCD byte array
- */
- public static byte[]
- numberToCalledPartyBCD(String number) {
- // The extra byte required for '+' is taken into consideration while calculating
- // length of ret.
- int size = (hasPlus(number) ? number.length() - 1 : number.length());
- byte[] ret = new byte[(size + 1) / 2 + 1];
-
- return numberToCalledPartyBCDHelper(ret, 0, number);
- }
-
- /**
- * Same as {@link #numberToCalledPartyBCD}, but includes a
- * one-byte length prefix.
- */
- private static byte[]
- numberToCalledPartyBCDWithLength(String number) {
- // The extra byte required for '+' is taken into consideration while calculating
- // length of ret.
- int size = (hasPlus(number) ? number.length() - 1 : number.length());
- int length = (size + 1) / 2 + 1;
- byte[] ret = new byte[length + 1];
-
- ret[0] = (byte) (length & 0xff);
- return numberToCalledPartyBCDHelper(ret, 1, number);
- }
-
- private static boolean
- hasPlus(String s) {
- return s.indexOf('+') >= 0;
- }
-
- private static byte[]
- numberToCalledPartyBCDHelper(byte[] ret, int offset, String number) {
- if (hasPlus(number)) {
- number = number.replaceAll("\\+", "");
- ret[offset] = (byte) TOA_International;
- } else {
- ret[offset] = (byte) TOA_Unknown;
- }
-
- int size = number.length();
- int curChar = 0;
- int countFullBytes = ret.length - offset - 1 - ((size - curChar) & 1);
- for (int i = 1; i < 1 + countFullBytes; i++) {
- ret[offset + i]
- = (byte) ((charToBCD(number.charAt(curChar++)))
- | (charToBCD(number.charAt(curChar++))) << 4);
- }
-
- // The left-over octet for odd-length phone numbers should be
- // filled with 0xf.
- if (countFullBytes + offset < ret.length - 1) {
- ret[ret.length - 1]
- = (byte) (charToBCD(number.charAt(curChar))
- | (0xf << 4));
- }
- return ret;
- }
-
- /** all of 'a' up to len must match non-US trunk prefix ('0') */
- private static boolean
- matchTrunkPrefix(String a, int len) {
- boolean found;
-
- found = false;
-
- for (int i = 0 ; i < len ; i++) {
- char c = a.charAt(i);
-
- if (c == '0' && !found) {
- found = true;
- } else if (isNonSeparator(c)) {
- return false;
- }
- }
-
- return found;
- }
-
- /** all of 'a' up to len must be a (+|00|011)country code)
- * We're fast and loose with the country code. Any \d{1,3} matches */
- private static boolean
- matchIntlPrefixAndCC(String a, int len) {
- /* [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */
- /* 0 1 2 3 45 6 7 8 */
-
- int state = 0;
- for (int i = 0 ; i < len ; i++ ) {
- char c = a.charAt(i);
-
- switch (state) {
- case 0:
- if (c == '+') state = 1;
- else if (c == '0') state = 2;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 2:
- if (c == '0') state = 3;
- else if (c == '1') state = 4;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 4:
- if (c == '1') state = 5;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 1:
- case 3:
- case 5:
- if (isISODigit(c)) state = 6;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 6:
- case 7:
- if (isISODigit(c)) state++;
- else if (isNonSeparator(c)) return false;
- break;
-
- default:
- if (isNonSeparator(c)) return false;
- }
- }
-
- return state == 6 || state == 7 || state == 8;
- }
-
- //================ Number formatting =========================
-
- /** The current locale is unknown, look for a country code or don't format */
- public static final int FORMAT_UNKNOWN = 0;
- /** NANP formatting */
- public static final int FORMAT_NANP = 1;
- /** Japanese formatting */
- public static final int FORMAT_JAPAN = 2;
-
- /** List of country codes for countries that use the NANP */
- private static final String[] NANP_COUNTRIES = new String[] {
- "US", // United States
- "CA", // Canada
- "AS", // American Samoa
- "AI", // Anguilla
- "AG", // Antigua and Barbuda
- "BS", // Bahamas
- "BB", // Barbados
- "BM", // Bermuda
- "VG", // British Virgin Islands
- "KY", // Cayman Islands
- "DM", // Dominica
- "DO", // Dominican Republic
- "GD", // Grenada
- "GU", // Guam
- "JM", // Jamaica
- "PR", // Puerto Rico
- "MS", // Montserrat
- "NP", // Northern Mariana Islands
- "KN", // Saint Kitts and Nevis
- "LC", // Saint Lucia
- "VC", // Saint Vincent and the Grenadines
- "TT", // Trinidad and Tobago
- "TC", // Turks and Caicos Islands
- "VI", // U.S. Virgin Islands
- };
-
- /**
- * Breaks the given number down and formats it according to the rules
- * for the country the number is from.
- *
- * @param source the phone number to format
- * @return a locally acceptable formatting of the input, or the raw input if
- * formatting rules aren't known for the number
- */
- public static String formatNumber(String source) {
- SpannableStringBuilder text = new SpannableStringBuilder(source);
- formatNumber(text, getFormatTypeForLocale(Locale.getDefault()));
- return text.toString();
- }
-
- /**
- * Returns the phone number formatting type for the given locale.
- *
- * @param locale The locale of interest, usually {@link Locale#getDefault()}
- * @return the formatting type for the given locale, or FORMAT_UNKNOWN if the formatting
- * rules are not known for the given locale
- */
- public static int getFormatTypeForLocale(Locale locale) {
- String country = locale.getCountry();
-
- // Check for the NANP countries
- int length = NANP_COUNTRIES.length;
- for (int i = 0; i < length; i++) {
- if (NANP_COUNTRIES[i].equals(country)) {
- return FORMAT_NANP;
- }
- }
- if (locale.equals(Locale.JAPAN)) {
- return FORMAT_JAPAN;
- }
- return FORMAT_UNKNOWN;
- }
-
- /**
- * Formats a phone number in-place. Currently only supports NANP formatting.
- *
- * @param text The number to be formatted, will be modified with the formatting
- * @param defaultFormattingType The default formatting rules to apply if the number does
- * not begin with +<country_code>
- */
- public static void formatNumber(Editable text, int defaultFormattingType) {
- int formatType = defaultFormattingType;
-
- if (text.length() > 2 && text.charAt(0) == '+') {
- if (text.charAt(1) == '1') {
- formatType = FORMAT_NANP;
- } else if (text.length() >= 3 && text.charAt(1) == '8'
- && text.charAt(2) == '1') {
- formatType = FORMAT_JAPAN;
- } else {
- return;
- }
- }
-
- switch (formatType) {
- case FORMAT_NANP:
- formatNanpNumber(text);
- return;
- case FORMAT_JAPAN:
- formatJapaneseNumber(text);
- return;
- }
- }
-
- private static final int NANP_STATE_DIGIT = 1;
- private static final int NANP_STATE_PLUS = 2;
- private static final int NANP_STATE_ONE = 3;
- private static final int NANP_STATE_DASH = 4;
-
- /**
- * Formats a phone number in-place using the NANP formatting rules. Numbers will be formatted
- * as:
- *
- * <p><code>
- * xxx-xxxx
- * xxx-xxx-xxxx
- * 1-xxx-xxx-xxxx
- * +1-xxx-xxx-xxxx
- * </code></p>
- *
- * @param text the number to be formatted, will be modified with the formatting
- */
- public static void formatNanpNumber(Editable text) {
- int length = text.length();
- if (length > "+1-nnn-nnn-nnnn".length()) {
- // The string is too long to be formatted
- return;
- }
- CharSequence saved = text.subSequence(0, length);
-
- // Strip the dashes first, as we're going to add them back
- int p = 0;
- while (p < text.length()) {
- if (text.charAt(p) == '-') {
- text.delete(p, p + 1);
- } else {
- p++;
- }
- }
- length = text.length();
-
- // When scanning the number we record where dashes need to be added,
- // if they're non-0 at the end of the scan the dashes will be added in
- // the proper places.
- int dashPositions[] = new int[3];
- int numDashes = 0;
-
- int state = NANP_STATE_DIGIT;
- int numDigits = 0;
- for (int i = 0; i < length; i++) {
- char c = text.charAt(i);
- switch (c) {
- case '1':
- if (numDigits == 0 || state == NANP_STATE_PLUS) {
- state = NANP_STATE_ONE;
- break;
- }
- // fall through
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '0':
- if (state == NANP_STATE_PLUS) {
- // Only NANP number supported for now
- text.replace(0, length, saved);
- return;
- } else if (state == NANP_STATE_ONE) {
- // Found either +1 or 1, follow it up with a dash
- dashPositions[numDashes++] = i;
- } else if (state != NANP_STATE_DASH && (numDigits == 3 || numDigits == 6)) {
- // Found a digit that should be after a dash that isn't
- dashPositions[numDashes++] = i;
- }
- state = NANP_STATE_DIGIT;
- numDigits++;
- break;
-
- case '-':
- state = NANP_STATE_DASH;
- break;
-
- case '+':
- if (i == 0) {
- // Plus is only allowed as the first character
- state = NANP_STATE_PLUS;
- break;
- }
- // Fall through
- default:
- // Unknown character, bail on formatting
- text.replace(0, length, saved);
- return;
- }
- }
-
- if (numDigits == 7) {
- // With 7 digits we want xxx-xxxx, not xxx-xxx-x
- numDashes--;
- }
-
- // Actually put the dashes in place
- for (int i = 0; i < numDashes; i++) {
- int pos = dashPositions[i];
- text.replace(pos + i, pos + i, "-");
- }
-
- // Remove trailing dashes
- int len = text.length();
- while (len > 0) {
- if (text.charAt(len - 1) == '-') {
- text.delete(len - 1, len);
- len--;
- } else {
- break;
- }
- }
- }
-
- /**
- * Formats a phone number in-place using the Japanese formatting rules.
- * Numbers will be formatted as:
- *
- * <p><code>
- * 03-xxxx-xxxx
- * 090-xxxx-xxxx
- * 0120-xxx-xxx
- * +81-3-xxxx-xxxx
- * +81-90-xxxx-xxxx
- * </code></p>
- *
- * @param text the number to be formatted, will be modified with
- * the formatting
- */
- public static void formatJapaneseNumber(Editable text) {
- JapanesePhoneNumberFormatter.format(text);
- }
-
- // Three and four digit phone numbers for either special services
- // or from the network (eg carrier-originated SMS messages) should
- // not match
- static final int MIN_MATCH = 5;
-
- /**
- * isEmergencyNumber: checks a given number against the list of
- * emergency numbers provided by the RIL and SIM card.
- *
- * @param number the number to look up.
- * @return if the number is in the list of emergency numbers
- * listed in the ril / sim, then return true, otherwise false.
- */
- public static boolean isEmergencyNumber(String number) {
- // Strip the separators from the number before comparing it
- // to the list.
- number = extractNetworkPortion(number);
-
- // retrieve the list of emergency numbers
- String numbers = SystemProperties.get("ro.ril.ecclist");
-
- if (!TextUtils.isEmpty(numbers)) {
- // searches through the comma-separated list for a match,
- // return true if one is found.
- for (String emergencyNum : numbers.split(",")) {
- if (emergencyNum.equals(number)) {
- return true;
- }
- }
- // no matches found against the list!
- return false;
- }
-
- //no ecclist system property, so use our own list.
- return (number.equals("112") || number.equals("911"));
- }
-
- /**
- * Translates any alphabetic letters (i.e. [A-Za-z]) in the
- * specified phone number into the equivalent numeric digits,
- * according to the phone keypad letter mapping described in
- * ITU E.161 and ISO/IEC 9995-8.
- *
- * @return the input string, with alpha letters converted to numeric
- * digits using the phone keypad letter mapping. For example,
- * an input of "1-800-GOOG-411" will return "1-800-4664-411".
- */
- public static String convertKeypadLettersToDigits(String input) {
- if (input == null) {
- return input;
- }
- int len = input.length();
- if (len == 0) {
- return input;
- }
-
- char[] out = input.toCharArray();
-
- for (int i = 0; i < len; i++) {
- char c = out[i];
- // If this char isn't in KEYPAD_MAP at all, just leave it alone.
- out[i] = (char) KEYPAD_MAP.get(c, c);
- }
-
- return new String(out);
- }
-
- /**
- * The phone keypad letter mapping (see ITU E.161 or ISO/IEC 9995-8.)
- * TODO: This should come from a resource.
- */
- private static final SparseIntArray KEYPAD_MAP = new SparseIntArray();
- static {
- KEYPAD_MAP.put('a', '2'); KEYPAD_MAP.put('b', '2'); KEYPAD_MAP.put('c', '2');
- KEYPAD_MAP.put('A', '2'); KEYPAD_MAP.put('B', '2'); KEYPAD_MAP.put('C', '2');
-
- KEYPAD_MAP.put('d', '3'); KEYPAD_MAP.put('e', '3'); KEYPAD_MAP.put('f', '3');
- KEYPAD_MAP.put('D', '3'); KEYPAD_MAP.put('E', '3'); KEYPAD_MAP.put('F', '3');
-
- KEYPAD_MAP.put('g', '4'); KEYPAD_MAP.put('h', '4'); KEYPAD_MAP.put('i', '4');
- KEYPAD_MAP.put('G', '4'); KEYPAD_MAP.put('H', '4'); KEYPAD_MAP.put('I', '4');
-
- KEYPAD_MAP.put('j', '5'); KEYPAD_MAP.put('k', '5'); KEYPAD_MAP.put('l', '5');
- KEYPAD_MAP.put('J', '5'); KEYPAD_MAP.put('K', '5'); KEYPAD_MAP.put('L', '5');
-
- KEYPAD_MAP.put('m', '6'); KEYPAD_MAP.put('n', '6'); KEYPAD_MAP.put('o', '6');
- KEYPAD_MAP.put('M', '6'); KEYPAD_MAP.put('N', '6'); KEYPAD_MAP.put('O', '6');
-
- KEYPAD_MAP.put('p', '7'); KEYPAD_MAP.put('q', '7'); KEYPAD_MAP.put('r', '7'); KEYPAD_MAP.put('s', '7');
- KEYPAD_MAP.put('P', '7'); KEYPAD_MAP.put('Q', '7'); KEYPAD_MAP.put('R', '7'); KEYPAD_MAP.put('S', '7');
-
- KEYPAD_MAP.put('t', '8'); KEYPAD_MAP.put('u', '8'); KEYPAD_MAP.put('v', '8');
- KEYPAD_MAP.put('T', '8'); KEYPAD_MAP.put('U', '8'); KEYPAD_MAP.put('V', '8');
-
- KEYPAD_MAP.put('w', '9'); KEYPAD_MAP.put('x', '9'); KEYPAD_MAP.put('y', '9'); KEYPAD_MAP.put('z', '9');
- KEYPAD_MAP.put('W', '9'); KEYPAD_MAP.put('X', '9'); KEYPAD_MAP.put('Y', '9'); KEYPAD_MAP.put('Z', '9');
- }
-}
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
deleted file mode 100644
index 8a8a675..0000000
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package android.telephony;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.ServiceState;
-import android.telephony.CellLocation;
-import android.util.Log;
-
-import com.android.internal.telephony.IPhoneStateListener;
-
-/**
- * A listener class for monitoring changes in specific telephony states
- * on the device, including service state, signal strength, message
- * waiting indicator (voicemail), and others.
- * <p>
- * Override the methods for the state that you wish to receive updates for, and
- * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_
- * flags to {@link TelephonyManager#listen TelephonyManager.listen()}.
- * <p>
- * Note that access to some telephony information is
- * permission-protected. Your application won't receive updates for protected
- * information unless it has the appropriate permissions declared in
- * its manifest file. Where permissions apply, they are noted in the
- * appropriate LISTEN_ flags.
- */
-public class PhoneStateListener {
-
- /**
- * Stop listening for updates.
- */
- public static final int LISTEN_NONE = 0;
-
- /**
- * Listen for changes to the network service state (cellular).
- *
- * @see #onServiceStateChanged
- * @see ServiceState
- */
- public static final int LISTEN_SERVICE_STATE = 0x00000001;
-
- /**
- * Listen for changes to the network signal strength (cellular).
- * <p>
- * Example: The status bar uses this to control the signal-strength
- * icon.
- *
- * @see #onSignalStrengthChanged
- */
- public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002;
-
- /**
- * Listen for changes to the message-waiting indicator.
- * <p>
- * Example: The status bar uses this to determine when to display the
- * voicemail icon.
- *
- * @see #onMessageWaitingIndicatorChanged
- */
- public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004;
-
- /**
- * Listen for changes to the call-forwarding indicator.
- *
- * @see #onCallForwardingIndicatorChanged
- */
- public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008;
-
- /**
- * Listen for changes to the device's cell location. Note that
- * this will result in frequent callbacks to the listener.
- * {@more}
- * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
- * ACCESS_COARSE_LOCATION}
- * <p>
- * If you need regular location updates but want more control over
- * the update interval or location precision, you can set up a listener
- * through the {@link android.location.LocationManager location manager}
- * instead.
- *
- * @see #onCellLocationChanged
- */
- public static final int LISTEN_CELL_LOCATION = 0x00000010;
-
- /**
- * Listen for changes to the device call state.
- *
- * @see #onCallStateChanged
- */
- public static final int LISTEN_CALL_STATE = 0x00000020;
-
- /**
- * Listen for changes to the data connection state (cellular).
- *
- * @see #onDataConnectionStateChanged
- */
- public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040;
-
- /**
- * Listen for changes to the direction of data traffic on the data
- * connection (cellular).
- *
- * Example: The status bar uses this to display the appropriate
- * data-traffic icon.
- *
- * @see #onDataActivity
- */
- public static final int LISTEN_DATA_ACTIVITY = 0x00000080;
-
- public PhoneStateListener() {
- }
-
- /**
- * Callback invoked when device service state changes.
- *
- * @see ServiceState#STATE_EMERGENCY_ONLY
- * @see ServiceState#STATE_IN_SERVICE
- * @see ServiceState#STATE_OUT_OF_SERVICE
- * @see ServiceState#STATE_POWER_OFF
- */
- public void onServiceStateChanged(ServiceState serviceState) {
- // default implementation empty
- }
-
- /**
- * Callback invoked when network signal strength changes.
- *
- * @see ServiceState#STATE_EMERGENCY_ONLY
- * @see ServiceState#STATE_IN_SERVICE
- * @see ServiceState#STATE_OUT_OF_SERVICE
- * @see ServiceState#STATE_POWER_OFF
- */
- public void onSignalStrengthChanged(int asu) {
- // default implementation empty
- }
-
- /**
- * Callback invoked when the message-waiting indicator changes.
- */
- public void onMessageWaitingIndicatorChanged(boolean mwi) {
- // default implementation empty
- }
-
- /**
- * Callback invoked when the call-forwarding indicator changes.
- */
- public void onCallForwardingIndicatorChanged(boolean cfi) {
- // default implementation empty
- }
-
- /**
- * Callback invoked when device cell location changes.
- */
- public void onCellLocationChanged(CellLocation location) {
- // default implementation empty
- }
-
- /**
- * Callback invoked when device call state changes.
- *
- * @see TelephonyManager#CALL_STATE_IDLE
- * @see TelephonyManager#CALL_STATE_RINGING
- * @see TelephonyManager#CALL_STATE_OFFHOOK
- */
- public void onCallStateChanged(int state, String incomingNumber) {
- // default implementation empty
- }
-
- /**
- * Callback invoked when connection state changes.
- *
- * @see TelephonyManager#DATA_DISCONNECTED
- * @see TelephonyManager#DATA_CONNECTING
- * @see TelephonyManager#DATA_CONNECTED
- * @see TelephonyManager#DATA_SUSPENDED
- */
- public void onDataConnectionStateChanged(int state) {
- // default implementation empty
- }
-
- /**
- * Callback invoked when data activity state changes.
- *
- * @see TelephonyManager#DATA_ACTIVITY_NONE
- * @see TelephonyManager#DATA_ACTIVITY_IN
- * @see TelephonyManager#DATA_ACTIVITY_OUT
- * @see TelephonyManager#DATA_ACTIVITY_INOUT
- */
- public void onDataActivity(int direction) {
- // default implementation empty
- }
-
- /**
- * The callback methods need to be called on the handler thread where
- * this object was created. If the binder did that for us it'd be nice.
- */
- IPhoneStateListener callback = new IPhoneStateListener.Stub() {
- public void onServiceStateChanged(ServiceState serviceState) {
- Message.obtain(mHandler, LISTEN_SERVICE_STATE, 0, 0, serviceState).sendToTarget();
- }
-
- public void onSignalStrengthChanged(int asu) {
- Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTH, asu, 0, null).sendToTarget();
- }
-
- public void onMessageWaitingIndicatorChanged(boolean mwi) {
- Message.obtain(mHandler, LISTEN_MESSAGE_WAITING_INDICATOR, mwi ? 1 : 0, 0, null)
- .sendToTarget();
- }
-
- public void onCallForwardingIndicatorChanged(boolean cfi) {
- Message.obtain(mHandler, LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null)
- .sendToTarget();
- }
-
- public void onCellLocationChanged(Bundle bundle) {
- CellLocation location = CellLocation.newFromBundle(bundle);
- Message.obtain(mHandler, LISTEN_CELL_LOCATION, 0, 0, location).sendToTarget();
- }
-
- public void onCallStateChanged(int state, String incomingNumber) {
- Message.obtain(mHandler, LISTEN_CALL_STATE, state, 0, incomingNumber).sendToTarget();
- }
-
- public void onDataConnectionStateChanged(int state) {
- Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, 0, null).sendToTarget();
- }
-
- public void onDataActivity(int direction) {
- Message.obtain(mHandler, LISTEN_DATA_ACTIVITY, direction, 0, null).sendToTarget();
- }
- };
-
- Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- //Log.d("TelephonyRegistry", "what=0x" + Integer.toHexString(msg.what) + " msg=" + msg);
- switch (msg.what) {
- case LISTEN_SERVICE_STATE:
- PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj);
- break;
- case LISTEN_SIGNAL_STRENGTH:
- PhoneStateListener.this.onSignalStrengthChanged(msg.arg1);
- break;
- case LISTEN_MESSAGE_WAITING_INDICATOR:
- PhoneStateListener.this.onMessageWaitingIndicatorChanged(msg.arg1 != 0);
- break;
- case LISTEN_CALL_FORWARDING_INDICATOR:
- PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0);
- break;
- case LISTEN_CELL_LOCATION:
- PhoneStateListener.this.onCellLocationChanged((CellLocation)msg.obj);
- break;
- case LISTEN_CALL_STATE:
- PhoneStateListener.this.onCallStateChanged(msg.arg1, (String)msg.obj);
- break;
- case LISTEN_DATA_CONNECTION_STATE:
- PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1);
- break;
- case LISTEN_DATA_ACTIVITY:
- PhoneStateListener.this.onDataActivity(msg.arg1);
- break;
- }
- }
- };
-}
diff --git a/telephony/java/android/telephony/ServiceState.aidl b/telephony/java/android/telephony/ServiceState.aidl
deleted file mode 100644
index b1cf379..0000000
--- a/telephony/java/android/telephony/ServiceState.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/* //device/java/android/android/content/Intent.aidl
-**
-** 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 android.telephony;
-
-parcelable ServiceState;
-
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
deleted file mode 100644
index 2c58051..0000000
--- a/telephony/java/android/telephony/ServiceState.java
+++ /dev/null
@@ -1,331 +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.telephony;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import com.android.internal.telephony.Phone;
-
-/**
- * Contains phone state and service related information.
- *
- * The following phone information is included in returned ServiceState:
- *
- * <ul>
- * <li>Service state: IN_SERVICE, OUT_OF_SERVICE, EMERGENCY_ONLY, POWER_OFF
- * <li>Roaming indicator
- * <li>Operator name, short name and numeric id
- * <li>Network selection mode
- * </ul>
- */
-public class ServiceState implements Parcelable {
-
- /**
- * Normal operation condition, the phone is registered
- * with an operator either in home network or in roaming.
- */
- public static final int STATE_IN_SERVICE = 0;
-
- /**
- * Phone is not registered with any operator, the phone
- * can be currently searching a new operator to register to, or not
- * searching to registration at all, or registration is denied, or radio
- * signal is not available.
- */
- public static final int STATE_OUT_OF_SERVICE = 1;
-
- /**
- * The phone is registered and locked. Only emergency numbers are allowed. {@more}
- */
- public static final int STATE_EMERGENCY_ONLY = 2;
-
- /**
- * Radio of telephony is explictly powered off.
- */
- public static final int STATE_POWER_OFF = 3;
-
- private int mState = STATE_OUT_OF_SERVICE;
- private boolean mRoaming;
- private String mOperatorAlphaLong;
- private String mOperatorAlphaShort;
- private String mOperatorNumeric;
- private boolean mIsManualNetworkSelection;
-
- /**
- * Create a new ServiceState from a intent notifier Bundle
- *
- * This method is used by PhoneStateIntentReceiver and maybe by
- * external applications.
- *
- * @param m Bundle from intent notifier
- * @return newly created ServiceState
- * @hide
- */
- public static ServiceState newFromBundle(Bundle m) {
- ServiceState ret;
- ret = new ServiceState();
- ret.setFromNotifierBundle(m);
- return ret;
- }
-
- /**
- * Empty constructor
- */
- public ServiceState() {
- }
-
- /**
- * Copy constructors
- *
- * @param s Source service state
- */
- public ServiceState(ServiceState s) {
- copyFrom(s);
- }
-
- protected void copyFrom(ServiceState s) {
- mState = s.mState;
- mRoaming = s.mRoaming;
- mOperatorAlphaLong = s.mOperatorAlphaLong;
- mOperatorAlphaShort = s.mOperatorAlphaShort;
- mOperatorNumeric = s.mOperatorNumeric;
- mIsManualNetworkSelection = s.mIsManualNetworkSelection;
- }
-
- /**
- * Construct a ServiceState object from the given parcel.
- */
- public ServiceState(Parcel in) {
- mState = in.readInt();
- mRoaming = in.readInt() != 0;
- mOperatorAlphaLong = in.readString();
- mOperatorAlphaShort = in.readString();
- mOperatorNumeric = in.readString();
- mIsManualNetworkSelection = in.readInt() != 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(mState);
- out.writeInt(mRoaming ? 1 : 0);
- out.writeString(mOperatorAlphaLong);
- out.writeString(mOperatorAlphaShort);
- out.writeString(mOperatorNumeric);
- out.writeInt(mIsManualNetworkSelection ? 1 : 0);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public static final Parcelable.Creator<ServiceState> CREATOR = new Parcelable.Creator() {
- public ServiceState createFromParcel(Parcel in) {
- return new ServiceState(in);
- }
-
- public ServiceState[] newArray(int size) {
- return new ServiceState[size];
- }
- };
-
- /**
- * Get current servcie state of phone
- *
- * @see #STATE_IN_SERVICE
- * @see #STATE_OUT_OF_SERVICE
- * @see #STATE_EMERGENCY_ONLY
- * @see #STATE_POWER_OFF
- */
- public int getState() {
- return mState;
- }
-
- /**
- * Get current roaming indicator of phone
- * (note: not just decoding from TS 27.007 7.2)
- *
- * @return true if TS 27.007 7.2 roaming is true
- * and ONS is different from SPN
- *
- */
- public boolean getRoaming() {
- return mRoaming;
- }
-
- /**
- * Get current registered operator name in long alphanumeric format
- *
- * In GSM/UMTS, long format can be upto 16 characters long
- *
- * @return long name of operator, null if unregistered or unknown
- */
- public String getOperatorAlphaLong() {
- return mOperatorAlphaLong;
- }
-
- /**
- * Get current registered operator name in short lphanumeric format
- *
- * In GSM/UMST, short format can be upto 8 characters long
- *
- * @return short name of operator, null if unregistered or unknown
- */
- public String getOperatorAlphaShort() {
- return mOperatorAlphaShort;
- }
-
- /**
- * Get current registered operator numeric id
- *
- * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
- * network code
- *
- * The country code can be decoded using MccTable.countryCodeForMcc()
- *
- * @return numeric format of operator, null if unregistered or unknown
- */
- public String getOperatorNumeric() {
- return mOperatorNumeric;
- }
-
- /**
- * Get current network selection mode
- *
- * @return true if manual mode, false if automatic mode
- */
- public boolean getIsManualSelection() {
- return mIsManualNetworkSelection;
- }
-
- @Override
- public int hashCode() {
- return (mState * 0x1234)
- + (mRoaming ? 1 : 0)
- + (mIsManualNetworkSelection ? 1 : 0)
- + ((null == mOperatorAlphaLong) ? 0 : mOperatorAlphaLong.hashCode())
- + ((null == mOperatorAlphaShort) ? 0 : mOperatorAlphaShort.hashCode())
- + ((null == mOperatorNumeric) ? 0 : mOperatorNumeric.hashCode());
- }
-
- @Override
- public boolean equals (Object o) {
- ServiceState s;
-
- try {
- s = (ServiceState) o;
- } catch (ClassCastException ex) {
- return false;
- }
-
- if (o == null) {
- return false;
- }
-
- return mState == s.mState
- && mRoaming == s.mRoaming
- && mIsManualNetworkSelection == s.mIsManualNetworkSelection
- && equalsHandlesNulls(mOperatorAlphaLong, s.mOperatorAlphaLong)
- && equalsHandlesNulls(mOperatorAlphaShort, s.mOperatorAlphaShort)
- && equalsHandlesNulls(mOperatorNumeric, s.mOperatorNumeric);
- }
-
- @Override
- public String toString() {
- return mState + " " + (mRoaming ? "roaming" : "home")
- + " " + mOperatorAlphaLong
- + " " + mOperatorAlphaShort
- + " " + mOperatorNumeric
- + " " + (mIsManualNetworkSelection ? "(manual)" : "");
- }
-
- public void setStateOutOfService() {
- mState = STATE_OUT_OF_SERVICE;
- mRoaming = false;
- mOperatorAlphaLong = null;
- mOperatorAlphaShort = null;
- mOperatorNumeric = null;
- mIsManualNetworkSelection = false;
- }
-
- public void setStateOff() {
- mState = STATE_POWER_OFF;
- mRoaming = false;
- mOperatorAlphaLong = null;
- mOperatorAlphaShort = null;
- mOperatorNumeric = null;
- mIsManualNetworkSelection = false;
- }
-
- public void setState(int state) {
- mState = state;
- }
-
- public void setRoaming(boolean roaming) {
- mRoaming = roaming;
- }
-
- public void setOperatorName(String longName, String shortName, String numeric) {
- mOperatorAlphaLong = longName;
- mOperatorAlphaShort = shortName;
- mOperatorNumeric = numeric;
- }
-
- public void setIsManualSelection(boolean isManual) {
- mIsManualNetworkSelection = isManual;
- }
-
- /**
- * Test whether two objects hold the same data values or both are null
- *
- * @param a first obj
- * @param b second obj
- * @return true if two objects equal or both are null
- */
- private static boolean equalsHandlesNulls (Object a, Object b) {
- return (a == null) ? (b == null) : a.equals (b);
- }
-
- /**
- * Set ServiceState based on intent notifier map
- *
- * @param m intent notifier map
- * @hide
- */
- private void setFromNotifierBundle(Bundle m) {
- mState = m.getInt("state");
- mRoaming = m.getBoolean("roaming");
- mOperatorAlphaLong = m.getString("operator-alpha-long");
- mOperatorAlphaShort = m.getString("operator-alpha-short");
- mOperatorNumeric = m.getString("operator-numeric");
- mIsManualNetworkSelection = m.getBoolean("manual");
- }
-
- /**
- * Set intent notifier Bundle based on service state
- *
- * @param m intent notifier Bundle
- * @hide
- */
- public void fillInNotifierBundle(Bundle m) {
- m.putInt("state", mState);
- m.putBoolean("roaming", Boolean.valueOf(mRoaming));
- m.putString("operator-alpha-long", mOperatorAlphaLong);
- m.putString("operator-alpha-short", mOperatorAlphaShort);
- m.putString("operator-numeric", mOperatorNumeric);
- m.putBoolean("manual", Boolean.valueOf(mIsManualNetworkSelection));
- }
-}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
deleted file mode 100644
index c5b1b73..0000000
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ /dev/null
@@ -1,689 +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 com.android.internal.telephony.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SdkConstant;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-
-
-/**
- * Provides access to information about the telephony services on
- * the device. Applications can use the methods in this class to
- * determine telephony services and states, as well as to access some
- * types of subscriber information. Applications can also register
- * a listener to receive notification of telephony state changes.
- * <p>
- * You do not instantiate this class directly; instead, you retrieve
- * a reference to an instance through
- * {@link android.content.Context#getSystemService
- * Context.getSystemService(Context.TELEPHONY_SERVICE)}.
- * <p>
- * Note that acess to some telephony information is
- * permission-protected. Your application cannot access the protected
- * information unless it has the appropriate permissions declared in
- * its manifest file. Where permissions apply, they are noted in the
- * the methods through which you access the protected information.
- */
-public class TelephonyManager {
- private static final String TAG = "TelephonyManager";
-
- private Context mContext;
- private ITelephonyRegistry mRegistry;
-
- /** @hide */
- public TelephonyManager(Context context) {
- mContext = context;
- mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- }
-
- /** @hide */
- private TelephonyManager() {
- }
-
- private static TelephonyManager sInstance = new TelephonyManager();
-
- /** @hide */
- public static TelephonyManager getDefault() {
- return sInstance;
- }
-
-
- //
- // Broadcast Intent actions
- //
-
- /**
- * Broadcast intent action indicating that the call state (cellular)
- * on the device has changed.
- *
- * <p>
- * The {@link #EXTRA_STATE} extra indicates the new call state.
- * If the new state is RINGING, a second extra
- * {@link #EXTRA_INCOMING_NUMBER} provides the incoming phone number as
- * a String.
- *
- * <p class="note">
- * Requires the READ_PHONE_STATE permission.
- *
- * <p class="note">
- * This was a {@link android.content.Context#sendStickyBroadcast sticky}
- * broadcast in version 1.0, but it is no longer sticky.
- * Instead, use {@link #getCallState} to synchronously query the current call state.
- *
- * @see #EXTRA_STATE
- * @see #EXTRA_INCOMING_NUMBER
- * @see #getCallState
- *
- * @hide pending API Council approval
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PHONE_STATE_CHANGED =
- "android.intent.action.PHONE_STATE";
-
- /**
- * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
- * for a String containing the new call state.
- *
- * @see #EXTRA_STATE_IDLE
- * @see #EXTRA_STATE_RINGING
- * @see #EXTRA_STATE_OFFHOOK
- *
- * <p class="note">
- * Retrieve with
- * {@link android.content.Intent#getStringExtra(String)}.
- *
- * @hide pending API Council approval
- */
- public static final String EXTRA_STATE = Phone.STATE_KEY;
-
- /**
- * Value used with {@link #EXTRA_STATE} corresponding to
- * {@link #CALL_STATE_IDLE}.
- *
- * @hide pending API Council approval
- */
- public static final String EXTRA_STATE_IDLE = Phone.State.IDLE.toString();
-
- /**
- * Value used with {@link #EXTRA_STATE} corresponding to
- * {@link #CALL_STATE_RINGING}.
- *
- * @hide pending API Council approval
- */
- public static final String EXTRA_STATE_RINGING = Phone.State.RINGING.toString();
-
- /**
- * Value used with {@link #EXTRA_STATE} corresponding to
- * {@link #CALL_STATE_OFFHOOK}.
- *
- * @hide pending API Council approval
- */
- public static final String EXTRA_STATE_OFFHOOK = Phone.State.OFFHOOK.toString();
-
- /**
- * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
- * for a String containing the incoming phone number.
- * Only valid when the new call state is RINGING.
- *
- * <p class="note">
- * Retrieve with
- * {@link android.content.Intent#getStringExtra(String)}.
- *
- * @hide pending API Council approval
- */
- public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
-
-
- //
- //
- // Device Info
- //
- //
-
- /**
- * Returns the software version number for the device, for example,
- * the IMEI/SV for GSM phones.
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- */
- public String getDeviceSoftwareVersion() {
- try {
- return getSubscriberInfo().getDeviceSvn();
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- /**
- * Returns the unique device ID, for example,the IMEI for GSM
- * phones.
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- */
- public String getDeviceId() {
- try {
- return getSubscriberInfo().getDeviceId();
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- /**
- * Returns the current location of the device.
- *
- * <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
- * ACCESS_COARSE_LOCATION}.
- */
- public CellLocation getCellLocation() {
- try {
- Bundle bundle = getITelephony().getCellLocation();
- return CellLocation.newFromBundle(bundle);
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- /**
- * Enables location update notifications. {@link PhoneStateListener#onCellLocationChanged
- * PhoneStateListener.onCellLocationChanged} will be called on location updates.
- *
- * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
- * CONTROL_LOCATION_UPDATES}
- *
- * @hide
- */
- public void enableLocationUpdates() {
- try {
- getITelephony().enableLocationUpdates();
- } catch (RemoteException ex) {
- }
- }
-
- /**
- * Disables location update notifications. {@link PhoneStateListener#onCellLocationChanged
- * PhoneStateListener.onCellLocationChanged} will be called on location updates.
- *
- * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
- * CONTROL_LOCATION_UPDATES}
- *
- * @hide
- */
- public void disableLocationUpdates() {
- try {
- getITelephony().disableLocationUpdates();
- } catch (RemoteException ex) {
- }
- }
-
- /**
- * Returns the neighboring cell information of the device.
- *
- * @return List of NeighboringCellInfo or null if info unavailable.
- *
- * <p>Requires Permission:
- * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES}
- */
- public List<NeighboringCellInfo> getNeighboringCellInfo() {
- try {
- return getITelephony().getNeighboringCellInfo();
- } catch (RemoteException ex) {
- }
- return null;
-
- }
-
- /**
- * No phone module
- */
- public static final int PHONE_TYPE_NONE = 0;
-
- /**
- * GSM phone
- */
- public static final int PHONE_TYPE_GSM = 1;
-
- /**
- * Returns a constant indicating the device phone type.
- *
- * @see #PHONE_TYPE_NONE
- * @see #PHONE_TYPE_GSM
- */
- public int getPhoneType() {
- // in the future, we should really check this
- return PHONE_TYPE_GSM;
- }
-
- //
- //
- // Current Network
- //
- //
-
- /**
- * Returns the alphabetic name of current registered operator.
- * <p>
- * Availability: Only when user is registered to a network
- */
- public String getNetworkOperatorName() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA);
- }
-
- /**
- * Returns the numeric name (MCC+MNC) of current registered operator.
- * <p>
- * Availability: Only when user is registered to a network
- */
- public String getNetworkOperator() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
- }
-
- /**
- * Returns true if the device is considered roaming on the current
- * network, for GSM purposes.
- * <p>
- * Availability: Only when user registered to a network
- */
- public boolean isNetworkRoaming() {
- return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
- }
-
- /**
- * Returns the ISO country code equivilent of the current registered
- * operator's MCC (Mobile Country Code).
- * <p>
- * Availability: Only when user is registered to a network
- */
- public String getNetworkCountryIso() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
- }
-
- /** Network type is unknown */
- public static final int NETWORK_TYPE_UNKNOWN = 0;
- /** Current network is GPRS */
- public static final int NETWORK_TYPE_GPRS = 1;
- /** Current network is EDGE */
- public static final int NETWORK_TYPE_EDGE = 2;
- /** Current network is UMTS */
- public static final int NETWORK_TYPE_UMTS = 3;
-
- /**
- * Returns a constant indicating the radio technology (network type)
- * currently in use on the device.
- * @return the network type
- *
- * @see #NETWORK_TYPE_UNKNOWN
- * @see #NETWORK_TYPE_GPRS
- * @see #NETWORK_TYPE_EDGE
- * @see #NETWORK_TYPE_UMTS
- */
- public int getNetworkType() {
- String prop = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE);
- if ("GPRS".equals(prop)) {
- return NETWORK_TYPE_GPRS;
- }
- else if ("EDGE".equals(prop)) {
- return NETWORK_TYPE_EDGE;
- }
- else if ("UMTS".equals(prop)) {
- return NETWORK_TYPE_UMTS;
- }
- else {
- return NETWORK_TYPE_UNKNOWN;
- }
- }
-
- /**
- * Returns a string representation of the radio technology (network type)
- * currently in use on the device.
- * @return the name of the radio technology
- *
- * @hide pending API council review
- */
- public String getNetworkTypeName() {
- switch (getNetworkType()) {
- case NETWORK_TYPE_GPRS:
- return "GPRS";
- case NETWORK_TYPE_EDGE:
- return "EDGE";
- case NETWORK_TYPE_UMTS:
- return "UMTS";
- default:
- return "UNKNOWN";
- }
- }
-
- //
- //
- // SIM Card
- //
- //
-
- /** SIM card state: Unknown. Signifies that the SIM is in transition
- * between states. For example, when the user inputs the SIM pin
- * under PIN_REQUIRED state, a query for sim status returns
- * this state before turning to SIM_STATE_READY. */
- public static final int SIM_STATE_UNKNOWN = 0;
- /** SIM card state: no SIM card is available in the device */
- public static final int SIM_STATE_ABSENT = 1;
- /** SIM card state: Locked: requires the user's SIM PIN to unlock */
- public static final int SIM_STATE_PIN_REQUIRED = 2;
- /** SIM card state: Locked: requires the user's SIM PUK to unlock */
- public static final int SIM_STATE_PUK_REQUIRED = 3;
- /** SIM card state: Locked: requries a network PIN to unlock */
- public static final int SIM_STATE_NETWORK_LOCKED = 4;
- /** SIM card state: Ready */
- public static final int SIM_STATE_READY = 5;
-
- /**
- * Returns a constant indicating the state of the
- * device SIM card.
- *
- * @see #SIM_STATE_UNKNOWN
- * @see #SIM_STATE_ABSENT
- * @see #SIM_STATE_PIN_REQUIRED
- * @see #SIM_STATE_PUK_REQUIRED
- * @see #SIM_STATE_NETWORK_LOCKED
- * @see #SIM_STATE_READY
- */
- public int getSimState() {
- String prop = SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE);
- if ("ABSENT".equals(prop)) {
- return SIM_STATE_ABSENT;
- }
- else if ("PIN_REQUIRED".equals(prop)) {
- return SIM_STATE_PIN_REQUIRED;
- }
- else if ("PUK_REQUIRED".equals(prop)) {
- return SIM_STATE_PUK_REQUIRED;
- }
- else if ("NETWORK_LOCKED".equals(prop)) {
- return SIM_STATE_NETWORK_LOCKED;
- }
- else if ("READY".equals(prop)) {
- return SIM_STATE_READY;
- }
- else {
- return SIM_STATE_UNKNOWN;
- }
- }
-
- /**
- * Returns the MCC+MNC (mobile country code + mobile network code) of the
- * provider of the SIM. 5 or 6 decimal digits.
- * <p>
- * Availability: SIM state must be {@link #SIM_STATE_READY}
- *
- * @see #getSimState
- */
- public String getSimOperator() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC);
- }
-
- /**
- * Returns the Service Provider Name (SPN).
- * <p>
- * Availability: SIM state must be {@link #SIM_STATE_READY}
- *
- * @see #getSimState
- */
- public String getSimOperatorName() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ALPHA);
- }
-
- /**
- * Returns the ISO country code equivalent for the SIM provider's country code.
- */
- public String getSimCountryIso() {
- return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ISO_COUNTRY);
- }
-
- /**
- * Returns the serial number of the SIM, if applicable.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- */
- public String getSimSerialNumber() {
- try {
- return getSubscriberInfo().getSimSerialNumber();
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- //
- //
- // Subscriber Info
- //
- //
-
- /**
- * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- */
- public String getSubscriberId() {
- try {
- return getSubscriberInfo().getSubscriberId();
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- /**
- * Returns the phone number string for line 1, for example, the MSISDN
- * for a GSM phone.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- */
- public String getLine1Number() {
- try {
- return getSubscriberInfo().getLine1Number();
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- /**
- * Returns the alphabetic identifier associated with the line 1 number.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- * @hide
- * nobody seems to call this.
- */
- public String getLine1AlphaTag() {
- try {
- return getSubscriberInfo().getLine1AlphaTag();
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- /**
- * Returns the voice mail number.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- */
- public String getVoiceMailNumber() {
- try {
- return getSubscriberInfo().getVoiceMailNumber();
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- /**
- * Retrieves the alphabetic identifier associated with the voice
- * mail number.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- */
- public String getVoiceMailAlphaTag() {
- try {
- return getSubscriberInfo().getVoiceMailAlphaTag();
- } catch (RemoteException ex) {
- }
- return null;
- }
-
- private IPhoneSubInfo getSubscriberInfo() {
- // get it each time because that process crashes a lot
- return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
- }
-
-
- /** Device call state: No activity. */
- public static final int CALL_STATE_IDLE = 0;
- /** Device call state: Ringing. A new call arrived and is
- * ringing or waiting. In the latter case, another call is
- * already active. */
- public static final int CALL_STATE_RINGING = 1;
- /** Device call state: Off-hook. At least one call exists
- * that is dialing, active, or on hold, and no calls are ringing
- * or waiting. */
- public static final int CALL_STATE_OFFHOOK = 2;
-
- /**
- * Returns a constant indicating the call state (cellular) on the device.
- */
- public int getCallState() {
- try {
- return getITelephony().getCallState();
- } catch (RemoteException ex) {
- // the phone process is restarting.
- return CALL_STATE_IDLE;
- }
- }
-
- /** Data connection activity: No traffic. */
- public static final int DATA_ACTIVITY_NONE = 0x00000000;
- /** Data connection activity: Currently receiving IP PPP traffic. */
- public static final int DATA_ACTIVITY_IN = 0x00000001;
- /** Data connection activity: Currently sending IP PPP traffic. */
- public static final int DATA_ACTIVITY_OUT = 0x00000002;
- /** Data connection activity: Currently both sending and receiving
- * IP PPP traffic. */
- public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT;
-
- /**
- * Returns a constant indicating the type of activity on a data connection
- * (cellular).
- *
- * @see #DATA_ACTIVITY_NONE
- * @see #DATA_ACTIVITY_IN
- * @see #DATA_ACTIVITY_OUT
- * @see #DATA_ACTIVITY_INOUT
- */
- public int getDataActivity() {
- try {
- return getITelephony().getDataActivity();
- } catch (RemoteException ex) {
- // the phone process is restarting.
- return DATA_ACTIVITY_NONE;
- }
- }
-
- /** Data connection state: Disconnected. IP traffic not available. */
- public static final int DATA_DISCONNECTED = 0;
- /** Data connection state: Currently setting up a data connection. */
- public static final int DATA_CONNECTING = 1;
- /** Data connection state: Connected. IP traffic should be available. */
- public static final int DATA_CONNECTED = 2;
- /** Data connection state: Suspended. The connection is up, but IP
- * traffic is temporarily unavailable. For example, in a 2G network,
- * data activity may be suspended when a voice call arrives. */
- public static final int DATA_SUSPENDED = 3;
-
- /**
- * Returns a constant indicating the current data connection state
- * (cellular).
- *
- * @see #DATA_DISCONNECTED
- * @see #DATA_CONNECTING
- * @see #DATA_CONNECTED
- * @see #DATA_SUSPENDED
- */
- public int getDataState() {
- try {
- return getITelephony().getDataState();
- } catch (RemoteException ex) {
- // the phone process is restarting.
- return DATA_DISCONNECTED;
- }
- }
-
- private ITelephony getITelephony() {
- return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
- }
-
- //
- //
- // PhoneStateListener
- //
- //
-
- /**
- * Registers a listener object to receive notification of changes
- * in specified telephony states.
- * <p>
- * To register a listener, pass a {@link PhoneStateListener}
- * and specify at least one telephony state of interest in
- * the events argument.
- *
- * At registration, and when a specified telephony state
- * changes, the telephony manager invokes the appropriate
- * callback method on the listener object and passes the
- * current (udpated) values.
- * <p>
- * To unregister a listener, pass the listener object and set the
- * events argument to
- * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
- *
- * @param listener The {@link PhoneStateListener} object to register
- * (or unregister)
- * @param events The telephony state(s) of interest to the listener,
- * as a bitwise-OR combination of {@link PhoneStateListener}
- * LISTEN_ flags.
- */
- public void listen(PhoneStateListener listener, int events) {
- String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
- try {
- Boolean notifyNow = (getITelephony() != null);
- mRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
- } catch (RemoteException ex) {
- // system process dead
- }
- }
-}
diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java
deleted file mode 100644
index fb9b73a..0000000
--- a/telephony/java/android/telephony/gsm/GsmCellLocation.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 android.telephony.gsm;
-
-import android.os.Bundle;
-import com.android.internal.telephony.Phone;
-import android.telephony.CellLocation;
-
-/**
- * Represents the cell location on a GSM phone.
- */
-public class GsmCellLocation extends CellLocation
-{
- private int mLac;
- private int mCid;
-
- /**
- * Empty constructor. Initializes the LAC and CID to -1.
- */
- public GsmCellLocation() {
- mLac = -1;
- mCid = -1;
- }
-
- /**
- * Initialize the object from a bundle.
- */
- public GsmCellLocation(Bundle bundle) {
- mLac = bundle.getInt("lac");
- mCid = bundle.getInt("cid");
- }
-
- /**
- * @return gsm location area code, -1 if unknown, 0xffff max legal value
- */
- public int getLac() {
- return mLac;
- }
-
- /**
- * @return gsm cell id, -1 if unknown, 0xffff max legal value
- */
- public int getCid() {
- return mCid;
- }
-
- /**
- * Invalidate this object. The location area code and the cell id are set to -1.
- */
- public void setStateInvalid() {
- mLac = -1;
- mCid = -1;
- }
-
- /**
- * Set the location area code and the cell id.
- */
- public void setLacAndCid(int lac, int cid) {
- mLac = lac;
- mCid = cid;
- }
-
- @Override
- public int hashCode() {
- return mLac ^ mCid;
- }
-
- @Override
- public boolean equals(Object o) {
- GsmCellLocation s;
-
- try {
- s = (GsmCellLocation)o;
- } catch (ClassCastException ex) {
- return false;
- }
-
- if (o == null) {
- return false;
- }
-
- return equalsHandlesNulls(mLac, s.mLac) && equalsHandlesNulls(mCid, s.mCid);
- }
-
- @Override
- public String toString() {
- return "["+ mLac + "," + mCid + "]";
- }
-
- /**
- * Test whether two objects hold the same data values or both are null
- *
- * @param a first obj
- * @param b second obj
- * @return true if two objects equal or both are null
- */
- private static boolean equalsHandlesNulls(Object a, Object b) {
- return (a == null) ? (b == null) : a.equals (b);
- }
-
- /**
- * Set intent notifier Bundle based on service state
- *
- * @param m intent notifier Bundle
- */
- public void fillInNotifierBundle(Bundle m) {
- m.putInt("lac", mLac);
- m.putInt("cid", mCid);
- }
-}
-
-
diff --git a/telephony/java/android/telephony/gsm/SmsManager.java b/telephony/java/android/telephony/gsm/SmsManager.java
deleted file mode 100644
index c63b530..0000000
--- a/telephony/java/android/telephony/gsm/SmsManager.java
+++ /dev/null
@@ -1,432 +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 android.os.RemoteException;
-import android.os.IServiceManager;
-import android.os.ServiceManager;
-import android.os.ServiceManagerNative;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.gsm.EncodeException;
-import com.android.internal.telephony.gsm.GsmAlphabet;
-import com.android.internal.telephony.gsm.ISms;
-import com.android.internal.telephony.gsm.SimConstants;
-import com.android.internal.telephony.gsm.SmsRawData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Manages SMS operations such as sending data, text, and pdu SMS messages.
- * Get this object by calling the static method SmsManager.getDefault().
- */
-public final class SmsManager {
- private static SmsManager sInstance;
-
- /**
- * Send a text based SMS.
- *
- * @param destinationAddress the address to send the message to
- * @param scAddress is the service center address or null to use
- * the current default SMSC
- * @param text the body of the message to send
- * @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is sucessfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown 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 text are empty
- */
- public void sendTextMessage(
- String destinationAddress, String scAddress, String text,
- PendingIntent sentIntent, PendingIntent deliveryIntent) {
- if (TextUtils.isEmpty(destinationAddress)) {
- throw new IllegalArgumentException("Invalid destinationAddress");
- }
-
- if (TextUtils.isEmpty(text)) {
- throw new IllegalArgumentException("Invalid message body");
- }
-
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
- scAddress, destinationAddress, text, (deliveryIntent != null));
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
- }
-
- /**
- * Divide a text message into several messages, none bigger than
- * the maximum SMS message size.
- *
- * @param text the original message. Must not be null.
- * @return an <code>ArrayList</code> of strings that, in order,
- * comprise the original message
- */
- public ArrayList<String> divideMessage(String text) {
- int size = text.length();
- int[] params = SmsMessage.calculateLength(text, false);
- /* SmsMessage.calculateLength returns an int[4] with:
- * int[0] being the number of SMS's required,
- * int[1] the number of code units used,
- * int[2] is the number of code units remaining until the next message.
- * int[3] is the encoding type that should be used for the message.
- */
- int messageCount = params[0];
- int encodingType = params[3];
- ArrayList<String> result = new ArrayList<String>(messageCount);
-
- int start = 0;
- int limit;
-
- if (messageCount > 1) {
- limit = (encodingType == SmsMessage.ENCODING_7BIT) ?
- SmsMessage.MAX_USER_DATA_SEPTETS_WITH_HEADER :
- SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER;
- } else {
- limit = (encodingType == SmsMessage.ENCODING_7BIT) ?
- SmsMessage.MAX_USER_DATA_SEPTETS : SmsMessage.MAX_USER_DATA_BYTES;
- }
-
- try {
- while (start < size) {
- int end = GsmAlphabet.findLimitIndex(text, start, limit, encodingType);
- result.add(text.substring(start, end));
- start = end;
- }
- } catch (EncodeException e) {
- // ignore it.
- }
- return result;
- }
-
- /**
- * 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").
- */
- 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 simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- simISms.sendMultipartText(destinationAddress, scAddress, parts,
- sentIntents, deliveryIntents);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
- } else {
- PendingIntent sentIntent = null;
- PendingIntent deliveryIntent = null;
- if (sentIntents != null && sentIntents.size() > 0) {
- sentIntent = sentIntents.get(0);
- }
- if (deliveryIntents != null && deliveryIntents.size() > 0) {
- deliveryIntent = deliveryIntents.get(0);
- }
- sendTextMessage(destinationAddress, scAddress, parts.get(0),
- sentIntent, deliveryIntent);
- }
- }
-
- /**
- * Send a data based SMS to a specific application port.
- *
- * @param destinationAddress the address to send the message to
- * @param scAddress is the service center address or null to use
- * the current default SMSC
- * @param destinationPort the port to deliver the message to
- * @param data the body of the message to send
- * @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is sucessfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applicaitons,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- *
- * @throws IllegalArgumentException if destinationAddress or data are empty
- */
- public void sendDataMessage(
- String destinationAddress, String scAddress, short destinationPort,
- byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
- if (TextUtils.isEmpty(destinationAddress)) {
- throw new IllegalArgumentException("Invalid destinationAddress");
- }
-
- if (data == null || data.length == 0) {
- throw new IllegalArgumentException("Invalid message data");
- }
-
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
- destinationPort, data, (deliveryIntent != null));
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
- }
-
- /**
- * Send a raw SMS PDU.
- *
- * @param smsc the SMSC to send the message through, or NULL for the
- * default SMSC
- * @param pdu the raw PDU to send
- * @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is sucessfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applicaitons,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- *
- */
- private void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- simISms.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
- }
-
- /**
- * Get the default instance of the SmsManager
- *
- * @return the default instance of the SmsManager
- */
- public static SmsManager getDefault() {
- if (sInstance == null) {
- sInstance = new SmsManager();
- }
- return sInstance;
- }
-
- private SmsManager() {
- // nothing to see here
- }
-
- /**
- * 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
- *
- * {@hide}
- */
- public boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) {
- boolean success = false;
-
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- success = simISms.copyMessageToSimEf(status, pdu, smsc);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
- }
-
- /**
- * Delete the specified message from the SIM.
- *
- * @param messageIndex is the record index of the message on SIM
- * @return true for success
- *
- * {@hide}
- */
- public boolean
- deleteMessageFromSim(int messageIndex) {
- boolean success = false;
- byte[] pdu = new byte[SimConstants.SMS_RECORD_LENGTH-1];
- Arrays.fill(pdu, (byte)0xff);
-
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- success = simISms.updateMessageOnSimEf(messageIndex,
- STATUS_ON_SIM_FREE, pdu);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
- }
-
- /**
- * 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
- *
- * {@hide}
- */
- public boolean updateMessageOnSim(int messageIndex, int newStatus,
- byte[] pdu) {
- boolean success = false;
-
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- success = simISms.updateMessageOnSimEf(messageIndex, newStatus, pdu);
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return success;
- }
-
-
- /**
- * Retrieves all messages currently stored on SIM.
- *
- * @return <code>ArrayList</code> of <code>SmsMessage</code> objects
- *
- * {@hide}
- */
- public ArrayList<SmsMessage> getAllMessagesFromSim() {
- List<SmsRawData> records = null;
-
- try {
- ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
- if (simISms != null) {
- records = simISms.getAllMessagesFromSimEf();
- }
- } catch (RemoteException ex) {
- // ignore it
- }
-
- return createMessageListFromRawRecords(records);
- }
-
- /**
- * Create a list of <code>SmsMessage</code>s from a list of RawSmsData
- * records returned by <code>getAllMessagesFromSim()</code>
- *
- * @param records SMS EF records, returned by
- * <code>getAllMessagesFromSim</code>
- * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
- */
- private ArrayList<SmsMessage> createMessageListFromRawRecords(List records) {
- ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
- if (records != null) {
- int count = records.size();
- for (int i = 0; i < count; i++) {
- SmsRawData data = (SmsRawData)records.get(i);
- // List contains all records, including "free" records (null)
- if (data != null) {
- SmsMessage sms =
- SmsMessage.createFromEfRecord(i+1, data.getBytes());
- messages.add(sms);
- }
- }
- }
- return messages;
- }
-
- /** Free space (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_FREE = 0;
-
- /** Received and read (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_READ = 1;
-
- /** Received and unread (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_UNREAD = 3;
-
- /** Stored and sent (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_SENT = 5;
-
- /** Stored and unsent (TS 51.011 10.5.3). */
- static public final int STATUS_ON_SIM_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;
-}
diff --git a/telephony/java/android/telephony/gsm/SmsMessage.java b/telephony/java/android/telephony/gsm/SmsMessage.java
deleted file mode 100644
index f79b0a0..0000000
--- a/telephony/java/android/telephony/gsm/SmsMessage.java
+++ /dev/null
@@ -1,1598 +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.telephony.gsm;
-
-import android.telephony.PhoneNumberUtils;
-import android.util.Config;
-import android.util.Log;
-import android.telephony.PhoneNumberUtils;
-import android.text.format.Time;
-
-import com.android.internal.telephony.gsm.EncodeException;
-import com.android.internal.telephony.gsm.GsmAlphabet;
-import com.android.internal.telephony.gsm.SimUtils;
-import com.android.internal.telephony.gsm.SmsHeader;
-
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-
-class SmsAddress {
- // From TS 23.040 9.1.2.5 and TS 24.008 table 10.5.118
- static final int TON_UNKNOWN = 0;
-
- static final int TON_INTERNATIONAL = 1;
-
- static final int TON_NATIONAL = 2;
-
- static final int TON_NETWORK = 3;
-
- static final int TON_SUBSCRIBER = 4;
-
- static final int TON_ALPHANUMERIC = 5;
-
- static final int TON_APPREVIATED = 6;
-
- static final int OFFSET_ADDRESS_LENGTH = 0;
-
- static final int OFFSET_TOA = 1;
-
- static final int OFFSET_ADDRESS_VALUE = 2;
-
- int ton;
-
- String address;
-
- byte[] origBytes;
-
- /**
- * New SmsAddress 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"
- */
-
- SmsAddress(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 addres
- */
- 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 indicationg 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;
-
- }
-
- 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;
- }
-
-}
-
-/**
- * A Short Message Service message.
- *
- */
-public class SmsMessage {
- static final String LOG_TAG = "GSM";
-
- /**
- * SMS Class enumeration.
- * See TS 23.038.
- *
- */
- public enum MessageClass {
- UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
- }
-
- /** Unknown encoding scheme (see TS 23.038) */
- public static final int ENCODING_UNKNOWN = 0;
- /** 7-bit encoding scheme (see TS 23.038) */
- public static final int ENCODING_7BIT = 1;
- /** 8-bit encoding scheme (see TS 23.038) */
- public static final int ENCODING_8BIT = 2;
- /** 16-bit encoding scheme (see TS 23.038) */
- public static final int ENCODING_16BIT = 3;
-
- /** The maximum number of payload bytes per message */
- public static final int MAX_USER_DATA_BYTES = 140;
-
- /**
- * The maximum number of payload bytes per message if a user data header
- * is present. This assumes the header only contains the
- * CONCATENATED_8_BIT_REFERENCE element.
- *
- * @hide pending API Council approval to extend the public API
- */
- 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;
-
- /** The address of the SMSC. May be null */
- String scAddress;
-
- /** The address of the sender */
- SmsAddress originatingAddress;
-
- /** The message body as a string. May be null if the message isn't text */
- String messageBody;
-
- String pseudoSubject;
-
- /** Non-null this is an email gateway message */
- String emailFrom;
-
- /** Non-null if this is an email gateway message */
- String emailBody;
-
- boolean isEmail;
-
- long scTimeMillis;
-
- /** The raw PDU of the message */
- byte[] mPdu;
-
- /** The raw bytes for the user data section of the message */
- byte[] userData;
-
- SmsHeader userDataHeader;
-
- /**
- * TP-Message-Type-Indicator
- * 9.2.3
- */
- int mti;
-
- /** TP-Protocol-Identifier (TP-PID) */
- int protocolIdentifier;
-
- // TP-Data-Coding-Scheme
- // see TS 23.038
- int dataCodingScheme;
-
- // TP-Reply-Path
- // e.g. 23.040 9.2.2.1
- boolean replyPathPresent = false;
-
- // "Message Marked for Automatic Deletion Group"
- // 23.038 Section 4
- boolean automaticDeletion;
-
- // "Message Waiting Indication Group"
- // 23.038 Section 4
- private boolean isMwi;
-
- private boolean mwiSense;
-
- private boolean mwiDontStore;
-
- MessageClass messageClass;
-
- /**
- * Indicates status for messages stored on the SIM.
- */
- int statusOnSim = -1;
-
- /**
- * Record index of message in the EF.
- */
- int indexOnSim = -1;
-
- /** TP-Message-Reference - Message Reference of sent message. @hide */
- public int messageRef;
-
- /** True if Status Report is for SMS-SUBMIT; false for SMS-COMMAND. */
- boolean forSubmit;
-
- /** The address of the receiver. */
- SmsAddress recipientAddress;
-
- /** Time when SMS-SUBMIT was delivered from SC to MSE. */
- 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.
- */
- int status;
-
- /**
- * TP-Status - status of a previously submitted SMS.
- * This field is true iff the message is a SMS-STATUS-REPORT message.
- */
- boolean isStatusReportMessage = false;
-
- /**
- * This class represents the encoded form of an outgoing SMS.
- */
- 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);
- }
- }
-
- /**
- * 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;
- }
- }
-
- /**
- * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
- * +CMT unsolicited response (PDU mode, of course)
- * +CMT: [&lt;alpha>],<length><CR><LF><pdu>
- *
- * Only public for debugging
- *
- * {@hide}
- */
- /* package */ public static SmsMessage newFromCMT(String[] lines) {
- try {
- SmsMessage msg = new SmsMessage();
- msg.parsePdu(SimUtils.hexStringToBytes(lines[1]));
- return msg;
- } catch (RuntimeException ex) {
- Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
- return null;
- }
- }
-
- /* pacakge */ static SmsMessage newFromCMTI(String line) {
- // the thinking here is not to read the message immediately
- // FTA test case
- Log.e(LOG_TAG, "newFromCMTI: not yet supported");
- return null;
- }
-
- /** @hide */
- /* package */ public static SmsMessage newFromCDS(String line) {
- try {
- SmsMessage msg = new SmsMessage();
- msg.parsePdu(SimUtils.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.indexOnSim = 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.statusOnSim = 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 = 0;
-
- smscLen = Integer.parseInt(pdu.substring(0, 2), 16);
-
- return len - smscLen - 1;
- }
-
- /**
- * Calculates the number of SMS's required to encode the message body and
- * the number of characters remaining until the next message, given the
- * current encoding.
- *
- * @param messageBody the message to encode
- * @param use7bitOnly if true, characters that are not part of the GSM
- * alphabet are counted as a single space char. If false, a
- * messageBody containing non-GSM alphabet characters is calculated
- * for 16-bit encoding.
- * @return an int[4] with int[0] being the number of SMS's required, int[1]
- * the number of code units used, and int[2] is the number of code
- * units remaining until the next message. int[3] is the encoding
- * type that should be used for the message.
- */
- public static int[] calculateLength(String messageBody, boolean use7bitOnly) {
- int ret[] = new int[4];
-
- try {
- // Try GSM alphabet
- int septets = GsmAlphabet.countGsmSeptets(messageBody, !use7bitOnly);
- ret[1] = septets;
- if (septets > MAX_USER_DATA_SEPTETS) {
- ret[0] = (septets / MAX_USER_DATA_SEPTETS_WITH_HEADER) + 1;
- ret[2] = MAX_USER_DATA_SEPTETS_WITH_HEADER
- - (septets % MAX_USER_DATA_SEPTETS_WITH_HEADER);
- } else {
- ret[0] = 1;
- ret[2] = MAX_USER_DATA_SEPTETS - septets;
- }
- ret[3] = ENCODING_7BIT;
- } catch (EncodeException ex) {
- // fall back to UCS-2
- int octets = messageBody.length() * 2;
- ret[1] = messageBody.length();
- if (octets > MAX_USER_DATA_BYTES) {
- // 6 is the size of the user data header
- ret[0] = (octets / MAX_USER_DATA_BYTES_WITH_HEADER) + 1;
- ret[2] = (MAX_USER_DATA_BYTES_WITH_HEADER
- - (octets % MAX_USER_DATA_BYTES_WITH_HEADER))/2;
- } else {
- ret[0] = 1;
- ret[2] = (MAX_USER_DATA_BYTES - octets)/2;
- }
- ret[3] = ENCODING_16BIT;
- }
-
- return ret;
- }
-
-
- /**
- * 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) {
-
- // Perform null parameter checks.
- if (message == null || destinationAddress == null) {
- return null;
- }
-
- 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);
-
- try {
- // First, try encoding it with the GSM alphabet
-
- // User Data (and length)
- byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header);
-
- if ((0xff & userData[0]) > MAX_USER_DATA_SEPTETS) {
- // Message too long
- return null;
- }
-
- // TP-Data-Coding-Scheme
- // Default encoding, uncompressed
- bo.write(0x00);
-
- // (no TP-Validity-Period)
-
- bo.write(userData, 0, userData.length);
- } catch (EncodeException ex) {
- byte[] userData, textPart;
- // Encoding to the 7-bit alphabet failed. Let's see if we can
- // send it as a UCS-2 encoded message
-
- try {
- textPart = message.getBytes("utf-16be");
- } catch (UnsupportedEncodingException uex) {
- Log.e(LOG_TAG,
- "Implausible UnsupportedEncodingException ",
- uex);
- return null;
- }
-
- if (header != null) {
- userData = new byte[header.length + textPart.length];
-
- System.arraycopy(header, 0, userData, 0, header.length);
- System.arraycopy(textPart, 0, userData, header.length, textPart.length);
- } else {
- userData = textPart;
- }
-
- if (userData.length > MAX_USER_DATA_BYTES) {
- // Message too long
- return null;
- }
-
- // TP-Data-Coding-Scheme
- // Class 3, UCS-2 encoding, uncompressed
- bo.write(0x0b);
-
- // (no TP-Validity-Period)
-
- // TP-UDL
- bo.write(userData.length);
-
- bo.write(userData, 0, userData.length);
- }
-
- ret.encodedMessage = bo.toByteArray();
- 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 &amp; port
- *
- * @param scAddress Service Centre address. null == use default
- * @param destinationAddress the address of the destination for the message
- * @param destinationPort the port to deliver the message to at the
- * destination
- * @param data the dat for the message
- * @return a <code>SubmitPdu</code> containing the encoded SC
- * address, if applicable, and the encoded message.
- * Returns null on encode error.
- */
- public static SubmitPdu getSubmitPdu(String scAddress,
- String destinationAddress, short destinationPort, byte[] data,
- boolean statusReportRequested) {
- if (data.length > (MAX_USER_DATA_BYTES - 7 /* UDH size */)) {
- Log.e(LOG_TAG, "SMS data message may only contain "
- + (MAX_USER_DATA_BYTES - 7) + " 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)
-
- // User data size
- bo.write(data.length + 7);
-
- // User data header size
- bo.write(0x06); // header is 6 octets
-
- // User data header, indicating the destination port
- bo.write(SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT); // port
- // addressing
- // header
- bo.write(0x04); // each port is 2 octets
- bo.write((destinationPort >> 8) & 0xFF); // MSB of destination port
- bo.write(destinationPort & 0xFF); // LSB of destination port
- bo.write(0x00); // MSB of originating port
- bo.write(0x00); // LSB of originating port
-
- // 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 (Config.LOGD) 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;
- }
-
- static class PduParser {
- byte pdu[];
-
- int cur;
-
- SmsHeader userDataHeader;
-
- byte[] userData;
-
- int mUserDataSeptetPadding;
-
- int mUserDataSize;
-
- PduParser(String s) {
- this(SimUtils.hexStringToBytes(s));
- }
-
- 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
- */
- SmsAddress getAddress() {
- SmsAddress 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 SmsAddress(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 = SimUtils.bcdByteToInt(pdu[cur++]);
- int month = SimUtils.bcdByteToInt(pdu[cur++]);
- int day = SimUtils.bcdByteToInt(pdu[cur++]);
- int hour = SimUtils.bcdByteToInt(pdu[cur++]);
- int minute = SimUtils.bcdByteToInt(pdu[cur++]);
- int second = SimUtils.bcdByteToInt(pdu[cur++]);
-
- // For the timezone, the most significant bit of the
- // least signficant 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 = SimUtils
- .bcdByteToInt((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;
-
- if (hasUserDataHeader) {
- int userDataHeaderLength = pdu[offset++] & 0xff;
-
- byte[] udh = new byte[userDataHeaderLength];
- System.arraycopy(pdu, offset, udh, 0, userDataHeaderLength);
- userDataHeader = SmsHeader.parse(udh);
- offset += userDataHeaderLength;
-
- int headerBits = (userDataHeaderLength + 1) * 8;
- headerSeptets = headerBits / 7;
- headerSeptets += (headerBits % 7) > 0 ? 1 : 0;
- mUserDataSeptetPadding = (headerSeptets * 7) - headerBits;
- }
-
- /*
- * Here we just create the user data length to be the remainder of
- * the pdu minus the user data hearder. This is because the count
- * could mean the number of uncompressed sepets if the userdata is
- * encoded in 7-bit.
- */
- userData = new byte[pdu.length - offset];
- 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 begining of the user data
- * array before the start of the septets.
- *
- * @return the number of padding bits at the begining of the user data
- * array before the start of the septets
- */
- int getUserDataSeptetPadding() {
- return mUserDataSeptetPadding;
- }
-
- /**
- * Returns an object representing the user data headers
- *
- * @return an object representing the user data headers
- *
- * {@hide}
- */
- SmsHeader getUserDataHeader() {
- return userDataHeader;
- }
-
-/*
- XXX Not sure what this one is supposed to be doing, and no one is using
- it.
- String getUserDataGSM8bit() {
- // System.out.println("remainder of pud:" +
- // HexDump.dumpHexString(pdu, cur, pdu.length - cur));
- int count = pdu[cur++] & 0xff;
- int size = pdu[cur++];
-
- // skip over header for now
- cur += size;
-
- if (pdu[cur - 1] == 0x01) {
- int tid = pdu[cur++] & 0xff;
- int type = pdu[cur++] & 0xff;
-
- size = pdu[cur++] & 0xff;
-
- int i = cur;
-
- while (pdu[i++] != '\0') {
- }
-
- int length = i - cur;
- String mimeType = new String(pdu, cur, length);
-
- cur += length;
-
- if (false) {
- System.out.println("tid = 0x" + HexDump.toHexString(tid));
- System.out.println("type = 0x" + HexDump.toHexString(type));
- System.out.println("header size = " + size);
- System.out.println("mimeType = " + mimeType);
- System.out.println("remainder of header:" +
- HexDump.dumpHexString(pdu, cur, (size - mimeType.length())));
- }
-
- cur += size - mimeType.length();
-
- // System.out.println("data count = " + count + " cur = " + cur
- // + " :" + HexDump.dumpHexString(pdu, cur, pdu.length - cur));
-
- MMSMessage msg = MMSMessage.parseEncoding(mContext, pdu, cur,
- pdu.length - cur);
- } else {
- System.out.println(new String(pdu, cur, pdu.length - cur - 1));
- }
-
- return SimUtils.bytesToHexString(pdu);
- }
-*/
-
- /**
- * Interprets the user data payload as pack 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) {
- String ret;
-
- ret = GsmAlphabet.gsm7BitPackedToString(pdu, cur, septetCount,
- mUserDataSeptetPadding);
-
- 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;
- }
-
- boolean moreDataPresent() {
- return (pdu.length > cur);
- }
- }
-
- /**
- * 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 MessageClass getMessageClass() {
- return messageClass;
- }
-
- /**
- * 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 int getProtocolIdentifier() {
- return protocolIdentifier;
- }
-
- /**
- * See TS 23.040 9.2.3.9 returns true if this is a "replace short message"
- * SMS
- */
- public boolean isReplace() {
- return (protocolIdentifier & 0xc0) == 0x40
- && (protocolIdentifier & 0x3f) > 0
- && (protocolIdentifier & 0x3f) < 8;
- }
-
- /**
- * 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 originatingAddress.isCphsVoiceMessageClear()
- || originatingAddress.isCphsVoiceMessageSet();
- }
-
- /**
- * returns true if this message is a CPHS voicemail / message waiting
- * indicator (MWI) clear message
- */
- public boolean isMWIClearMessage() {
- if (isMwi && (mwiSense == false)) {
- return true;
- }
-
- return originatingAddress != null
- && originatingAddress.isCphsVoiceMessageClear();
- }
-
- /**
- * returns true if this message is a CPHS voicemail / message waiting
- * indicator (MWI) set message
- */
- public boolean isMWISetMessage() {
- if (isMwi && (mwiSense == true)) {
- return true;
- }
-
- return originatingAddress != null
- && originatingAddress.isCphsVoiceMessageSet();
- }
-
- /**
- * returns true if this message is a "Message Waiting Indication Group:
- * Discard Message" notification and should not be stored.
- */
- 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;
- }
-
- /**
- * 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
- *
- * @return an object representing the user data header
- *
- * {@hide}
- */
- public SmsHeader getUserDataHeader() {
- return userDataHeader;
- }
-
- /**
- * Returns the raw PDU for the message.
- *
- * @return the raw PDU for the message.
- */
- public byte[] getPdu() {
- return mPdu;
- }
-
- /**
- * 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
- */
- public int getStatusOnSim() {
- return statusOnSim;
- }
-
- /**
- * 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.
- */
- public int getIndexOnSim() {
- return indexOnSim;
- }
-
- /**
- * For an SMS-STATUS-REPORT message, this returns the status field from
- * the status report. This field indicates the status of a previousely
- * 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 int getStatus() {
- return status;
- }
-
- /**
- * Return true iff the message is a SMS-STATUS-REPORT message.
- */
- public boolean isStatusReportMessage() {
- return isStatusReportMessage;
- }
-
- /**
- * Returns true iff the <code>TP-Reply-Path</code> bit is set in
- * this message.
- */
- 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
- * hexad 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 mesage:");
- // Log.d(LOG_TAG, s);
-
- PduParser p = new PduParser(pdu);
-
- scAddress = p.getSCAddress();
-
- if (scAddress != null) {
- if (Config.LOGD) 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:
- 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 (Config.LOGV) 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 (Config.LOGV) {
- Log.v(LOG_TAG, "SMS TP-PID:" + protocolIdentifier
- + " data coding scheme: " + dataCodingScheme);
- }
-
- scTimeMillis = p.getSCTimestampMillis();
-
- if (Config.LOGD) 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 {
- 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);
- break;
-
- case ENCODING_16BIT:
- messageBody = p.getUserDataUCS2(count);
- break;
- }
-
- if (Config.LOGV) 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;
- }
- }
- }
-
- private void parseMessageBody() {
- if (originatingAddress.couldBeEmailGateway()) {
- extractEmailAddressFromMessageBody();
- }
- }
-
- /**
- * Try to parse this message as an email gateway message -> Neither
- * of the standard ways are currently supported: There are two ways
- * specified in TS 23.040 Section 3.8 (not supported via this mechanism) -
- * 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." - multiple addreses
- * separated by commas, no spaces - subject field delimited by '()' or '##'
- * and '#' Section 9.2.3.24.11
- */
- private void extractEmailAddressFromMessageBody() {
-
- /*
- * a little guesswork here. I haven't found doc for this.
- * the format could be either
- *
- * 1. [x@y][ ]/[subject][ ]/[body]
- * -or-
- * 2. [x@y][ ]/[body]
- */
- int slash = 0, slash2 = 0, atSymbol = 0;
-
- try {
- slash = messageBody.indexOf(" /");
- if (slash == -1) {
- return;
- }
-
- atSymbol = messageBody.indexOf('@');
- if (atSymbol == -1 || atSymbol > slash) {
- return;
- }
-
- emailFrom = messageBody.substring(0, slash);
-
- slash2 = messageBody.indexOf(" /", slash + 2);
-
- if (slash2 == -1) {
- pseudoSubject = null;
- emailBody = messageBody.substring(slash + 2);
- } else {
- pseudoSubject = messageBody.substring(slash + 2, slash2);
- emailBody = messageBody.substring(slash2 + 2);
- }
-
- isEmail = true;
- } catch (Exception ex) {
- Log.w(LOG_TAG,
- "extractEmailAddressFromMessageBody: exception slash="
- + slash + ", atSymbol=" + atSymbol + ", slash2="
- + slash2, ex);
- }
- }
-
-}
diff --git a/telephony/java/android/telephony/gsm/package.html b/telephony/java/android/telephony/gsm/package.html
deleted file mode 100644
index 9860417..0000000
--- a/telephony/java/android/telephony/gsm/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Provides APIs for utilizing GSM-specific telephony features, such as
-text/data/PDU SMS messages.
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/telephony/java/android/telephony/package.html b/telephony/java/android/telephony/package.html
deleted file mode 100644
index aee4a6f..0000000
--- a/telephony/java/android/telephony/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<HTML>
-<BODY>
-Provides APIs for monitoring the basic phone information, such as
-the network type and connection state, plus utilities
-for manipulating phone number strings.
-</BODY>
-</HTML> \ No newline at end of file