diff options
58 files changed, 944 insertions, 128 deletions
diff --git a/Android.mk b/Android.mk index e5980b415b1a..9ee4e187a84b 100644 --- a/Android.mk +++ b/Android.mk @@ -293,7 +293,7 @@ fwbase_dirs_to_document := \ # as "final" in the official SDK APIs. fwbase_dirs_to_document += core/config/sdk -# These are relative to dalvik/libcore +# These are relative to libcore # Intentionally not included from libcore: # icu openssl suncompat support libcore_to_document := \ @@ -333,7 +333,7 @@ non_base_dirs := \ dirs_to_document := \ $(fwbase_dirs_to_document) \ $(non_base_dirs) \ - $(addprefix ../../dalvik/libcore/, $(libcore_to_document)) + $(addprefix ../../libcore/, $(libcore_to_document)) html_dirs := \ $(FRAMEWORKS_BASE_SUBDIRS) \ diff --git a/api/current.xml b/api/current.xml index 9d259f3a3090..e27fb5c3ae16 100644 --- a/api/current.xml +++ b/api/current.xml @@ -142238,6 +142238,17 @@ visibility="public" > </field> +<field name="NETWORK_TYPE_EVDO_B" + type="int" + transient="false" + volatile="false" + value="12" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="NETWORK_TYPE_GPRS" type="int" transient="false" @@ -169637,6 +169648,28 @@ visibility="public" > </field> +<field name="KEYCODE_PAGE_DOWN" + type="int" + transient="false" + volatile="false" + value="93" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="KEYCODE_PAGE_UP" + type="int" + transient="false" + volatile="false" + value="92" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="KEYCODE_PERIOD" type="int" transient="false" @@ -169648,6 +169681,17 @@ visibility="public" > </field> +<field name="KEYCODE_PICTSYMBOLS" + type="int" + transient="false" + volatile="false" + value="94" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="KEYCODE_PLUS" type="int" transient="false" @@ -169824,6 +169868,17 @@ visibility="public" > </field> +<field name="KEYCODE_SWITCH_CHARSET" + type="int" + transient="false" + volatile="false" + value="95" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="KEYCODE_SYM" type="int" transient="false" diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index 80e9865e5a81..44f30f7c5dac 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -47,9 +47,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub private static final int DO_UPDATE_CURSOR = 95; private static final int DO_APP_PRIVATE_COMMAND = 100; private static final int DO_TOGGLE_SOFT_INPUT = 105; - - final HandlerCaller mCaller; - final InputMethodSession mInputMethodSession; + private static final int DO_FINISH_SESSION = 110; + + HandlerCaller mCaller; + InputMethodSession mInputMethodSession; // NOTE: we should have a cache of these. static class InputMethodEventCallbackWrapper implements InputMethodSession.EventCallback { @@ -127,6 +128,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub mInputMethodSession.toggleSoftInput(msg.arg1, msg.arg2); return; } + case DO_FINISH_SESSION: { + mInputMethodSession = null; + return; + } } Log.w(TAG, "Unhandled message code: " + msg.what); } @@ -174,4 +179,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub public void toggleSoftInput(int showFlags, int hideFlags) { mCaller.executeOrSendMessage(mCaller.obtainMessageII(DO_TOGGLE_SOFT_INPUT, showFlags, hideFlags)); } + + public void finishSession() { + mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_SESSION)); + } } diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java index bfa82ee0d13c..35fd46f5a2f2 100644 --- a/core/java/android/inputmethodservice/IInputMethodWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java @@ -39,6 +39,7 @@ import android.view.inputmethod.InputMethodSession; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -64,9 +65,9 @@ class IInputMethodWrapper extends IInputMethod.Stub private static final int DO_SHOW_SOFT_INPUT = 60; private static final int DO_HIDE_SOFT_INPUT = 70; - final AbstractInputMethodService mTarget; + final WeakReference<AbstractInputMethodService> mTarget; final HandlerCaller mCaller; - final InputMethod mInputMethod; + final WeakReference<InputMethod> mInputMethod; static class Notifier { boolean notified; @@ -96,21 +97,32 @@ class IInputMethodWrapper extends IInputMethod.Stub public IInputMethodWrapper(AbstractInputMethodService context, InputMethod inputMethod) { - mTarget = context; - mCaller = new HandlerCaller(context, this); - mInputMethod = inputMethod; + mTarget = new WeakReference<AbstractInputMethodService>(context); + mCaller = new HandlerCaller(context.getApplicationContext(), this); + mInputMethod = new WeakReference<InputMethod>(inputMethod); } public InputMethod getInternalInputMethod() { - return mInputMethod; + return mInputMethod.get(); } public void executeMessage(Message msg) { + InputMethod inputMethod = mInputMethod.get(); + // Need a valid reference to the inputMethod for everything except a dump. + if (inputMethod == null && msg.what != DO_DUMP) { + Log.w(TAG, "Input method reference was null, ignoring message: " + msg.what); + return; + } + switch (msg.what) { case DO_DUMP: { + AbstractInputMethodService target = mTarget.get(); + if (target == null) { + return; + } HandlerCaller.SomeArgs args = (HandlerCaller.SomeArgs)msg.obj; try { - mTarget.dump((FileDescriptor)args.arg1, + target.dump((FileDescriptor)args.arg1, (PrintWriter)args.arg2, (String[])args.arg3); } catch (RuntimeException e) { ((PrintWriter)args.arg2).println("Exception: " + e); @@ -122,22 +134,22 @@ class IInputMethodWrapper extends IInputMethod.Stub } case DO_ATTACH_TOKEN: { - mInputMethod.attachToken((IBinder)msg.obj); + inputMethod.attachToken((IBinder)msg.obj); return; } case DO_SET_INPUT_CONTEXT: { - mInputMethod.bindInput((InputBinding)msg.obj); + inputMethod.bindInput((InputBinding)msg.obj); return; } case DO_UNSET_INPUT_CONTEXT: - mInputMethod.unbindInput(); + inputMethod.unbindInput(); return; case DO_START_INPUT: { HandlerCaller.SomeArgs args = (HandlerCaller.SomeArgs)msg.obj; IInputContext inputContext = (IInputContext)args.arg1; InputConnection ic = inputContext != null ? new InputConnectionWrapper(inputContext) : null; - mInputMethod.startInput(ic, (EditorInfo)args.arg2); + inputMethod.startInput(ic, (EditorInfo)args.arg2); return; } case DO_RESTART_INPUT: { @@ -145,33 +157,37 @@ class IInputMethodWrapper extends IInputMethod.Stub IInputContext inputContext = (IInputContext)args.arg1; InputConnection ic = inputContext != null ? new InputConnectionWrapper(inputContext) : null; - mInputMethod.restartInput(ic, (EditorInfo)args.arg2); + inputMethod.restartInput(ic, (EditorInfo)args.arg2); return; } case DO_CREATE_SESSION: { - mInputMethod.createSession(new InputMethodSessionCallbackWrapper( + inputMethod.createSession(new InputMethodSessionCallbackWrapper( mCaller.mContext, (IInputMethodCallback)msg.obj)); return; } case DO_SET_SESSION_ENABLED: - mInputMethod.setSessionEnabled((InputMethodSession)msg.obj, + inputMethod.setSessionEnabled((InputMethodSession)msg.obj, msg.arg1 != 0); return; case DO_REVOKE_SESSION: - mInputMethod.revokeSession((InputMethodSession)msg.obj); + inputMethod.revokeSession((InputMethodSession)msg.obj); return; case DO_SHOW_SOFT_INPUT: - mInputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj); + inputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj); return; case DO_HIDE_SOFT_INPUT: - mInputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj); + inputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj); return; } Log.w(TAG, "Unhandled message code: " + msg.what); } @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { - if (mTarget.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + AbstractInputMethodService target = mTarget.get(); + if (target == null) { + return; + } + if (target.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { fout.println("Permission Denial: can't dump InputMethodManager from from pid=" diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 8c8d3e59b8b4..1a261d3fa6ba 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1988,15 +1988,19 @@ public class InputMethodService extends AbstractInputMethodService { ei.inputType != InputType.TYPE_NULL); if (hasAction) { mExtractAccessories.setVisibility(View.VISIBLE); - if (ei.actionLabel != null) { - mExtractAction.setText(ei.actionLabel); - } else { - mExtractAction.setText(getTextForImeAction(ei.imeOptions)); + if (mExtractAction != null) { + if (ei.actionLabel != null) { + mExtractAction.setText(ei.actionLabel); + } else { + mExtractAction.setText(getTextForImeAction(ei.imeOptions)); + } + mExtractAction.setOnClickListener(mActionClickListener); } - mExtractAction.setOnClickListener(mActionClickListener); } else { mExtractAccessories.setVisibility(View.GONE); - mExtractAction.setOnClickListener(null); + if (mExtractAction != null) { + mExtractAction.setOnClickListener(null); + } } } diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 98f32b36e99e..214510d885d5 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -310,6 +310,9 @@ public class MobileDataStateTracker extends NetworkStateTracker { case TelephonyManager.NETWORK_TYPE_EVDO_A: networkTypeStr = "evdo"; break; + case TelephonyManager.NETWORK_TYPE_EVDO_B: + networkTypeStr = "evdo"; + break; } return "net.tcp.buffersize." + networkTypeStr; } diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index d4f978756f4d..9aa16b53216d 100644..100755 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -120,6 +120,10 @@ public class KeyEvent implements Parcelable { public static final int KEYCODE_MEDIA_REWIND = 89; public static final int KEYCODE_MEDIA_FAST_FORWARD = 90; public static final int KEYCODE_MUTE = 91; + public static final int KEYCODE_PAGE_UP = 92; + public static final int KEYCODE_PAGE_DOWN = 93; + public static final int KEYCODE_PICTSYMBOLS = 94; // switch symbol-sets (Emoji,Kao-moji) + public static final int KEYCODE_SWITCH_CHARSET = 95; // switch char-sets (Kanji,Katakana) // NOTE: If you add a new keycode here you must also add it to: // isSystem() @@ -135,7 +139,7 @@ public class KeyEvent implements Parcelable { // those new codes. This is intended to maintain a consistent // set of key code definitions across all Android devices. - private static final int LAST_KEYCODE = KEYCODE_MUTE; + private static final int LAST_KEYCODE = KEYCODE_SWITCH_CHARSET; /** * @deprecated There are now more than MAX_KEYCODE keycodes. @@ -692,6 +696,8 @@ public class KeyEvent implements Parcelable { case KEYCODE_CAMERA: case KEYCODE_FOCUS: case KEYCODE_SEARCH: + case KEYCODE_PICTSYMBOLS: + case KEYCODE_SWITCH_CHARSET: return true; default: return false; diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java index 034c88ae0731..ca9ad53c52a5 100644 --- a/core/java/android/webkit/MimeTypeMap.java +++ b/core/java/android/webkit/MimeTypeMap.java @@ -67,7 +67,7 @@ public class MimeTypeMap { // if the filename contains special characters, we don't // consider it valid for our matching purposes: if (filename.length() > 0 && - Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)]+", filename)) { + Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)\\%]+", filename)) { int dotPos = filename.lastIndexOf('.'); if (0 <= dotPos) { return filename.substring(dotPos + 1); diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index b3d5f1af58a7..1fc23abe1eb2 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -328,6 +328,7 @@ public class DatePicker extends FrameLayout { mYear = ss.getYear(); mMonth = ss.getMonth(); mDay = ss.getDay(); + updateSpinners(); } /** diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl index a05ff14bcccd..338dcaa7db96 100644 --- a/core/java/com/android/internal/view/IInputMethodSession.aidl +++ b/core/java/com/android/internal/view/IInputMethodSession.aidl @@ -48,4 +48,6 @@ oneway interface IInputMethodSession { void appPrivateCommand(String action, in Bundle data); void toggleSoftInput(int showFlags, int hideFlags); + + void finishSession(); } diff --git a/core/java/com/google/android/mms/ContentType.java b/core/java/com/google/android/mms/ContentType.java index 94bc9fdcd4bf..b066fadae2f1 100644 --- a/core/java/com/google/android/mms/ContentType.java +++ b/core/java/com/google/android/mms/ContentType.java @@ -26,6 +26,7 @@ public class ContentType { public static final String MMS_GENERIC = "application/vnd.wap.mms-generic"; public static final String MULTIPART_MIXED = "application/vnd.wap.multipart.mixed"; public static final String MULTIPART_RELATED = "application/vnd.wap.multipart.related"; + public static final String MULTIPART_ALTERNATIVE = "application/vnd.wap.multipart.alternative"; public static final String TEXT_PLAIN = "text/plain"; public static final String TEXT_HTML = "text/html"; diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java index d465c5aafb3b..1cd118b56ac6 100644 --- a/core/java/com/google/android/mms/pdu/PduParser.java +++ b/core/java/com/google/android/mms/pdu/PduParser.java @@ -200,7 +200,18 @@ public class PduParser { PduHeaders headers = new PduHeaders(); while (keepParsing && (pduDataStream.available() > 0)) { + pduDataStream.mark(1); int headerField = extractByteValue(pduDataStream); + /* parse custom text header */ + if ((headerField >= TEXT_MIN) && (headerField <= TEXT_MAX)) { + pduDataStream.reset(); + byte [] bVal = parseWapString(pduDataStream, TYPE_TEXT_STRING); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "TextHeader: " + new String(bVal)); + } + /* we should ignore it at the moment */ + continue; + } switch (headerField) { case PduHeaders.MESSAGE_TYPE: { @@ -778,26 +789,34 @@ public class PduParser { /* get part's data */ if (dataLength > 0) { byte[] partData = new byte[dataLength]; + String partContentType = new String(part.getContentType()); pduDataStream.read(partData, 0, dataLength); - // Check Content-Transfer-Encoding. - byte[] partDataEncoding = part.getContentTransferEncoding(); - if (null != partDataEncoding) { - String encoding = new String(partDataEncoding); - if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { - // Decode "base64" into "binary". - partData = Base64.decodeBase64(partData); - } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { - // Decode "quoted-printable" into "binary". - partData = QuotedPrintable.decodeQuotedPrintable(partData); - } else { - // "binary" is the default encoding. + if (partContentType.equalsIgnoreCase(ContentType.MULTIPART_ALTERNATIVE)) { + // parse "multipart/vnd.wap.multipart.alternative". + PduBody childBody = parseParts(new ByteArrayInputStream(partData)); + // take the first part of children. + part = childBody.getPart(0); + } else { + // Check Content-Transfer-Encoding. + byte[] partDataEncoding = part.getContentTransferEncoding(); + if (null != partDataEncoding) { + String encoding = new String(partDataEncoding); + if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) { + // Decode "base64" into "binary". + partData = Base64.decodeBase64(partData); + } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) { + // Decode "quoted-printable" into "binary". + partData = QuotedPrintable.decodeQuotedPrintable(partData); + } else { + // "binary" is the default encoding. + } } + if (null == partData) { + log("Decode part data error!"); + return null; + } + part.setData(partData); } - if (null == partData) { - log("Decode part data error!"); - return null; - } - part.setData(partData); } /* add this part to body */ diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 6d6c47f3b3d0..8d4fa4eebcae 100644..100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -916,6 +916,10 @@ <enum name="KEYCODE_MEDIA_REWIND" value="89" /> <enum name="KEYCODE_MEDIA_FAST_FORWARD" value="90" /> <enum name="KEYCODE_MUTE" value="91" /> + <enum name="KEYCODE_PAGE_UP" value="92" /> + <enum name="KEYCODE_PAGE_DOWN" value="93" /> + <enum name="KEYCODE_PICTSYMBOLS" value="94" /> + <enum name="KEYCODE_SWITCH_CHARSET" value="95" /> </attr> <!-- ***************************************************************** --> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 86bfe94cbf8f..1e007d3654c0 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -60,6 +60,10 @@ <!-- Displayed when the user dialed an MMI code whose function could not be performed. This will be displayed in a toast. --> <string name="mmiError">Connection problem or invalid MMI code.</string> + <!-- Displayed when the user dialed an MMI code whose function + could not be performed because FDN is enabled. This will be displayed in a toast. --> + <string name="mmiFdnError">Operation is restricted to fixed dialing numbers only.</string> + <!-- Displayed when a phone feature such as call barring was activated. --> <string name="serviceEnabled">Service was enabled.</string> <!-- Displayed in front of the list of a set of service classes diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java index 5cefaa3b72c6..a50693d2f130 100644 --- a/graphics/java/android/graphics/Color.java +++ b/graphics/java/android/graphics/Color.java @@ -30,7 +30,8 @@ import java.util.Locale; * (green << 8) | blue. Each component ranges between 0..255 with 0 * meaning no contribution for that component, and 255 meaning 100% * contribution. Thus opaque-black would be 0xFF000000 (100% opaque but - * no contributes from red, gree, blue, and opaque-white would be 0xFFFFFFFF + * no contributions from red, green, or blue), and opaque-white would be + * 0xFFFFFFFF */ public class Color { public static final int BLACK = 0xFF000000; diff --git a/include/binder/IInterface.h b/include/binder/IInterface.h index 273d92231fe2..5f9f69c042bf 100644 --- a/include/binder/IInterface.h +++ b/include/binder/IInterface.h @@ -72,21 +72,24 @@ protected: // ---------------------------------------------------------------------- #define DECLARE_META_INTERFACE(INTERFACE) \ - static const String16 descriptor; \ - static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \ - virtual const String16& getInterfaceDescriptor() const; \ + static const android::String16 descriptor; \ + static android::sp<I##INTERFACE> asInterface( \ + const android::sp<android::IBinder>& obj); \ + virtual const android::String16& getInterfaceDescriptor() const; \ I##INTERFACE(); \ virtual ~I##INTERFACE(); \ #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ - const String16 I##INTERFACE::descriptor(NAME); \ - const String16& I##INTERFACE::getInterfaceDescriptor() const { \ + const android::String16 I##INTERFACE::descriptor(NAME); \ + const android::String16& \ + I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ - sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \ + android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ + const android::sp<android::IBinder>& obj) \ { \ - sp<I##INTERFACE> intr; \ + android::sp<I##INTERFACE> intr; \ if (obj != NULL) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h index 571e47b22d86..e81d0f9064dc 100644..100755 --- a/include/ui/KeycodeLabels.h +++ b/include/ui/KeycodeLabels.h @@ -114,6 +114,10 @@ static const KeycodeLabel KEYCODES[] = { { "MEDIA_REWIND", 89 }, { "MEDIA_FAST_FORWARD", 90 }, { "MUTE", 91 }, + { "PAGE_UP", 92 }, + { "PAGE_DOWN", 93 }, + { "PICTSYMBOLS", 94 }, + { "SWITCH_CHARSET", 95 }, // NOTE: If you add a new keycode here you must also add it to: // (enum KeyCode, in this file) @@ -218,7 +222,11 @@ typedef enum KeyCode { kKeyCodePreviousSong = 88, kKeyCodeRewind = 89, kKeyCodeForward = 90, - kKeyCodeMute = 91 + kKeyCodeMute = 91, + kKeyCodePageUp = 92, + kKeyCodePageDown = 93, + kKeyCodePictSymbols = 94, + kKeyCodeSwitchCharset = 95 } KeyCode; static const KeycodeLabel FLAGS[] = { diff --git a/location/java/android/location/Address.java b/location/java/android/location/Address.java index ac275c677c76..b152f48a3e9e 100644 --- a/location/java/android/location/Address.java +++ b/location/java/android/location/Address.java @@ -500,7 +500,10 @@ public class Address implements Parcelable { a.mAdminArea = in.readString(); a.mSubAdminArea = in.readString(); a.mLocality = in.readString(); + a.mSubLocality = in.readString(); a.mThoroughfare = in.readString(); + a.mSubThoroughfare = in.readString(); + a.mPremises = in.readString(); a.mPostalCode = in.readString(); a.mCountryCode = in.readString(); a.mCountryName = in.readString(); @@ -544,7 +547,10 @@ public class Address implements Parcelable { parcel.writeString(mAdminArea); parcel.writeString(mSubAdminArea); parcel.writeString(mLocality); + parcel.writeString(mSubLocality); parcel.writeString(mThoroughfare); + parcel.writeString(mSubThoroughfare); + parcel.writeString(mPremises); parcel.writeString(mPostalCode); parcel.writeString(mCountryCode); parcel.writeString(mCountryName); diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java index 15d692c46263..fa53ccfa0f66 100755 --- a/location/java/com/android/internal/location/GpsLocationProvider.java +++ b/location/java/com/android/internal/location/GpsLocationProvider.java @@ -965,29 +965,6 @@ public class GpsLocationProvider implements LocationProviderInterface { if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + " timestamp: " + timestamp); - mLastFixTime = System.currentTimeMillis(); - // report time to first fix - if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { - mTTFF = (int)(mLastFixTime - mFixRequestTime); - if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF); - - // notify status listeners - synchronized(mListeners) { - int size = mListeners.size(); - for (int i = 0; i < size; i++) { - Listener listener = mListeners.get(i); - try { - listener.mListener.onFirstFix(mTTFF); - } catch (RemoteException e) { - Log.w(TAG, "RemoteException in stopNavigating"); - mListeners.remove(listener); - // adjust for size of list changing - size--; - } - } - } - } - synchronized (mLocation) { mLocationFlags = flags; if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { @@ -1023,6 +1000,29 @@ public class GpsLocationProvider implements LocationProviderInterface { } } + mLastFixTime = System.currentTimeMillis(); + // report time to first fix + if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { + mTTFF = (int)(mLastFixTime - mFixRequestTime); + if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF); + + // notify status listeners + synchronized(mListeners) { + int size = mListeners.size(); + for (int i = 0; i < size; i++) { + Listener listener = mListeners.get(i); + try { + listener.mListener.onFirstFix(mTTFF); + } catch (RemoteException e) { + Log.w(TAG, "RemoteException in stopNavigating"); + mListeners.remove(listener); + // adjust for size of list changing + size--; + } + } + } + } + if (mStarted && mStatus != LocationProvider.AVAILABLE) { // we still want to time out if we do not receive MIN_FIX_COUNT // within the time out and we are requesting infrequent fixes diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index e8b89e0e63c5..8f6564a06450 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -133,7 +133,7 @@ import java.lang.ref.WeakReference; * <li>It is good programming practice to have your application * register a OnErrorListener to look out for error notifications from * the internal player engine.</li> - * <li>IlleglStateException is + * <li>IllegalStateException is * thrown to prevent programming errors such as calling {@link #prepare()}, * {@link #prepareAsync()}, or one of the overloaded <code>setDataSource * </code> methods in an invalid state. </li> diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 6cb146c06094..8abd6499689b 100644 --- a/opengl/libagl/Android.mk +++ b/opengl/libagl/Android.mk @@ -37,6 +37,10 @@ ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -fstrict-aliasing endif +ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) + LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER +endif + ifneq ($(TARGET_SIMULATOR),true) # we need to access the private Bionic header <bionic_tls.h> # on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 9407bd55305e..d67612e681a8 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -1515,7 +1515,7 @@ void glReadPixels( ogles_error(c, GL_INVALID_VALUE); return; } - if (x<0 || x<0) { + if (x<0 || y<0) { ogles_error(c, GL_INVALID_VALUE); return; } diff --git a/opengl/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp index 33b25ab6c775..f031c79cd33e 100644 --- a/opengl/tests/gl_jni/jni/gl_code.cpp +++ b/opengl/tests/gl_jni/jni/gl_code.cpp @@ -180,4 +180,5 @@ JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobjec JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_changeBackground(JNIEnv * env, jobject obj) { background = 1.0f - background; -}
\ No newline at end of file +} + diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 1b4ba817adec..1019fa81d65e 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -399,9 +399,12 @@ public class SettingsProvider extends ContentProvider { } } else if (prefix == '-' && index >= 0) { // remove the provider from the list if present - // remove leading and trailing commas - if (index > 0) index--; - if (end < providers.length()) end++; + // remove leading or trailing comma + if (index > 0) { + index--; + } else if (end < providers.length()) { + end++; + } newProviders = providers.substring(0, index); if (end < providers.length()) { diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index 24526af68240..dc5fd30c15d5 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -869,7 +869,7 @@ class AppWidgetService extends IAppWidgetService.Stub out.startTag(null, "p"); out.attribute(null, "pkg", p.info.provider.getPackageName()); out.attribute(null, "cl", p.info.provider.getClassName()); - out.endTag(null, "h"); + out.endTag(null, "p"); p.tag = providerIndex; providerIndex++; } diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 0c205ca83566..5bf66e4d1282 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -889,13 +889,27 @@ public class InputMethodManagerService extends IInputMethodManager.Stub MSG_UNBIND_METHOD, mCurSeq, mCurClient.client)); } } + + private void finishSession(SessionState sessionState) { + if (sessionState != null && sessionState.session != null) { + try { + sessionState.session.finishSession(); + } catch (RemoteException e) { + Slog.w(TAG, "Session failed to close due to remote exception", e); + } + } + } void clearCurMethodLocked() { if (mCurMethod != null) { for (ClientState cs : mClients.values()) { cs.sessionRequested = false; + finishSession(cs.curSession); cs.curSession = null; } + + finishSession(mEnabledSession); + mEnabledSession = null; mCurMethod = null; } mStatusBar.setIconVisibility(mInputMethodIcon, false); diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index b9204c7ede6a..36c07e384316 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -2363,7 +2363,7 @@ class PackageManagerService extends IPackageManager.Stub { && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 && (!mSafeMode || (p.applicationInfo.flags &ApplicationInfo.FLAG_SYSTEM) != 0)) { - finalList.add(p.applicationInfo); + finalList.add(PackageParser.generateApplicationInfo(p, flags)); } } } diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 53de7d99e517..be5cc7bbc592 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -6526,18 +6526,30 @@ public class WindowManagerService extends IWindowManager.Stub case RawInputEvent.CLASS_KEYBOARD: KeyEvent ke = (KeyEvent)ev.event; if (ke.isDown()) { - lastKey = ke; - downTime = curTime; - keyRepeatCount = 0; lastKeyTime = curTime; - nextKeyTime = lastKeyTime - + ViewConfiguration.getLongPressTimeout(); - if (DEBUG_INPUT) Slog.v( - TAG, "Received key down: first repeat @ " - + nextKeyTime); + if (lastKey != null && + ke.getKeyCode() == lastKey.getKeyCode()) { + keyRepeatCount++; + // Arbitrary long timeout to block + // repeating here since we know that + // the device driver takes care of it. + nextKeyTime = lastKeyTime + LONG_WAIT; + if (DEBUG_INPUT) Slog.v( + TAG, "Received repeated key down"); + } else { + downTime = curTime; + keyRepeatCount = 0; + nextKeyTime = lastKeyTime + + ViewConfiguration.getLongPressTimeout(); + if (DEBUG_INPUT) Slog.v( + TAG, "Received key down: first repeat @ " + + nextKeyTime); + } + lastKey = ke; } else { lastKey = null; downTime = 0; + keyRepeatCount = 0; // Arbitrary long timeout. lastKeyTime = curTime; nextKeyTime = curTime + LONG_WAIT; @@ -6545,7 +6557,12 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Received key up: ignore repeat @ " + nextKeyTime); } - dispatchKey((KeyEvent)ev.event, 0, 0); + if (keyRepeatCount > 0) { + dispatchKey(KeyEvent.changeTimeRepeat(ke, + ke.getEventTime(), keyRepeatCount), 0, 0); + } else { + dispatchKey(ke, 0, 0); + } mQueue.recycleEvent(ev); break; case RawInputEvent.CLASS_TOUCHSCREEN: @@ -8684,7 +8701,8 @@ public class WindowManagerService extends IWindowManager.Stub for (int i=0; i<N; i++) { WindowState win = allAppWindows.get(i); if (win == startingWindow || win.mAppFreezing - || win.mViewVisibility != View.VISIBLE) { + || win.mViewVisibility != View.VISIBLE + || win.mAttrs.type == TYPE_APPLICATION_STARTING) { continue; } if (DEBUG_VISIBILITY) { @@ -11328,6 +11346,7 @@ public class WindowManagerService extends IWindowManager.Stub "DimSurface", -1, 16, 16, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM); + mDimSurface.setAlpha(0.0f); } catch (Exception e) { Slog.e(TAG, "Exception creating Dim surface", e); } diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java index 94d1cb492494..3b0c436bf9b9 100644 --- a/services/java/com/android/server/status/StatusBarPolicy.java +++ b/services/java/com/android/server/status/StatusBarPolicy.java @@ -954,7 +954,9 @@ public class StatusBarPolicy { && ((mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_0) || (mServiceState.getRadioTechnology() - == ServiceState.RADIO_TECHNOLOGY_EVDO_A))); + == ServiceState.RADIO_TECHNOLOGY_EVDO_A) + || (mServiceState.getRadioTechnology() + == ServiceState.RADIO_TECHNOLOGY_EVDO_B))); } private boolean hasService() { @@ -1070,7 +1072,6 @@ public class StatusBarPolicy { } private final void updateDataNetType(int net) { - switch (net) { case TelephonyManager.NETWORK_TYPE_EDGE: mDataIconList = sDataNetType_e; @@ -1096,6 +1097,7 @@ public class StatusBarPolicy { break; case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through case TelephonyManager.NETWORK_TYPE_EVDO_A: + case TelephonyManager.NETWORK_TYPE_EVDO_B: mDataIconList = sDataNetType_3g; break; default: diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java index ad7dfc9e2858..2f7666d118bc 100644 --- a/telephony/java/android/telephony/NeighboringCellInfo.java +++ b/telephony/java/android/telephony/NeighboringCellInfo.java @@ -133,8 +133,11 @@ public class NeighboringCellInfo implements Parcelable case NETWORK_TYPE_GPRS: case NETWORK_TYPE_EDGE: mNetworkType = radioType; - mLac = Integer.valueOf(location.substring(0, 4), 16); - mCid = Integer.valueOf(location.substring(4), 16); + // check if 0xFFFFFFFF for UNKNOWN_CID + if (!location.equalsIgnoreCase("FFFFFFFF")) { + mCid = Integer.valueOf(location.substring(4), 16); + mLac = Integer.valueOf(location.substring(0, 4), 16); + } break; case NETWORK_TYPE_UMTS: case NETWORK_TYPE_HSDPA: @@ -293,4 +296,4 @@ public class NeighboringCellInfo implements Parcelable return new NeighboringCellInfo[size]; } }; -}
\ No newline at end of file +} diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 6c665595cc26..1f0088501576 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -89,6 +89,8 @@ public class ServiceState implements Parcelable { public static final int RADIO_TECHNOLOGY_HSUPA = 10; /** @hide */ public static final int RADIO_TECHNOLOGY_HSPA = 11; + /** @hide */ + public static final int RADIO_TECHNOLOGY_EVDO_B = 12; /** * Available registration states for GSM, UMTS and CDMA. @@ -379,7 +381,6 @@ public class ServiceState implements Parcelable { @Override public String toString() { String radioTechnology = new String("Error in radioTechnology"); - switch(this.mRadioTechnology) { case 0: radioTechnology = "Unknown"; @@ -417,6 +418,9 @@ public class ServiceState implements Parcelable { case 11: radioTechnology = "HSPA"; break; + case 12: + radioTechnology = "EvDo rev. B"; + break; default: Log.w(LOG_TAG, "mRadioTechnology variable out of range."); break; diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 312272272f85..f5e9751b9571 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -398,4 +398,6 @@ public final class SmsManager { static public final int RESULT_ERROR_NO_SERVICE = 4; /** Failed because we reached the sending queue limit. {@hide} */ static public final int RESULT_ERROR_LIMIT_EXCEEDED = 5; + /** Failed because FDN is enabled. {@hide} */ + static public final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index f018d1074a74..ab63017b0df1 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -391,6 +391,9 @@ public class TelephonyManager { public static final int NETWORK_TYPE_HSPA = 10; /** Current network is iDen */ public static final int NETWORK_TYPE_IDEN = 11; + /** Current network is EVDO revision B*/ + public static final int NETWORK_TYPE_EVDO_B = 12; + /** * Returns a constant indicating the radio technology (network type) @@ -407,6 +410,7 @@ public class TelephonyManager { * @see #NETWORK_TYPE_CDMA * @see #NETWORK_TYPE_EVDO_0 * @see #NETWORK_TYPE_EVDO_A + * @see #NETWORK_TYPE_EVDO_B * @see #NETWORK_TYPE_1xRTT */ public int getNetworkType() { @@ -454,6 +458,8 @@ public class TelephonyManager { return "CDMA - EvDo rev. 0"; case NETWORK_TYPE_EVDO_A: return "CDMA - EvDo rev. A"; + case NETWORK_TYPE_EVDO_B: + return "CDMA - EvDo rev. B"; case NETWORK_TYPE_1xRTT: return "CDMA - 1xRTT"; default: diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java index eb0a440dff25..94c544ecffd5 100644 --- a/telephony/java/com/android/internal/telephony/CommandException.java +++ b/telephony/java/com/android/internal/telephony/CommandException.java @@ -37,6 +37,10 @@ public class CommandException extends RuntimeException { OP_NOT_ALLOWED_DURING_VOICE_CALL, OP_NOT_ALLOWED_BEFORE_REG_NW, SMS_FAIL_RETRY, + SIM_ABSENT, + SUBSCRIPTION_NOT_AVAILABLE, + MODE_NOT_SUPPORTED, + FDN_CHECK_FAILURE, ILLEGAL_SIM_OR_ME, } @@ -69,6 +73,14 @@ public class CommandException extends RuntimeException { return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW); case RILConstants.SMS_SEND_FAIL_RETRY: return new CommandException(Error.SMS_FAIL_RETRY); + case RILConstants.SIM_ABSENT: + return new CommandException(Error.SIM_ABSENT); + case RILConstants.SUBSCRIPTION_NOT_AVAILABLE: + return new CommandException(Error.SUBSCRIPTION_NOT_AVAILABLE); + case RILConstants.MODE_NOT_SUPPORTED: + return new CommandException(Error.MODE_NOT_SUPPORTED); + case RILConstants.FDN_CHECK_FAILURE: + return new CommandException(Error.FDN_CHECK_FAILURE); case RILConstants.ILLEGAL_SIM_OR_ME: return new CommandException(Error.ILLEGAL_SIM_OR_ME); default: diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java index d90c3056bf76..8e03c5a5bd5e 100644 --- a/telephony/java/com/android/internal/telephony/CommandsInterface.java +++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java @@ -664,6 +664,19 @@ public interface CommandsInterface { * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj + * ar.result is null on success and failure + * + * CLIR_DEFAULT == on "use subscription default value" + * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) + * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) + */ + void dial(String address, int clirMode, UUSInfo uusInfo, Message result); + + /** + * returned message + * retMsg.obj = AsyncResult ar + * ar.exception carries exception on failure + * ar.userObject contains the orignal value of result.obj * ar.result is String containing IMSI on success */ void getIMSI(Message result); diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java index 37e8a99e6799..0bcb63a8a7b4 100644 --- a/telephony/java/com/android/internal/telephony/Connection.java +++ b/telephony/java/com/android/internal/telephony/Connection.java @@ -50,6 +50,7 @@ public abstract class Connection { CS_RESTRICTED, /* call was blocked by restricted all voice access */ CS_RESTRICTED_NORMAL, /* call was blocked by restricted normal voice access */ CS_RESTRICTED_EMERGENCY, /* call was blocked by restricted emergency voice access */ + UNOBTAINABLE_NUMBER, /* Unassigned number (3GPP TS 24.008 table 10.5.123) */ CDMA_LOCKED_UNTIL_POWER_CYCLE, /* MS is locked until next power cycle */ CDMA_DROP, CDMA_INTERCEPT, /* INTERCEPT order received, MS state idle entered */ @@ -273,6 +274,13 @@ public abstract class Connection { public abstract int getNumberPresentation(); /** + * Returns the User to User Signaling (UUS) information associated with + * incoming and waiting calls + * @return UUSInfo containing the UUS userdata. + */ + public abstract UUSInfo getUUSInfo(); + + /** * Build a human representation of a connection instance, suitable for debugging. * Don't log personal stuff unless in debug mode. * @return a string representing the internal state of this connection. diff --git a/telephony/java/com/android/internal/telephony/DriverCall.java b/telephony/java/com/android/internal/telephony/DriverCall.java index 66f6b9cbff95..663c2842a793 100644 --- a/telephony/java/com/android/internal/telephony/DriverCall.java +++ b/telephony/java/com/android/internal/telephony/DriverCall.java @@ -49,6 +49,7 @@ public class DriverCall implements Comparable { public int numberPresentation; public String name; public int namePresentation; + public UUSInfo uusInfo; /** returns null on error */ static DriverCall diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java index 7179bef9f165..f14ab707e7d3 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -789,6 +789,19 @@ public interface Phone { Connection dial(String dialString) throws CallStateException; /** + * Initiate a new voice connection with supplementary User to User + * Information. This happens asynchronously, so you cannot assume the audio + * path is connected (or a call index has been assigned) until + * PhoneStateChanged notification has occurred. + * + * @exception CallStateException if a new outgoing call is not currently + * possible because no more call slots exist or a call exists + * that is dialing, alerting, ringing, or waiting. Other + * errors are handled asynchronously. + */ + Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException; + + /** * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated * without SEND (so <code>dial</code> is not appropriate). * diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java index cd72752e4328..803b73685587 100644 --- a/telephony/java/com/android/internal/telephony/PhoneFactory.java +++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java @@ -109,13 +109,13 @@ public class PhoneFactory { int phoneType = getPhoneType(networkMode); if (phoneType == Phone.PHONE_TYPE_GSM) { + Log.i(LOG_TAG, "Creating GSMPhone"); sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier)); - Log.i(LOG_TAG, "Creating GSMPhone"); } else if (phoneType == Phone.PHONE_TYPE_CDMA) { + Log.i(LOG_TAG, "Creating CDMAPhone"); sProxyPhone = new PhoneProxy(new CDMAPhone(context, sCommandsInterface, sPhoneNotifier)); - Log.i(LOG_TAG, "Creating CDMAPhone"); } sMadeDefaults = true; diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java index 6d3798ed1459..e1511e6ed79f 100644 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java @@ -423,6 +423,10 @@ public class PhoneProxy extends Handler implements Phone { return mActivePhone.dial(dialString); } + public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { + return mActivePhone.dial(dialString, uusInfo); + } + public boolean handlePinMmi(String dialString) { return mActivePhone.handlePinMmi(dialString); } diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index d8e313a79908..3d410fd2c465 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -796,12 +796,26 @@ public final class RIL extends BaseCommands implements CommandsInterface { public void dial (String address, int clirMode, Message result) { + dial(address, clirMode, null, result); + } + + public void + dial(String address, int clirMode, UUSInfo uusInfo, Message result) { RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); rr.mp.writeString(address); rr.mp.writeInt(clirMode); rr.mp.writeInt(0); // UUS information is absent + if (uusInfo == null) { + rr.mp.writeInt(0); // UUS information is absent + } else { + rr.mp.writeInt(1); // UUS information is present + rr.mp.writeInt(uusInfo.getType()); + rr.mp.writeInt(uusInfo.getDcs()); + rr.mp.writeByteArray(uusInfo.getUserData()); + } + if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); @@ -2837,10 +2851,21 @@ public final class RIL extends BaseCommands implements CommandsInterface { dc.namePresentation = p.readInt(); int uusInfoPresent = p.readInt(); if (uusInfoPresent == 1) { - // TODO: Copy the data to dc to forward to the apps. - p.readInt(); - p.readInt(); - p.createByteArray(); + dc.uusInfo = new UUSInfo(); + dc.uusInfo.setType(p.readInt()); + dc.uusInfo.setDcs(p.readInt()); + byte[] userData = p.createByteArray(); + dc.uusInfo.setUserData(userData); + Log + .v(LOG_TAG, String.format("Incoming UUS : type=%d, dcs=%d, length=%d", + dc.uusInfo.getType(), dc.uusInfo.getDcs(), + dc.uusInfo.getUserData().length)); + Log.v(LOG_TAG, "Incoming UUS : data (string)=" + + new String(dc.uusInfo.getUserData())); + Log.v(LOG_TAG, "Incoming UUS : data (hex): " + + IccUtils.bytesToHexString(dc.uusInfo.getUserData())); + } else { + Log.v(LOG_TAG, "Incoming UUS : NOT present!"); } // Make sure there's a leading + on addresses with a TOA of 145 diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 01f4ab274c13..71a80e01eacf 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -45,6 +45,11 @@ public interface RILConstants { int OP_NOT_ALLOWED_BEFORE_REG_NW = 9; /* request is not allowed before device registers to network */ int SMS_SEND_FAIL_RETRY = 10; /* send sms fail and need retry */ + int SIM_ABSENT = 11; /* ICC card is absent */ + int SUBSCRIPTION_NOT_AVAILABLE = 12; /* fail to find CDMA subscription from specified + location */ + int MODE_NOT_SUPPORTED = 13; /* HW does not support preferred network type */ + int FDN_CHECK_FAILURE = 14; /* send operation barred error when FDN is enabled */ int ILLEGAL_SIM_OR_ME = 15; /* network selection failure due to wrong SIM/ME and no retries needed */ diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index 764d12ebe067..ca526a521dc3 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -62,6 +62,7 @@ import static android.telephony.SmsManager.RESULT_ERROR_NO_SERVICE; import static android.telephony.SmsManager.RESULT_ERROR_NULL_PDU; import static android.telephony.SmsManager.RESULT_ERROR_RADIO_OFF; import static android.telephony.SmsManager.RESULT_ERROR_LIMIT_EXCEEDED; +import static android.telephony.SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE; public abstract class SMSDispatcher extends Handler { @@ -499,13 +500,20 @@ public abstract class SMSDispatcher extends Handler { Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker); sendMessageDelayed(retryMsg, SEND_RETRY_DELAY); } else if (tracker.mSentIntent != null) { + int error = RESULT_ERROR_GENERIC_FAILURE; + + if (((CommandException)(ar.exception)).getCommandError() + == CommandException.Error.FDN_CHECK_FAILURE) { + error = RESULT_ERROR_FDN_CHECK_FAILURE; + } // Done retrying; return an error to the app. try { Intent fillIn = new Intent(); if (ar.result != null) { fillIn.putExtra("errorCode", ((SmsResponse)ar.result).errorCode); } - tracker.mSentIntent.send(mContext, RESULT_ERROR_GENERIC_FAILURE, fillIn); + tracker.mSentIntent.send(mContext, error, fillIn); + } catch (CanceledException ex) {} } } diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java index 73836497dc4e..706f260b76ee 100644 --- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java @@ -44,6 +44,7 @@ public abstract class ServiceStateTracker extends Handler { protected static final int DATA_ACCESS_HSDPA = 9; protected static final int DATA_ACCESS_HSUPA = 10; protected static final int DATA_ACCESS_HSPA = 11; + protected static final int DATA_ACCESS_CDMA_EvDo_B = 12; protected CommandsInterface cm; diff --git a/telephony/java/com/android/internal/telephony/UUSInfo.java b/telephony/java/com/android/internal/telephony/UUSInfo.java new file mode 100644 index 000000000000..801b84563c98 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/UUSInfo.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +public class UUSInfo { + + /* + * User-to-User signaling Info activation types derived from 3GPP 23.087 + * v8.0 + */ + + public static final int UUS_TYPE1_IMPLICIT = 0; + + public static final int UUS_TYPE1_REQUIRED = 1; + + public static final int UUS_TYPE1_NOT_REQUIRED = 2; + + public static final int UUS_TYPE2_REQUIRED = 3; + + public static final int UUS_TYPE2_NOT_REQUIRED = 4; + + public static final int UUS_TYPE3_REQUIRED = 5; + + public static final int UUS_TYPE3_NOT_REQUIRED = 6; + + /* + * User-to-User Signaling Information data coding schemes. Possible values + * for Octet 3 (Protocol Discriminator field) in the UUIE. The values have + * been specified in section 10.5.4.25 of 3GPP TS 24.008 + */ + + public static final int UUS_DCS_USP = 0; /* User specified protocol */ + + public static final int UUS_DCS_OSIHLP = 1; /* OSI higher layer protocol */ + + public static final int UUS_DCS_X244 = 2; /* X.244 */ + + public static final int UUS_DCS_RMCF = 3; /* + * Reserved for system management + * convergence function + */ + + public static final int UUS_DCS_IA5c = 4; /* IA5 characters */ + + private int uusType; + + private int uusDcs; + + private byte[] uusData; + + public UUSInfo() { + this.uusType = UUS_TYPE1_IMPLICIT; + this.uusDcs = UUS_DCS_IA5c; + this.uusData = null; + } + + public UUSInfo(int uusType, int uusDcs, byte[] uusData) { + this.uusType = uusType; + this.uusDcs = uusDcs; + this.uusData = uusData; + } + + public int getDcs() { + return uusDcs; + } + + public void setDcs(int uusDcs) { + this.uusDcs = uusDcs; + } + + public int getType() { + return uusType; + } + + public void setType(int uusType) { + this.uusType = uusType; + } + + public byte[] getUserData() { + return uusData; + } + + public void setUserData(byte[] uusData) { + this.uusData = uusData; + } +} diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index 1f5accf38f21..0c591e4d951c 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -62,11 +62,13 @@ import com.android.internal.telephony.PhoneProxy; import com.android.internal.telephony.PhoneSubInfo; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; +import com.android.internal.telephony.UUSInfo; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC; import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY; +import java.util.ArrayList; import java.util.List; @@ -101,6 +103,7 @@ public class CDMAPhone extends PhoneBase { RuimFileHandler mRuimFileHandler; RuimRecords mRuimRecords; RuimCard mRuimCard; + ArrayList <CdmaMmiCode> mPendingMmis = new ArrayList<CdmaMmiCode>(); RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager; RuimSmsInterfaceManager mRuimSmsInterfaceManager; PhoneSubInfo mSubInfo; @@ -219,6 +222,8 @@ public class CDMAPhone extends PhoneBase { mSST.unregisterForNetworkAttach(this); //EVENT_REGISTERED_TO_NETWORK mCM.unSetOnSuppServiceNotification(this); + mPendingMmis.clear(); + //Force all referenced classes to unregister their former registered events mCT.dispose(); mDataConnection.dispose(); @@ -344,6 +349,10 @@ public class CDMAPhone extends PhoneBase { return mCT.dial(newDialString); } + public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { + throw new CallStateException("Sending UUS information NOT supported in CDMA!"); + } + public SignalStrength getSignalStrength() { return mSST.mSignalStrength; } @@ -355,8 +364,7 @@ public class CDMAPhone extends PhoneBase { public List<? extends MmiCode> getPendingMmiCodes() { - Log.e(LOG_TAG, "method getPendingMmiCodes is NOT supported in CDMA!"); - return null; + return mPendingMmis; } public void registerForSuppServiceNotification( @@ -373,6 +381,15 @@ public class CDMAPhone extends PhoneBase { return false; } + boolean isInCall() { + CdmaCall.State foregroundCallState = getForegroundCall().getState(); + CdmaCall.State backgroundCallState = getBackgroundCall().getState(); + CdmaCall.State ringingCallState = getRingingCall().getState(); + + return (foregroundCallState.isAlive() || backgroundCallState.isAlive() || ringingCallState + .isAlive()); + } + public void setNetworkSelectionModeAutomatic(Message response) { Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!"); @@ -472,7 +489,18 @@ public class CDMAPhone extends PhoneBase { } public boolean handlePinMmi(String dialString) { - Log.e(LOG_TAG, "method handlePinMmi is NOT supported in CDMA!"); + CdmaMmiCode mmi = CdmaMmiCode.newFromDialString(dialString, this); + + if (mmi == null) { + Log.e(LOG_TAG, "Mmi is NULL!"); + return false; + } else if (mmi.isPukCommand()) { + mPendingMmis.add(mmi); + mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); + mmi.processCode(); + return true; + } + Log.e(LOG_TAG, "Unrecognized mmi!"); return false; } @@ -484,6 +512,22 @@ public class CDMAPhone extends PhoneBase { (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming()); } + /** + * Removes the given MMI from the pending list and notifies registrants that + * it is complete. + * + * @param mmi MMI that is done + */ + void onMMIDone(CdmaMmiCode mmi) { + /* + * Only notify complete if it's on the pending list. Otherwise, it's + * already been handled (eg, previously canceled). + */ + if (mPendingMmis.remove(mmi)) { + mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); + } + } + public void setLine1Number(String alphaTag, String number, Message onComplete) { Log.e(LOG_TAG, "setLine1Number: not possible in CDMA"); } @@ -1405,5 +1449,4 @@ public class CDMAPhone extends PhoneBase { } return false; } - } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java index 188145b33fcb..fbe455e1ffdd 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java @@ -945,4 +945,10 @@ public class CdmaConnection extends Connection { public int getNumberPresentation() { return numberPresentation; } + + @Override + public UUSInfo getUUSInfo() { + // UUS information not supported in CDMA + return null; + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java b/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java new file mode 100644 index 000000000000..8dd8c2e6c679 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaMmiCode.java @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony.cdma; + +import android.content.Context; + +import com.android.internal.telephony.CommandException; +import com.android.internal.telephony.MmiCode; + +import android.os.AsyncResult; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +/** + * This class can handle Puk code Mmi + * + * {@hide} + * + */ +public final class CdmaMmiCode extends Handler implements MmiCode { + static final String LOG_TAG = "CDMA_MMI"; + + // Constants + + // From TS 22.030 6.5.2 + static final String ACTION_REGISTER = "**"; + + // Supp Service codes from TS 22.030 Annex B + static final String SC_PUK = "05"; + + // Event Constant + + static final int EVENT_SET_COMPLETE = 1; + + // Instance Variables + + CDMAPhone phone; + Context context; + + String action; // ACTION_REGISTER + String sc; // Service Code + String sia, sib, sic; // Service Info a,b,c + String poundString; // Entire MMI string up to and including # + String dialingNumber; + String pwd; // For password registration + + State state = State.PENDING; + CharSequence message; + + // Class Variables + + static Pattern sPatternSuppService = Pattern.compile( + "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)"); +/* 1 2 3 4 5 6 7 8 9 10 11 12 + + 1 = Full string up to and including # + 2 = action + 3 = service code + 5 = SIA + 7 = SIB + 9 = SIC + 10 = dialing number +*/ + + static final int MATCH_GROUP_POUND_STRING = 1; + static final int MATCH_GROUP_ACTION = 2; + static final int MATCH_GROUP_SERVICE_CODE = 3; + static final int MATCH_GROUP_SIA = 5; + static final int MATCH_GROUP_SIB = 7; + static final int MATCH_GROUP_SIC = 9; + static final int MATCH_GROUP_PWD_CONFIRM = 11; + static final int MATCH_GROUP_DIALING_NUMBER = 12; + + + // Public Class methods + + /** + * Check if provided string contains Mmi code in it and create corresponding + * Mmi if it does + */ + + public static CdmaMmiCode + newFromDialString(String dialString, CDMAPhone phone) { + Matcher m; + CdmaMmiCode ret = null; + + m = sPatternSuppService.matcher(dialString); + + // Is this formatted like a standard supplementary service code? + if (m.matches()) { + ret = new CdmaMmiCode(phone); + ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING)); + ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION)); + ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE)); + ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA)); + ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB)); + ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC)); + ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM)); + ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER)); + + } + + return ret; + } + + // Private Class methods + + /** make empty strings be null. + * Regexp returns empty strings for empty groups + */ + private static String + makeEmptyNull (String s) { + if (s != null && s.length() == 0) return null; + + return s; + } + + // Constructor + + CdmaMmiCode (CDMAPhone phone) { + super(phone.getHandler().getLooper()); + this.phone = phone; + this.context = phone.getContext(); + } + + // MmiCode implementation + + public State + getState() { + return state; + } + + public CharSequence + getMessage() { + return message; + } + + // inherited javadoc suffices + public void + cancel() { + // Complete or failed cannot be cancelled + if (state == State.COMPLETE || state == State.FAILED) { + return; + } + + state = State.CANCELLED; + phone.onMMIDone (this); + } + + public boolean isCancelable() { + return false; + } + + // Instance Methods + + /** + * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related + */ + boolean isPukCommand() { + return sc != null && sc.equals(SC_PUK); + } + + boolean isRegister() { + return action != null && action.equals(ACTION_REGISTER); + } + + public boolean isUssdRequest() { + Log.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode"); + return false; + } + + /** Process a MMI PUK code */ + void + processCode () { + try { + if (isPukCommand()) { + // sia = old PUK + // sib = new PIN + // sic = new PIN + String oldPinOrPuk = sia; + String newPin = sib; + int pinLen = newPin.length(); + if (isRegister()) { + if (!newPin.equals(sic)) { + // password mismatch; return error + handlePasswordError(com.android.internal.R.string.mismatchPin); + } else if (pinLen < 4 || pinLen > 8 ) { + // invalid length + handlePasswordError(com.android.internal.R.string.invalidPin); + } else { + phone.mCM.supplyIccPuk(oldPinOrPuk, newPin, + obtainMessage(EVENT_SET_COMPLETE, this)); + } + } else { + throw new RuntimeException ("Invalid or Unsupported MMI Code"); + } + } else { + throw new RuntimeException ("Invalid or Unsupported MMI Code"); + } + } catch (RuntimeException exc) { + state = State.FAILED; + message = context.getText(com.android.internal.R.string.mmiError); + phone.onMMIDone(this); + } + } + + private void handlePasswordError(int res) { + state = State.FAILED; + StringBuilder sb = new StringBuilder(getScString()); + sb.append("\n"); + sb.append(context.getText(res)); + message = sb; + phone.onMMIDone(this); + } + + public void + handleMessage (Message msg) { + AsyncResult ar; + + if (msg.what == EVENT_SET_COMPLETE) { + ar = (AsyncResult) (msg.obj); + onSetComplete(ar); + } else { + Log.e(LOG_TAG, "Unexpected reply"); + } + } + // Private instance methods + + private CharSequence getScString() { + if (sc != null) { + if (isPukCommand()) { + return context.getText(com.android.internal.R.string.PinMmi); + } + } + + return ""; + } + + private void + onSetComplete(AsyncResult ar){ + StringBuilder sb = new StringBuilder(getScString()); + sb.append("\n"); + + if (ar.exception != null) { + state = State.FAILED; + if (ar.exception instanceof CommandException) { + CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); + if (err == CommandException.Error.PASSWORD_INCORRECT) { + if (isPukCommand()) { + sb.append(context.getText( + com.android.internal.R.string.badPuk)); + } else { + sb.append(context.getText( + com.android.internal.R.string.passwordIncorrect)); + } + } else { + sb.append(context.getText( + com.android.internal.R.string.mmiError)); + } + } else { + sb.append(context.getText( + com.android.internal.R.string.mmiError)); + } + } else if (isRegister()) { + state = State.COMPLETE; + sb.append(context.getText( + com.android.internal.R.string.serviceRegistered)); + } else { + state = State.FAILED; + sb.append(context.getText( + com.android.internal.R.string.mmiError)); + } + + message = sb; + phone.onMMIDone(this); + } + +} diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index 39fe007f4b20..6c7158437379 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -945,6 +945,9 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { case DATA_ACCESS_CDMA_EvDo_A: ret = "CDMA - EvDo rev. A"; break; + case DATA_ACCESS_CDMA_EvDo_B: + ret = "CDMA - EvDo rev. B"; + break; default: if (DBG) { Log.e(LOG_TAG, "Wrong network. Can not return a string."); @@ -1237,6 +1240,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { case 6: // RADIO_TECHNOLOGY_1xRTT case 7: // RADIO_TECHNOLOGY_EVDO_0 case 8: // RADIO_TECHNOLOGY_EVDO_A + case 12: // RADIO_TECHNOLOGY_EVDO_B retVal = ServiceState.STATE_IN_SERVICE; break; default: diff --git a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java index e7fbf6bd8a8b..af2ad48a9bc0 100644 --- a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java +++ b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java @@ -25,6 +25,9 @@ package com.android.internal.telephony.gsm; * */ public interface CallFailCause { + // Unassigned/Unobtainable number + static final int UNOBTAINABLE_NUMBER = 1; + static final int NORMAL_CLEARING = 16; // Busy Tone static final int USER_BUSY = 17; diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index 2bb796827049..c7b1e5cd3c52 100755..100644 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -67,6 +67,7 @@ import com.android.internal.telephony.PhoneNotifier; import com.android.internal.telephony.PhoneProxy; import com.android.internal.telephony.PhoneSubInfo; import com.android.internal.telephony.TelephonyProperties; +import com.android.internal.telephony.UUSInfo; import com.android.internal.telephony.gsm.stk.StkService; import com.android.internal.telephony.test.SimulatedRadioControl; import com.android.internal.telephony.IccVmNotSupportedException; @@ -711,7 +712,12 @@ public class GSMPhone extends PhoneBase { } public Connection - dial (String dialString) throws CallStateException { + dial(String dialString) throws CallStateException { + return dial(dialString, null); + } + + public Connection + dial (String dialString, UUSInfo uusInfo) throws CallStateException { // Need to make sure dialString gets parsed properly String newDialString = PhoneNumberUtils.stripSeparators(dialString); @@ -727,9 +733,9 @@ public class GSMPhone extends PhoneBase { "dialing w/ mmi '" + mmi + "'..."); if (mmi == null) { - return mCT.dial(newDialString); + return mCT.dial(newDialString, uusInfo); } else if (mmi.isTemporaryModeCLIR()) { - return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode()); + return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode(), uusInfo); } else { mPendingMMIs.add(mmi); mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java index 87530e42874a..22fc13e5be12 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java @@ -37,6 +37,7 @@ import com.android.internal.telephony.DriverCall; import com.android.internal.telephony.EventLogTags; import com.android.internal.telephony.Phone; import com.android.internal.telephony.TelephonyProperties; +import com.android.internal.telephony.UUSInfo; import com.android.internal.telephony.gsm.CallFailCause; import com.android.internal.telephony.gsm.GSMPhone; import com.android.internal.telephony.gsm.GsmCall; @@ -167,7 +168,7 @@ public final class GsmCallTracker extends CallTracker { * clirMode is one of the CLIR_ constants */ Connection - dial (String dialString, int clirMode) throws CallStateException { + dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException { // note that this triggers call state changed notif clearDisconnected(); @@ -213,7 +214,7 @@ public final class GsmCallTracker extends CallTracker { // Always unmute when initiating a new call setMute(false); - cm.dial(pendingMO.address, clirMode, obtainCompleteMessage()); + cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage()); } updatePhoneState(); @@ -222,10 +223,19 @@ public final class GsmCallTracker extends CallTracker { return pendingMO; } + Connection + dial(String dialString) throws CallStateException { + return dial(dialString, CommandsInterface.CLIR_DEFAULT, null); + } + + Connection + dial(String dialString, UUSInfo uusInfo) throws CallStateException { + return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo); + } Connection - dial (String dialString) throws CallStateException { - return dial(dialString, CommandsInterface.CLIR_DEFAULT); + dial(String dialString, int clirMode) throws CallStateException { + return dial(dialString, clirMode, null); } void diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java index 4788a0130657..7dc25044eb16 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java @@ -73,6 +73,7 @@ public class GsmConnection extends Connection { DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED; PostDialState postDialState = PostDialState.NOT_STARTED; int numberPresentation = Connection.PRESENTATION_ALLOWED; + UUSInfo uusInfo; Handler h; @@ -126,6 +127,7 @@ public class GsmConnection extends Connection { isIncoming = dc.isMT; createTime = System.currentTimeMillis(); numberPresentation = dc.numberPresentation; + uusInfo = dc.uusInfo; this.index = index; @@ -356,6 +358,9 @@ public class GsmConnection extends Connection { case CallFailCause.FDN_BLOCKED: return DisconnectCause.FDN_BLOCKED; + case CallFailCause.UNOBTAINABLE_NUMBER: + return DisconnectCause.UNOBTAINABLE_NUMBER; + case CallFailCause.ERROR_UNSPECIFIED: case CallFailCause.NORMAL_CLEARING: default: @@ -728,4 +733,9 @@ public class GsmConnection extends Connection { public int getNumberPresentation() { return numberPresentation; } + + @Override + public UUSInfo getUUSInfo() { + return uusInfo; + } } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java index bcbd127497b2..cacf057d14c5 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java @@ -832,8 +832,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { if (ar.exception != null) { state = State.FAILED; - message = context.getText( - com.android.internal.R.string.mmiError); + message = getErrorMessage(ar); phone.onMMIDone(this); } @@ -852,6 +851,19 @@ public final class GsmMmiCode extends Handler implements MmiCode { } //***** Private instance methods + private CharSequence getErrorMessage(AsyncResult ar) { + + if (ar.exception instanceof CommandException) { + CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); + if (err == CommandException.Error.FDN_CHECK_FAILURE) { + Log.i(LOG_TAG, "FDN_CHECK_FAILURE"); + return context.getText(com.android.internal.R.string.mmiFdnError); + } + } + + return context.getText(com.android.internal.R.string.mmiError); + } + private CharSequence getScString() { if (sc != null) { if (isServiceCodeCallBarring(sc)) { @@ -904,6 +916,9 @@ public final class GsmMmiCode extends Handler implements MmiCode { sb.append("\n"); sb.append(context.getText( com.android.internal.R.string.needPuk2)); + } else if (err == CommandException.Error.FDN_CHECK_FAILURE) { + Log.i(LOG_TAG, "FDN_CHECK_FAILURE"); + sb.append(context.getText(com.android.internal.R.string.mmiFdnError)); } else { sb.append(context.getText( com.android.internal.R.string.mmiError)); @@ -953,7 +968,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { if (ar.exception != null) { state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); + sb.append(getErrorMessage(ar)); } else { int clirArgs[]; @@ -1123,7 +1138,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { if (ar.exception != null) { state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); + sb.append(getErrorMessage(ar)); } else { CallForwardInfo infos[]; @@ -1175,7 +1190,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { if (ar.exception != null) { state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); + sb.append(getErrorMessage(ar)); } else { int[] ints = (int[])ar.result; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java index 6ae316d0f08e..d7205169f7af 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java @@ -94,6 +94,13 @@ final class GsmSMSDispatcher extends SMSDispatcher { SmsMessage sms = (SmsMessage) smsb; boolean handled = false; + if (sms.isTypeZero()) { + // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be + // Displayed/Stored/Notified. They should only be acknowledged. + Log.d(TAG, "Received short message type 0, Dont display or store it. Send Ack"); + return Intents.RESULT_SMS_HANDLED; + } + // Special case the message waiting indicator messages if (sms.isMWISetMessage()) { mGsmPhone.updateMessageWaitingIndicator(true); diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index d627bafbafe9..12c6b8897b76 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java @@ -111,6 +111,14 @@ public class SmsMessage extends SmsMessageBase{ } /** + * 3GPP TS 23.040 9.2.3.9 specifies that Type Zero messages are indicated + * by TP_PID field set to value 0x40 + */ + public boolean isTypeZero() { + return (protocolIdentifier == 0x40); + } + + /** * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the * +CMT unsolicited response (PDU mode, of course) * +CMT: [<alpha>],<length><CR><LF><pdu> diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java index 11b3fd6fa12c..a120f5234124 100644 --- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java +++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java @@ -29,6 +29,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.DataCallState; import com.android.internal.telephony.IccCard; import com.android.internal.telephony.Phone; +import com.android.internal.telephony.UUSInfo; import com.android.internal.telephony.gsm.CallFailCause; import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo; import com.android.internal.telephony.gsm.SuppServiceNotification; @@ -496,6 +497,23 @@ public final class SimulatedCommands extends BaseCommands * retMsg.obj = AsyncResult ar * ar.exception carries exception on failure * ar.userObject contains the orignal value of result.obj + * ar.result is null on success and failure + * + * CLIR_DEFAULT == on "use subscription default value" + * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) + * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) + */ + public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) { + simulatedCallState.onDial(address); + + resultSuccess(result, null); + } + + /** + * returned message + * retMsg.obj = AsyncResult ar + * ar.exception carries exception on failure + * ar.userObject contains the orignal value of result.obj * ar.result is String containing IMSI on success */ public void getIMSI(Message result) { diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp index fc658f5b54fb..f17f66b31f8e 100644 --- a/tools/aidl/aidl.cpp +++ b/tools/aidl/aidl.cpp @@ -55,7 +55,7 @@ test_document(document_item_type* d) printf("parcelable %s %s;\n", b->package, b->name.data); } else { - printf("UNKNOWN d=0x%08x d->item_type=%ld\n", (long)d, d->item_type); + printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type); } d = d->next; } |