diff options
101 files changed, 1518 insertions, 321 deletions
@@ -294,7 +294,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 := \ @@ -334,7 +334,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 9d259f3..28d417c 100644 --- a/api/current.xml +++ b/api/current.xml @@ -131660,6 +131660,17 @@ visibility="public" > </field> +<field name="MEDIA_IGNORE_FILENAME" + type="java.lang.String" + transient="false" + volatile="false" + value="".nomedia"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="MEDIA_SCANNER_VOLUME" type="java.lang.String" transient="false" @@ -142238,6 +142249,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 +169659,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 +169692,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 +169879,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/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 736ac08..301883f 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -205,7 +205,7 @@ public class Am { String uri = nextArg(); if (uri != null) { Intent oldIntent = intent; - intent = Intent.getIntent(uri); + intent = Intent.parseUri(uri, 0); if (oldIntent.getAction() != null) { intent.setAction(oldIntent.getAction()); } diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java index 377e383..fc2dfc0 100644 --- a/core/java/android/content/ContentService.java +++ b/core/java/android/content/ContentService.java @@ -537,6 +537,9 @@ public final class ContentService extends IContentService.Stub { // Look to see if the proper child already exists String segment = getUriSegment(uri, index); + if (segment == null) { + throw new IllegalArgumentException("Invalid Uri (" + uri + ") used for observer"); + } int N = mChildren.size(); for (int i = 0; i < N; i++) { ObserverNode node = mChildren.get(i); diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java index 79178f4..6539156 100644 --- a/core/java/android/database/Cursor.java +++ b/core/java/android/database/Cursor.java @@ -25,6 +25,9 @@ import java.util.Map; /** * This interface provides random read-write access to the result set returned * by a database query. + * + * Cursor implementations are not required to be synchronized so code using a Cursor from multiple + * threads should perform its own synchronization when using the Cursor. */ public interface Cursor { /** diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java index 6e5b3e1..c7e58fa 100644 --- a/core/java/android/database/sqlite/SQLiteCursor.java +++ b/core/java/android/database/sqlite/SQLiteCursor.java @@ -36,6 +36,9 @@ import java.util.concurrent.locks.ReentrantLock; /** * A Cursor implementation that exposes results from a query on a * {@link SQLiteDatabase}. + * + * SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple + * threads should perform its own synchronization when using the SQLiteCursor. */ public class SQLiteCursor extends AbstractWindowedCursor { static final String TAG = "Cursor"; diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index fb5507d..d4f9b20 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -1134,7 +1134,8 @@ public class SQLiteDatabase extends SQLiteClosable { * * @param sql The raw SQL statement, may contain ? for unknown values to be * bound later. - * @return a pre-compiled statement object. + * @return A pre-compiled {@link SQLiteStatement} object. Note that + * {@link SQLiteStatement}s are not synchronized, see the documentation for more details. */ public SQLiteStatement compileStatement(String sql) throws SQLException { lock(); @@ -1175,7 +1176,8 @@ public class SQLiteDatabase extends SQLiteClosable { * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. - * @return A Cursor object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */ public Cursor query(boolean distinct, String table, String[] columns, @@ -1213,7 +1215,8 @@ public class SQLiteDatabase extends SQLiteClosable { * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. - * @return A Cursor object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */ public Cursor queryWithFactory(CursorFactory cursorFactory, @@ -1254,7 +1257,8 @@ public class SQLiteDatabase extends SQLiteClosable { * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */ public Cursor query(String table, String[] columns, String selection, @@ -1291,7 +1295,8 @@ public class SQLiteDatabase extends SQLiteClosable { * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */ public Cursor query(String table, String[] columns, String selection, @@ -1309,7 +1314,8 @@ public class SQLiteDatabase extends SQLiteClosable { * @param selectionArgs You may include ?s in where clause in the query, * which will be replaced by the values from selectionArgs. The * values will be bound as Strings. - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. */ public Cursor rawQuery(String sql, String[] selectionArgs) { return rawQueryWithFactory(null, sql, selectionArgs, null); @@ -1324,7 +1330,8 @@ public class SQLiteDatabase extends SQLiteClosable { * which will be replaced by the values from selectionArgs. The * values will be bound as Strings. * @param editTable the name of the first table, which is editable - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. */ public Cursor rawQueryWithFactory( CursorFactory cursorFactory, String sql, String[] selectionArgs, @@ -1379,7 +1386,8 @@ public class SQLiteDatabase extends SQLiteClosable { * values will be bound as Strings. * @param initialRead set the initial count of items to read from the cursor * @param maxRead set the count of items to read on each iteration after the first - * @return A {@link Cursor} object, which is positioned before the first entry + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. * * This work is incomplete and not fully tested or reviewed, so currently * hidden. diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java index 89a5f0d..4d96f12 100644 --- a/core/java/android/database/sqlite/SQLiteProgram.java +++ b/core/java/android/database/sqlite/SQLiteProgram.java @@ -20,6 +20,9 @@ import android.util.Log; /** * A base class for compiled SQLite programs. + * + * SQLiteProgram is not internally synchronized so code using a SQLiteProgram from multiple + * threads should perform its own synchronization when using the SQLiteProgram. */ public abstract class SQLiteProgram extends SQLiteClosable { diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java index 43d2fac..905b66b 100644 --- a/core/java/android/database/sqlite/SQLiteQuery.java +++ b/core/java/android/database/sqlite/SQLiteQuery.java @@ -23,6 +23,9 @@ import android.util.Log; /** * A SQLite program that represents a query that reads the resulting rows into a CursorWindow. * This class is used by SQLiteCursor and isn't useful itself. + * + * SQLiteQuery is not internally synchronized so code using a SQLiteQuery from multiple + * threads should perform its own synchronization when using the SQLiteQuery. */ public class SQLiteQuery extends SQLiteProgram { private static final String TAG = "Cursor"; diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java index 98da414..47cca87 100644 --- a/core/java/android/database/sqlite/SQLiteStatement.java +++ b/core/java/android/database/sqlite/SQLiteStatement.java @@ -23,6 +23,9 @@ import android.os.SystemClock; * The statement cannot return multiple rows, but 1x1 result sets are allowed. * Don't use SQLiteStatement constructor directly, please use * {@link SQLiteDatabase#compileStatement(String)} + * + * SQLiteStatement is not internally synchronized so code using a SQLiteStatement from multiple + * threads should perform its own synchronization when using the SQLiteStatement. */ public class SQLiteStatement extends SQLiteProgram { diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index 80e9865..44f30f7 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 bfa82ee..35fd46f 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 8c8d3e5..1a261d3 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 98f32b3..214510d 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/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java index cc48aeb..bbad2b6 100644 --- a/core/java/android/preference/DialogPreference.java +++ b/core/java/android/preference/DialogPreference.java @@ -33,7 +33,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; -import android.view.inputmethod.InputMethodManager; import android.widget.TextView; /** @@ -275,7 +274,7 @@ public abstract class DialogPreference extends Preference implements protected void showDialog(Bundle state) { Context context = getContext(); - mWhichButtonClicked = DialogInterface.BUTTON2; + mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE; mBuilder = new AlertDialog.Builder(context) .setTitle(mDialogTitle) diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index c9d125b..40ed980 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -1819,4 +1819,12 @@ public final class MediaStore { * Name of current volume being scanned by the media scanner. */ public static final String MEDIA_SCANNER_VOLUME = "volume"; + + /** + * Name of the file signaling the media scanner to ignore media in the containing directory + * and its subdirectories. Developers should use this to avoid application graphics showing + * up in the Gallery and likewise prevent application sounds and music from showing up in + * the Music app. + */ + public static final String MEDIA_IGNORE_FILENAME = ".nomedia"; } diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index d4f9787..9aa16b5 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/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java index aab76c4..e69b807 100644 --- a/core/java/android/view/VelocityTracker.java +++ b/core/java/android/view/VelocityTracker.java @@ -206,7 +206,7 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { final long oldestTime = pastTime[oldestTouch]; float accumX = 0; float accumY = 0; - float N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1; + int N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1; // Skip the last received event, since it is probably pretty noisy. if (N > 3) N--; diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java index 034c88a..ca9ad53 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 b3d5f1a..1fc23ab 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/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index f34823c..1ed6b16 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -1087,7 +1087,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList @Override public boolean dispatchKeyEvent(KeyEvent event) { // Gallery steals all key events - return event.dispatch(this); + return event.dispatch(this, null, null); } /** diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 202e658..8e9eb05 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -947,4 +947,20 @@ public class ProgressBar extends View { setProgress(ss.progress); setSecondaryProgress(ss.secondaryProgress); } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (mIndeterminate) { + startAnimation(); + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mIndeterminate) { + stopAnimation(); + } + } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 64c9c99..950012c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -4547,6 +4547,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener outText.text = TextUtils.substring(content, partialStartOffset, partialEndOffset); } + } else { + outText.partialStartOffset = 0; + outText.partialEndOffset = 0; + outText.text = ""; } outText.flags = 0; if (MetaKeyKeyListener.getMetaState(mText, MetaKeyKeyListener.META_SELECTING) != 0) { diff --git a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java index 7e9bbd1..98dcb8b 100644 --- a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java +++ b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java @@ -23,13 +23,10 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; -import android.os.Handler; import android.os.storage.IMountService; -import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.Environment; -import android.widget.Toast; import android.util.Log; /** @@ -38,7 +35,7 @@ import android.util.Log; */ public class ExternalMediaFormatActivity extends AlertActivity implements DialogInterface.OnClickListener { - private static final int POSITIVE_BUTTON = AlertDialog.BUTTON1; + private static final int POSITIVE_BUTTON = AlertDialog.BUTTON_POSITIVE; /** Used to detect when the media state changes, in case we need to call finish() */ private BroadcastReceiver mStorageReceiver = new BroadcastReceiver() { diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java index 24818a8..36f45b2 100755 --- a/core/java/com/android/internal/app/NetInitiatedActivity.java +++ b/core/java/com/android/internal/app/NetInitiatedActivity.java @@ -23,14 +23,9 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.RemoteException; -import android.os.ServiceManager; import android.widget.Toast; import android.util.Log; import android.location.LocationManager; -import com.android.internal.location.GpsLocationProvider; import com.android.internal.location.GpsNetInitiatedHandler; /** @@ -44,8 +39,8 @@ public class NetInitiatedActivity extends AlertActivity implements DialogInterfa private static final boolean DEBUG = true; private static final boolean VERBOSE = false; - private static final int POSITIVE_BUTTON = AlertDialog.BUTTON1; - private static final int NEGATIVE_BUTTON = AlertDialog.BUTTON2; + private static final int POSITIVE_BUTTON = AlertDialog.BUTTON_POSITIVE; + private static final int NEGATIVE_BUTTON = AlertDialog.BUTTON_NEGATIVE; // Dialog button text public static final String BUTTON_TEXT_ACCEPT = "Accept"; diff --git a/core/java/com/android/internal/app/RingtonePickerActivity.java b/core/java/com/android/internal/app/RingtonePickerActivity.java index ddddabe..5569ffe 100644 --- a/core/java/com/android/internal/app/RingtonePickerActivity.java +++ b/core/java/com/android/internal/app/RingtonePickerActivity.java @@ -223,7 +223,7 @@ public final class RingtonePickerActivity extends AlertActivity implements * On click of Ok/Cancel buttons */ public void onClick(DialogInterface dialog, int which) { - boolean positiveResult = which == BUTTON1; + boolean positiveResult = which == DialogInterface.BUTTON_POSITIVE; // Stop playing the previous ringtone mRingtoneManager.stopPreviousRingtone(); diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl index a05ff14..338dcaa 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 94bc9fd..b066fad 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 d465c5a..1cd118b 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/arrays.xml b/core/res/res/values/arrays.xml index 4672c0e..a0bc5b3 100644 --- a/core/res/res/values/arrays.xml +++ b/core/res/res/values/arrays.xml @@ -128,11 +128,11 @@ <item><xliff:g id="id">phone_evdo_signal</xliff:g></item> <item><xliff:g id="id">data_connection</xliff:g></item> <item><xliff:g id="id">cdma_eri</xliff:g></item> + <item><xliff:g id="id">wifi</xliff:g></item> <item><xliff:g id="id">tty</xliff:g></item> <item><xliff:g id="id">volume</xliff:g></item> <item><xliff:g id="id">mute</xliff:g></item> <item><xliff:g id="id">speakerphone</xliff:g></item> - <item><xliff:g id="id">wifi</xliff:g></item> <item><xliff:g id="id">tty</xliff:g></item> <item><xliff:g id="id">bluetooth</xliff:g></item> <item><xliff:g id="id">gps</xliff:g></item> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 6d6c47f..8d4fa4e 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 86bfe94..1e007d36 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/core/tests/coretests/src/android/view/VelocityTest.java b/core/tests/coretests/src/android/view/VelocityTest.java new file mode 100644 index 0000000..fb28e1e --- /dev/null +++ b/core/tests/coretests/src/android/view/VelocityTest.java @@ -0,0 +1,285 @@ +/* + * 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.frameworktest.view; + +import junit.framework.Assert; + +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; + +/** + * Exercises {@link android.view.VelocityTracker} to compute correct velocity.<br> + * To launch this test, use :<br> + * <code>./development/testrunner/runtest.py framework -c com.android.frameworktest.view.VelocityTest</code> + */ +public class VelocityTest extends InstrumentationTestCase { + + @MediumTest + public void testInitialCondiditions() { + VelocityTracker vt = VelocityTracker.obtain(); + assertNotNull(vt); + vt.recycle(); + } + + /** + * Test that {@link android.view.VelocityTracker}.clear() clears + * the previous values after a call to computeCurrentVelocity() + */ + @MediumTest + public void testClear() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 300); + vt.computeCurrentVelocity(1); + assertFalse("Velocity should not be null", vt.getXVelocity() == 0.0f); + assertFalse("Velocity should not be null", vt.getYVelocity() == 0.0f); + vt.clear(); + vt.computeCurrentVelocity(1); + assertEquals(0.0f, vt.getXVelocity()); + assertEquals(0.0f, vt.getYVelocity()); + vt.recycle(); + } + + @MediumTest + public void testDragAcceleration () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 15, t, 400, new AccelerateInterpolator()); + vt.computeCurrentVelocity(1000); + assertGreater(250.0f, vt.getXVelocity()); + assertGreater(250.0f, vt.getYVelocity()); + vt.recycle(); + } + + @MediumTest + public void testDragDeceleration () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 15, t, 400, new DecelerateInterpolator()); + vt.computeCurrentVelocity(1000); + assertLower(250.0f, vt.getXVelocity()); + assertLower(250.0f, vt.getYVelocity()); + vt.recycle(); + } + + @MediumTest + public void testDragLinearHorizontal() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + // 100px in 400ms => 250px/s + drag(vt, 100, 200, 200, 200, 15, t, 400); + vt.computeCurrentVelocity(1000); + assertEquals(0.0f, vt.getYVelocity()); + assertEqualFuzzy(250.0f, vt.getXVelocity(), 4f); + vt.recycle(); + } + + @MediumTest + public void testDragLinearVertical() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + // 100px in 400ms => 250px/s + drag(vt, 200, 200, 100, 200, 15, t, 400); + vt.computeCurrentVelocity(1000); + assertEquals(0.0f, vt.getXVelocity()); + assertEqualFuzzy(250.0f, vt.getYVelocity(), 4f); + vt.recycle(); + } + + /** + * Test dragging with two points only + * (velocity must be an exact value) + */ + @MediumTest + public void testDragWith2Points () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + // 100px, 2 steps, 100ms => 1000px/s + drag(vt, 100, 200, 100, 200, 2, t, 100); + vt.computeCurrentVelocity(1000); + assertEquals(1000.0f, vt.getXVelocity()); + assertEquals(1000.0f, vt.getYVelocity()); + vt.recycle(); + } + + /** + * Velocity is independent of the number of points used during + * the same interval + */ + @MediumTest + public void testStabilityInNbPoints () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 400); // 10 steps over 400ms + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.clear(); + drag(vt, 100, 200, 100, 200, 20, t, 400); // 20 steps over 400ms + vt.computeCurrentVelocity(1); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEqualFuzzy(firstX, secondX, 0.1f); + assertEqualFuzzy(firstY, secondY, 0.1f); + vt.recycle(); + } + + /** + * Velocity is independent of the time when the events occurs, + * it only depends on delays between the events. + */ + @MediumTest + public void testStabilityInTime () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 400); + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.clear(); + drag(vt, 100, 200, 100, 200, 10, t + 3600*1000, 400); // on hour later + vt.computeCurrentVelocity(1); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEqualFuzzy(firstX, secondX, 0.1f); + assertEqualFuzzy(firstY, secondY, 0.1f); + vt.recycle(); + } + + /** + * Velocity is independent of the position of the events, + * it only depends on their relative distance. + */ + @MediumTest + public void testStabilityInSpace () { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 400); + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.clear(); + drag(vt, 200, 300, 200, 300, 10, t, 400); // 100px further + vt.computeCurrentVelocity(1); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEqualFuzzy(firstX, secondX, 0.1f); + assertEqualFuzzy(firstY, secondY, 0.1f); + vt.recycle(); + } + + /** + * Test that calls to {@link android.view.VelocityTracker}.computeCurrentVelocity() + * will output same values when using the same data. + */ + @MediumTest + public void testStabilityOfComputation() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 300); + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.computeCurrentVelocity(1); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEquals(firstX, secondX); + assertEquals(firstY, secondY); + vt.recycle(); + } + + /** + * Test the units parameter of {@link android.view.VelocityTracker}.computeCurrentVelocity() + */ + @MediumTest + public void testStabilityOfUnits() { + long t = System.currentTimeMillis(); + VelocityTracker vt = VelocityTracker.obtain(); + drag(vt, 100, 200, 100, 200, 10, t, 300); + vt.computeCurrentVelocity(1); + float firstX = vt.getXVelocity(); + float firstY = vt.getYVelocity(); + vt.computeCurrentVelocity(1000); + float secondX = vt.getXVelocity(); + float secondY = vt.getYVelocity(); + assertEqualFuzzy(firstX, secondX / 1000.0f, 0.1f); + assertEqualFuzzy(firstY, secondY / 1000.0f, 0.1f); + vt.recycle(); + } + + /** + * Simulate a drag by giving directly MotionEvents to + * the VelocityTracker using a linear interpolator + */ + private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps, + long startime, int duration) { + drag(vt, startX, endX, startY, endY, steps, startime, duration, new LinearInterpolator()); + } + + /** + * Simulate a drag by giving directly MotionEvents to + * the VelocityTracker using a given interpolator + */ + private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps, + long startime, int duration, Interpolator interpolator) { + addMotionEvent(vt, startX, startY, startime, MotionEvent.ACTION_DOWN); + float dt = duration / (float)steps; + int distX = endX - startX; + int distY = endY - startY; + for (int i=1; i<steps-1; i++) { + float ii = interpolator.getInterpolation(i / (float)steps); + int x = (int) (startX + distX * ii); + int y = (int) (startY + distY * ii); + long time = startime + (int) (i * dt); + addMotionEvent(vt, x, y, time, MotionEvent.ACTION_MOVE); + } + addMotionEvent(vt, endX, endY, startime + duration, MotionEvent.ACTION_UP); + } + + private void addMotionEvent(VelocityTracker vt, int x, int y, long time, int action) { + MotionEvent me = MotionEvent.obtain(time, time, action, x, y, 0); + vt.addMovement(me); + me.recycle(); + } + + /** + * Float imprecision of the average computations and filtering + * (removing last MotionEvent for N > 3) implies that tests + * accepts some approximated values. + */ + private void assertEqualFuzzy(float expected, float actual, float threshold) { + boolean fuzzyEqual = actual >= expected - threshold && actual <= expected + threshold; + Assert.assertTrue("Expected: <"+expected+"> but was: <"+actual+ + "> while accepting a variation of: <"+threshold+">", fuzzyEqual); + } + + private void assertGreater(float minExpected, float actual) { + Assert.assertTrue("Expected: minimum <"+minExpected+"> but was: <"+actual+">", + actual > minExpected); + } + + private void assertLower(float maxExpected, float actual) { + Assert.assertTrue("Expected: maximum <"+maxExpected+"> but was: <"+actual+">", + actual < maxExpected); + } +} diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java index 5cefaa3..a50693d 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 273d922..5f9f69c 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 571e47b..e81d0f9 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/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp index 3117495..85167da 100644 --- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp +++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp @@ -58,7 +58,7 @@ namespace android { // Must not be holding SurfaceComposerClient::mLock when acquiring gLock here. static Mutex gLock; static sp<ISurfaceComposer> gSurfaceManager; -static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections; +static DefaultKeyedVector< sp<IBinder>, wp<SurfaceComposerClient> > gActiveConnections; static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions; static sp<IMemoryHeap> gServerCblkMemory; static volatile surface_flinger_cblk_t* gServerCblk; @@ -195,7 +195,7 @@ SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn) { // scope for lock Mutex::Autolock _l(gLock); - client = gActiveConnections.valueFor(conn); + client = gActiveConnections.valueFor(conn).promote(); } if (client == 0) { @@ -383,8 +383,8 @@ void SurfaceComposerClient::openGlobalTransaction() const size_t N = gActiveConnections.size(); VERBOSE("openGlobalTransaction (%ld clients)", N); for (size_t i=0; i<N; i++) { - sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i)); - if (gOpenTransactions.indexOf(client) < 0) { + sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i).promote()); + if (client != 0 && gOpenTransactions.indexOf(client) < 0) { if (client->openTransaction() == NO_ERROR) { if (gOpenTransactions.add(client) < 0) { // Ooops! diff --git a/location/java/android/location/Address.java b/location/java/android/location/Address.java index ac275c6..b152f48 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 15d692c..fa53ccf 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 e8b89e0..8f6564a 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/media/libdrm/mobile2/Android.mk b/media/libdrm/mobile2/Android.mk index e187139..70c6683 100644 --- a/media/libdrm/mobile2/Android.mk +++ b/media/libdrm/mobile2/Android.mk @@ -74,6 +74,10 @@ LOCAL_MODULE := libdrm2 ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-x86) LOCAL_CFLAGS += -DUSTL_ANDROID_X86 +else + ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-sh) + LOCAL_CFLAGS += -DUSTL_ANDROID_SH + endif endif include $(BUILD_STATIC_LIBRARY) diff --git a/media/libdrm/mobile2/src/util/ustl-1.0/uutility.h b/media/libdrm/mobile2/src/util/ustl-1.0/uutility.h index 7b5ae64..2ee9a81 100644 --- a/media/libdrm/mobile2/src/util/ustl-1.0/uutility.h +++ b/media/libdrm/mobile2/src/util/ustl-1.0/uutility.h @@ -370,7 +370,7 @@ namespace simd { /// implicit casts to pointer from an integral type. Ironically, such an /// implicit cast is already detected by gcc. /// -#if defined(USTL_ANDROID_X86) +#if defined(USTL_ANDROID_X86) || defined(USTL_ANDROID_SH) #define OVERLOAD_POINTER_AND_SIZE_T_V2(name, arg1type) #else #define OVERLOAD_POINTER_AND_SIZE_T_V2(name, arg1type) \ diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 3e1f4a5..6a6afa1 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -758,7 +758,7 @@ player_type getPlayerType(const char* url) int len = strlen(FILE_EXTS[i].extension); int start = lenURL - len; if (start > 0) { - if (!strncmp(url + start, FILE_EXTS[i].extension, len)) { + if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) { if (FILE_EXTS[i].playertype == VORBIS_PLAYER && !strncasecmp(url, "http://", 7) && useStagefrightForHTTP) { diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 6cb146c..8abd649 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 9407bd5..d67612e 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 33b25ab..f031c79 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 1b4ba81..1019fa8 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 24526af..dc5fd30 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 0c205ca..5bf66e4 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 5ed19a2..df93215 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 53de7d9..be5cc7b 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 94d1cb4..3b0c436 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 ad7dfc9..2f7666d 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/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 32e7176..a60d2be 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -732,7 +732,8 @@ public class PhoneNumberUtils return ""; } - if ((bytes[offset] & 0xff) == TOA_International) { + //Only TON field should be taken in consideration + if ((bytes[offset] & 0xf0) == (TOA_International & 0xf0)) { prependPlus = true; } diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 6c66559..35a2c19 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -57,7 +57,7 @@ public class ServiceState implements Parcelable { public static final int STATE_EMERGENCY_ONLY = 2; /** - * Radio of telephony is explictly powered off. + * Radio of telephony is explicitly powered off. */ public static final int STATE_POWER_OFF = 3; @@ -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. @@ -218,7 +220,8 @@ public class ServiceState implements Parcelable { return 0; } - public static final Parcelable.Creator<ServiceState> CREATOR = new Parcelable.Creator() { + public static final Parcelable.Creator<ServiceState> CREATOR = + new Parcelable.Creator<ServiceState>() { public ServiceState createFromParcel(Parcel in) { return new ServiceState(in); } @@ -229,7 +232,7 @@ public class ServiceState implements Parcelable { }; /** - * Get current servcie state of phone + * Get current service state of phone * * @see #STATE_IN_SERVICE * @see #STATE_OUT_OF_SERVICE @@ -288,10 +291,10 @@ public class ServiceState implements Parcelable { } /** - * Get current registered operator name in long alphanumeric format + * Get current registered operator name in long alphanumeric format. * - * In GSM/UMTS, long format can be upto 16 characters long - * In CDMA, returns the ERI text, if set, otherwise the ONS + * In GSM/UMTS, long format can be up to 16 characters long. + * In CDMA, returns the ERI text, if set. Otherwise, returns the ONS. * * @return long name of operator, null if unregistered or unknown */ @@ -300,9 +303,9 @@ public class ServiceState implements Parcelable { } /** - * Get current registered operator name in short lphanumeric format + * Get current registered operator name in short alphanumeric format. * - * In GSM/UMST, short format can be upto 8 characters long + * In GSM/UMTS, short format can be up to 8 characters long. * * @return short name of operator, null if unregistered or unknown */ @@ -311,21 +314,23 @@ public class ServiceState implements Parcelable { } /** - * Get current registered operator numeric id + * 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() + * network code. * * @return numeric format of operator, null if unregistered or unknown */ + /* + * The country code can be decoded using + * {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}. + */ public String getOperatorNumeric() { return mOperatorNumeric; } /** - * Get current network selection mode + * Get current network selection mode. * * @return true if manual mode, false if automatic mode */ @@ -379,7 +384,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 +421,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; @@ -454,7 +461,7 @@ public class ServiceState implements Parcelable { mIsEmergencyOnly = false; } - // TODO - can't this be combined with the above func.. + // TODO - can't this be combined with the above method? public void setStateOff() { mState = STATE_POWER_OFF; mRoaming = false; @@ -524,8 +531,8 @@ public class ServiceState implements Parcelable { } /** - * In CDMA mOperatorAlphaLong can be set from the ERI - * text, this is done from the CDMAPhone and not from the CdmaServiceStateTracker + * In CDMA, mOperatorAlphaLong can be set from the ERI text. + * This is done from the CDMAPhone and not from the CdmaServiceStateTracker. * * @hide */ @@ -538,7 +545,7 @@ public class ServiceState implements Parcelable { } /** - * Test whether two objects hold the same data values or both are null + * Test whether two objects hold the same data values or both are null. * * @param a first obj * @param b second obj @@ -549,7 +556,7 @@ public class ServiceState implements Parcelable { } /** - * Set ServiceState based on intent notifier map + * Set ServiceState based on intent notifier map. * * @param m intent notifier map * @hide @@ -571,7 +578,7 @@ public class ServiceState implements Parcelable { } /** - * Set intent notifier Bundle based on service state + * Set intent notifier Bundle based on service state. * * @param m intent notifier Bundle * @hide diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 3122722..f5e9751 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 f018d10..ab63017 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/android/telephony/gsm/SmsManager.java b/telephony/java/android/telephony/gsm/SmsManager.java index 241c485..3b75298 100644 --- a/telephony/java/android/telephony/gsm/SmsManager.java +++ b/telephony/java/android/telephony/gsm/SmsManager.java @@ -56,7 +56,7 @@ import java.util.ArrayList; * 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. + * broadcast when the message is successfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, * or one of these errors: * <code>RESULT_ERROR_GENERIC_FAILURE</code> diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.java b/telephony/java/com/android/internal/telephony/AdnRecord.java index 0896ba6..1bf2d3c 100644 --- a/telephony/java/com/android/internal/telephony/AdnRecord.java +++ b/telephony/java/com/android/internal/telephony/AdnRecord.java @@ -19,10 +19,9 @@ package com.android.internal.telephony; import android.os.Parcel; import android.os.Parcelable; import android.telephony.PhoneNumberUtils; +import android.text.TextUtils; import android.util.Log; -import com.android.internal.telephony.GsmAlphabet; - import java.util.Arrays; @@ -38,8 +37,8 @@ public class AdnRecord implements Parcelable { //***** Instance Variables - String alphaTag = ""; - String number = ""; + String alphaTag = null; + String number = null; String[] emails; int extRecord = 0xff; int efid; // or 0 if none @@ -63,8 +62,8 @@ public class AdnRecord implements Parcelable { // ADN offset static final int ADN_BCD_NUMBER_LENGTH = 0; static final int ADN_TON_AND_NPI = 1; - static final int ADN_DAILING_NUMBER_START = 2; - static final int ADN_DAILING_NUMBER_END = 11; + static final int ADN_DIALING_NUMBER_START = 2; + static final int ADN_DIALING_NUMBER_END = 11; static final int ADN_CAPABILITY_ID = 12; static final int ADN_EXTENSION_ID = 13; @@ -152,17 +151,31 @@ public class AdnRecord implements Parcelable { } public boolean isEmpty() { - return alphaTag.equals("") && number.equals("") && emails == null; + return TextUtils.isEmpty(alphaTag) && TextUtils.isEmpty(number) && emails == null; } public boolean hasExtendedRecord() { return extRecord != 0 && extRecord != 0xff; } + /** Helper function for {@link #isEqual}. */ + private static boolean stringCompareNullEqualsEmpty(String s1, String s2) { + if (s1 == s2) { + return true; + } + if (s1 == null) { + s1 = ""; + } + if (s2 == null) { + s2 = ""; + } + return (s1.equals(s2)); + } + public boolean isEqual(AdnRecord adn) { - return ( alphaTag.equals(adn.getAlphaTag()) && - number.equals(adn.getNumber()) && - Arrays.equals(emails, adn.getEmails())); + return ( stringCompareNullEqualsEmpty(alphaTag, adn.alphaTag) && + stringCompareNullEqualsEmpty(number, adn.number) && + Arrays.equals(emails, adn.emails)); } //***** Parcelable Implementation @@ -184,36 +197,33 @@ public class AdnRecord implements Parcelable { * * @param recordSize is the size X of EF record * @return hex byte[recordSize] to be written to EF record - * return nulll for wrong format of dialing nubmer or tag + * return null for wrong format of dialing number or tag */ public byte[] buildAdnString(int recordSize) { byte[] bcdNumber; byte[] byteTag; - byte[] adnString = null; + byte[] adnString; int footerOffset = recordSize - FOOTER_SIZE_BYTES; - if (number == null || number.equals("") || - alphaTag == null || alphaTag.equals("")) { + // create an empty record + adnString = new byte[recordSize]; + for (int i = 0; i < recordSize; i++) { + adnString[i] = (byte) 0xFF; + } - Log.w(LOG_TAG, "[buildAdnString] Empty alpha tag or number"); - adnString = new byte[recordSize]; - for (int i = 0; i < recordSize; i++) { - adnString[i] = (byte) 0xFF; - } + if (TextUtils.isEmpty(number)) { + Log.w(LOG_TAG, "[buildAdnString] Empty dialing number"); + return adnString; // return the empty record (for delete) } else if (number.length() - > (ADN_DAILING_NUMBER_END - ADN_DAILING_NUMBER_START + 1) * 2) { + > (ADN_DIALING_NUMBER_END - ADN_DIALING_NUMBER_START + 1) * 2) { Log.w(LOG_TAG, - "[buildAdnString] Max length of dailing number is 20"); - } else if (alphaTag.length() > footerOffset) { + "[buildAdnString] Max length of dialing number is 20"); + return null; + } else if (alphaTag != null && alphaTag.length() > footerOffset) { Log.w(LOG_TAG, "[buildAdnString] Max length of tag is " + footerOffset); + return null; } else { - - adnString = new byte[recordSize]; - for (int i = 0; i < recordSize; i++) { - adnString[i] = (byte) 0xFF; - } - bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(number); System.arraycopy(bcdNumber, 0, adnString, @@ -222,16 +232,17 @@ public class AdnRecord implements Parcelable { adnString[footerOffset + ADN_BCD_NUMBER_LENGTH] = (byte) (bcdNumber.length); adnString[footerOffset + ADN_CAPABILITY_ID] - = (byte) 0xFF; // Capacility Id + = (byte) 0xFF; // Capability Id adnString[footerOffset + ADN_EXTENSION_ID] = (byte) 0xFF; // Extension Record Id - byteTag = GsmAlphabet.stringToGsm8BitPacked(alphaTag); - System.arraycopy(byteTag, 0, adnString, 0, byteTag.length); + if (!TextUtils.isEmpty(alphaTag)) { + byteTag = GsmAlphabet.stringToGsm8BitPacked(alphaTag); + System.arraycopy(byteTag, 0, adnString, 0, byteTag.length); + } + return adnString; } - - return adnString; } /** diff --git a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java b/telephony/java/com/android/internal/telephony/AdnRecordLoader.java index cfb5aaa..55bdc06 100644 --- a/telephony/java/com/android/internal/telephony/AdnRecordLoader.java +++ b/telephony/java/com/android/internal/telephony/AdnRecordLoader.java @@ -106,7 +106,7 @@ public class AdnRecordLoader extends Handler { * It will get the record size of EF record and compose hex adn array * then write the hex array to EF record * - * @param adn is set with alphaTag and phoneNubmer + * @param adn is set with alphaTag and phone number * @param ef EF fileid * @param extensionEF extension EF fileid * @param recordNumber 1-based record index @@ -159,7 +159,7 @@ public class AdnRecordLoader extends Handler { data = adn.buildAdnString(recordSize[0]); if(data == null) { - throw new RuntimeException("worong ADN format", + throw new RuntimeException("wrong ADN format", ar.exception); } @@ -218,7 +218,7 @@ public class AdnRecordLoader extends Handler { throw new RuntimeException("load failed", ar.exception); } - Log.d(LOG_TAG,"ADN extention EF: 0x" + Log.d(LOG_TAG,"ADN extension EF: 0x" + Integer.toHexString(extensionEF) + ":" + adn.extRecord + "\n" + IccUtils.bytesToHexString(data)); diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java index 802e79b..798a5a5 100644 --- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java +++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java @@ -284,7 +284,7 @@ public class CallerInfoAsyncQuery { */ public static CallerInfoAsyncQuery startQuery(int token, Context context, String number, OnQueryCompleteListener listener, Object cookie) { - //contruct the URI object and start Query. + //construct the URI object and start Query. Uri contactRef = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); CallerInfoAsyncQuery c = new CallerInfoAsyncQuery(); diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java index eb0a440..94c544e 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 d90c305..8e03c5a 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 37e8a99..11d0b1b 100644 --- a/telephony/java/com/android/internal/telephony/Connection.java +++ b/telephony/java/com/android/internal/telephony/Connection.java @@ -45,17 +45,18 @@ public abstract class Connection { POWER_OFF, /* radio is turned off explicitly */ OUT_OF_SERVICE, /* out of service */ ICC_ERROR, /* No ICC, ICC locked, or other ICC error */ - CALL_BARRED, /* call was blocked by call barrring */ + CALL_BARRED, /* call was blocked by call barring */ FDN_BLOCKED, /* call was blocked by fixed dial number */ CS_RESTRICTED, /* call was blocked by restricted all voice access */ CS_RESTRICTED_NORMAL, /* call was blocked by restricted normal voice access */ CS_RESTRICTED_EMERGENCY, /* call was blocked by restricted emergency voice access */ + UNOBTAINABLE_NUMBER, /* Unassigned number (3GPP TS 24.008 table 10.5.123) */ CDMA_LOCKED_UNTIL_POWER_CYCLE, /* MS is locked until next power cycle */ CDMA_DROP, CDMA_INTERCEPT, /* INTERCEPT order received, MS state idle entered */ CDMA_REORDER, /* MS has been redirected, call is cancelled */ CDMA_SO_REJECT, /* service option rejection */ - CDMA_RETRY_ORDER, /* requeseted service is rejected, retry delay is set */ + CDMA_RETRY_ORDER, /* requested service is rejected, retry delay is set */ CDMA_ACCESS_FAILURE, CDMA_PREEMPTED, CDMA_NOT_EMERGENCY, /* not an emergency call */ @@ -68,8 +69,8 @@ public abstract class Connection { /* Instance Methods */ /** - * Gets address (e.g., phone number) associated with connection - * TODO: distinguish reasons for unavailablity + * Gets address (e.g. phone number) associated with connection. + * TODO: distinguish reasons for unavailability * * @return address or null if unavailable */ @@ -77,7 +78,7 @@ public abstract class Connection { public abstract String getAddress(); /** - * Gets cdma CNAP name associated with connection + * Gets CDMA CNAP name associated with connection. * @return cnap name or null if unavailable */ public String getCnapName() { @@ -85,15 +86,15 @@ public abstract class Connection { } /** - * Get orignal dial string - * @return orignal dial string or null if unavailable + * Get original dial string. + * @return original dial string or null if unavailable */ public String getOrigDialString(){ return null; } /** - * Gets cdma CNAP presentation associated with connection + * Gets CDMA CNAP presentation associated with connection. * @return cnap name or null if unavailable */ @@ -115,45 +116,45 @@ public abstract class Connection { public abstract long getCreateTime(); /** - * Connection connect time in currentTimeMillis() format - * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition - * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition - * Returns 0 before then + * Connection connect time in currentTimeMillis() format. + * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. + * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. + * Returns 0 before then. */ public abstract long getConnectTime(); /** - * Disconnect time in currentTimeMillis() format - * The time when this Connection makes a transition into ENDED or FAIL - * Returns 0 before then + * Disconnect time in currentTimeMillis() format. + * The time when this Connection makes a transition into ENDED or FAIL. + * Returns 0 before then. */ public abstract long getDisconnectTime(); /** - * returns the number of milliseconds the call has been connected, + * Returns the number of milliseconds the call has been connected, * or 0 if the call has never connected. * If the call is still connected, then returns the elapsed - * time since connect + * time since connect. */ public abstract long getDurationMillis(); /** * If this connection is HOLDING, return the number of milliseconds - * that it has been on hold for (approximently) - * If this connection is in any other state, return 0 + * that it has been on hold for (approximately). + * If this connection is in any other state, return 0. */ public abstract long getHoldDurationMillis(); /** - * Returns "NOT_DISCONNECTED" if not yet disconnected + * Returns "NOT_DISCONNECTED" if not yet disconnected. */ public abstract DisconnectCause getDisconnectCause(); /** * Returns true of this connection originated elsewhere * ("MT" or mobile terminated; another party called this terminal) - * or false if this call originated here (MO or mobile originated) + * or false if this call originated here (MO or mobile originated). */ public abstract boolean isIncoming(); @@ -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/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java index 1f8bbcf..6634017 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -164,7 +164,7 @@ public abstract class DataConnection extends HierarchicalStateMachine { NONE, OPERATOR_BARRED, INSUFFICIENT_RESOURCES, - MISSING_UKNOWN_APN, + MISSING_UNKNOWN_APN, UNKNOWN_PDP_ADDRESS, USER_AUTHENTICATION, ACTIVATION_REJECT_GGSN, @@ -181,7 +181,7 @@ public abstract class DataConnection extends HierarchicalStateMachine { RADIO_NOT_AVAILABLE; public boolean isPermanentFail() { - return (this == OPERATOR_BARRED) || (this == MISSING_UKNOWN_APN) || + return (this == OPERATOR_BARRED) || (this == MISSING_UNKNOWN_APN) || (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) || (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) || (this == SERVICE_OPTION_NOT_SUPPORTED) || @@ -208,12 +208,12 @@ public abstract class DataConnection extends HierarchicalStateMachine { return "Operator Barred"; case INSUFFICIENT_RESOURCES: return "Insufficient Resources"; - case MISSING_UKNOWN_APN: + case MISSING_UNKNOWN_APN: return "Missing / Unknown APN"; case UNKNOWN_PDP_ADDRESS: return "Unknown PDP Address"; case USER_AUTHENTICATION: - return "Error User Autentication"; + return "Error User Authentication"; case ACTIVATION_REJECT_GGSN: return "Activation Reject GGSN"; case ACTIVATION_REJECT_UNSPECIFIED: diff --git a/telephony/java/com/android/internal/telephony/DriverCall.java b/telephony/java/com/android/internal/telephony/DriverCall.java index 66f6b9c..663c284 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/IccProvider.java b/telephony/java/com/android/internal/telephony/IccProvider.java index fa91457..3471ec2 100644 --- a/telephony/java/com/android/internal/telephony/IccProvider.java +++ b/telephony/java/com/android/internal/telephony/IccProvider.java @@ -417,11 +417,11 @@ public class IccProvider extends ContentProvider { } } - if (TextUtils.isEmpty(tag)) { + if (TextUtils.isEmpty(number)) { return 0; } - if (efType == FDN && TextUtils.isEmpty(pin2)) { + if (efType == IccConstants.EF_FDN && TextUtils.isEmpty(pin2)) { return 0; } diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java index 7179bef..23325f6 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -243,15 +243,14 @@ public interface Phone { /** * Get the current DataState. No change notification exists at this * interface -- use - * {@link com.android.telephony.PhoneStateListener PhoneStateListener} - * instead. + * {@link android.telephony.PhoneStateListener} instead. */ DataState getDataConnectionState(); /** * Get the current DataActivityState. No change notification exists at this * interface -- use - * {@link TelephonyManager} instead. + * {@link android.telephony.TelephonyManager} instead. */ DataActivityState getDataActivityState(); @@ -789,6 +788,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). * @@ -840,7 +852,7 @@ public interface Phone { * @param dtmfString is string representing the dialing digit(s) in the active call * @param on the DTMF ON length in milliseconds, or 0 for default * @param off the DTMF OFF length in milliseconds, or 0 for default - * @param onCompelte is the callback message when the action is processed by BP + * @param onComplete is the callback message when the action is processed by BP * */ void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete); @@ -980,7 +992,7 @@ public interface Phone { * ((AsyncResult)onComplete.obj) is an array of int, with a length of 2. * * @param onComplete a callback message when the action is completed. - * @see com.android.internal.telephony.CommandsInterface.getCLIR for details. + * @see com.android.internal.telephony.CommandsInterface#getCLIR for details. */ void getOutgoingCallerIdDisplay(Message onComplete); @@ -1002,7 +1014,7 @@ public interface Phone { * ((AsyncResult)onComplete.obj) is an array of int, with a length of 1. * * @param onComplete a callback message when the action is completed. - * @see com.android.internal.telephony.CommandsInterface.queryCallWaiting for details. + * @see com.android.internal.telephony.CommandsInterface#queryCallWaiting for details. */ void getCallWaiting(Message onComplete); @@ -1445,7 +1457,7 @@ public interface Phone { * setTTYMode * sets a TTY mode option. * - * @param enable is a boolean representing the state that you are + * @param ttyMode is a boolean representing the state that you are * requesting, true for enabled, false for disabled. * @param onComplete a callback message when the action is completed */ diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java index a8f4143..74601e6 100644 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ b/telephony/java/com/android/internal/telephony/PhoneBase.java @@ -543,7 +543,7 @@ public abstract class PhoneBase extends Handler implements Phone { private void setPropertiesByCarrier() { String carrier = SystemProperties.get("ro.carrier"); - if (null == carrier || 0 == carrier.length()) { + if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { return; } diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java index cd72752..803b736 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 6d3798e..e1511e6 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/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java index 1ac2da3..4f71bb1 100644 --- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java +++ b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java @@ -65,7 +65,7 @@ public class PhoneSubInfo extends IPhoneSubInfo.Stub { } /** - * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones. + * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones. */ public String getSubscriberId() { mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java index adfbe20..202ded2 100644 --- a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java @@ -47,7 +47,7 @@ public class PhoneSubInfoProxy extends IPhoneSubInfo.Stub { } /** - * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones. + * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones. */ public String getSubscriberId() { return mPhoneSubInfo.getSubscriberId(); diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index d8e313a..3d410fd 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 01f4ab2..71a80e0 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/RetryManager.java b/telephony/java/com/android/internal/telephony/RetryManager.java index 779f358..b1049a2 100644 --- a/telephony/java/com/android/internal/telephony/RetryManager.java +++ b/telephony/java/com/android/internal/telephony/RetryManager.java @@ -25,7 +25,7 @@ import java.util.ArrayList; /** * Retry manager allows a simple way to declare a series of - * retires timeouts. After creating a RetryManager the configure + * retry timeouts. After creating a RetryManager the configure * method is used to define the sequence. A simple linear series * may be initialized using configure with three integer parameters * The other configure method allows a series to be declared using @@ -54,18 +54,18 @@ import java.util.ArrayList; *<p> * Examples: * <ul> - * <li>3 retires with no randomization value which means its 0: + * <li>3 retries with no randomization value which means its 0: * <ul><li><code>"1000, 2000, 3000"</code></ul> * - * <li>10 retires with a 500 default randomization value for each and + * <li>10 retries with a 500 default randomization value for each and * the 4..10 retries all using 3000 as the delay: * <ul><li><code>"max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul> * - * <li>4 retires with a 100 as the default randomization value for the first 2 values and + * <li>4 retries with a 100 as the default randomization value for the first 2 values and * the other two having specified values of 500: * <ul><li><code>"default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul> * - * <li>Infinite number of retires with the first one at 1000, the second at 2000 all + * <li>Infinite number of retries with the first one at 1000, the second at 2000 all * others will be at 3000. * <ul><li><code>"max_retries=infinite,1000,2000,3000</code></ul> * </ul> @@ -75,9 +75,6 @@ import java.util.ArrayList; public class RetryManager { static public final String LOG_TAG = "RetryManager"; static public final boolean DBG = false; - static public final int RETRYIES_NOT_STARTED = 0; - static public final int RETRYIES_ON_GOING = 1; - static public final int RETRYIES_COMPLETED = 2; /** * Retry record with times in milli-seconds @@ -104,7 +101,7 @@ public class RetryManager { */ private int mMaxRetryCount; - /** The current number of retires */ + /** The current number of retries */ private int mRetryCount; /** Random number generator */ @@ -125,7 +122,7 @@ public class RetryManager { * @param randomizationTime a random value between 0 and * randomizationTime will be added to retryTime. this * parameter may be 0. - * @return true if successfull + * @return true if successful */ public boolean configure(int maxRetryCount, int retryTime, int randomizationTime) { Pair<Boolean, Integer> value; @@ -242,7 +239,7 @@ public class RetryManager { /** * Report whether data reconnection should be retried * - * @return {@code true} if the max retires has not been reached. {@code + * @return {@code true} if the max retries has not been reached. {@code * false} otherwise. */ public boolean isRetryNeeded() { @@ -289,7 +286,7 @@ public class RetryManager { if (mRetryCount > mMaxRetryCount) { mRetryCount = mMaxRetryCount; } - if (DBG) log("increseRetryCount: " + mRetryCount); + if (DBG) log("increaseRetryCount: " + mRetryCount); } /** diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index 764d12e..ca526a5 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 7383649..e8bbe5e 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; @@ -206,8 +207,8 @@ public abstract class ServiceStateTracker extends Handler { } /** - * Reregister network through toggle perferred network type - * This is a work aorund to deregister and register network since there is + * Re-register network by toggling preferred network type. + * This is a work-around to deregister and register network since there is * no ril api to set COPS=2 (deregister) only. * * @param onComplete is dispatched when this is complete. it will be @@ -229,7 +230,7 @@ public abstract class ServiceStateTracker extends Handler { /** * These two flags manage the behavior of the cell lock -- the * lock should be held if either flag is true. The intention is - * to allow temporary aquisition of the lock to get a single + * to allow temporary acquisition of the lock to get a single * update. Such a lock grab and release can thus be made to not * interfere with more permanent lock holds -- in other words, the * lock will only be released if both flags are false, and so 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 0000000..801b845 --- /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 1f5accf..0c591e4 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/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java index 1005d20..3669e60 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java @@ -61,7 +61,7 @@ public final class CdmaCallTracker extends CallTracker { RegistrantList callWaitingRegistrants = new RegistrantList(); - // connections dropped durin last poll + // connections dropped during last poll ArrayList<CdmaConnection> droppedDuringPoll = new ArrayList<CdmaConnection>(MAX_CONNECTIONS); diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java index 188145b..fbe455e 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/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 217e1e8..9f2a44b 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -114,7 +114,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { // if we have no active Apn this is null protected ApnSetting mActiveApn; - // Possibly promoate to base class, the only difference is + // Possibly promote to base class, the only difference is // the INTENT_RECONNECT_ALARM action is a different string. // Do consider technology changes if it is promoted. BroadcastReceiver mIntentReceiver = new BroadcastReceiver () @@ -420,7 +420,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { CdmaDataConnection conn = findFreeDataConnection(); if (conn == null) { - if (DBG) log("setupData: No free CdmaDataConnectionfound!"); + if (DBG) log("setupData: No free CdmaDataConnection found!"); return false; } @@ -646,7 +646,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } /** - * @override com.android.intenral.telephony.DataConnectionTracker + * @override com.android.internal.telephony.DataConnectionTracker */ @Override protected void onEnableNewApn() { 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 0000000..8dd8c2e --- /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 39fe007..2cad6cc 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -66,7 +66,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { CdmaCellLocation cellLoc; CdmaCellLocation newCellLoc; - /** if time between NTIZ updates is less than mNitzUpdateSpacing the update may be ignored. */ + /** if time between NITZ updates is less than mNitzUpdateSpacing the update may be ignored. */ private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10; private int mNitzUpdateSpacing = SystemProperties.getInt("ro.nitz_update_spacing", NITZ_UPDATE_SPACING_DEFAULT); @@ -395,7 +395,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { } // Release any temporary cell lock, which could have been - // aquired to allow a single-shot location update. + // acquired to allow a single-shot location update. disableSingleLocationUpdate(); break; @@ -591,7 +591,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { boolean showPlmn = false; int rule = 0; if (cm.getRadioState().isRUIMReady()) { - // TODO RUIM SPN is not implemnted, EF_SPN has to be read and Display Condition + // TODO RUIM SPN is not implemented, EF_SPN has to be read and Display Condition // Character Encoding, Language Indicator and SPN has to be set // rule = phone.mRuimRecords.getDisplayRule(ss.getOperatorNumeric()); // spn = phone.mSIMRecords.getServiceProvideName(); @@ -872,7 +872,6 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { * and start over again if the radio notifies us that some * event has changed */ - private void pollState() { pollingContext = new int[1]; @@ -945,6 +944,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 +1239,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: @@ -1256,7 +1259,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { return ServiceState.STATE_IN_SERVICE; case 2: // 2 is "searching", fall through case 3: // 3 is "registration denied", fall through - case 4: // 4 is "unknown" no vaild in current baseband + case 4: // 4 is "unknown", not valid in current baseband return ServiceState.STATE_OUT_OF_SERVICE; case 5:// 5 is "Registered, roaming" return ServiceState.STATE_IN_SERVICE; @@ -1295,12 +1298,12 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { */ private boolean isRoamIndForHomeSystem(String roamInd) { // retrieve the carrier-specified list of ERIs for home system - String homeRoamIndcators = SystemProperties.get("ro.cdma.homesystem"); + String homeRoamIndicators = SystemProperties.get("ro.cdma.homesystem"); - if (!TextUtils.isEmpty(homeRoamIndcators)) { + if (!TextUtils.isEmpty(homeRoamIndicators)) { // searches through the comma-separated list for a match, // return true if one is found. - for (String homeRoamInd : homeRoamIndcators.split(",")) { + for (String homeRoamInd : homeRoamIndicators.split(",")) { if (homeRoamInd.equals(roamInd)) { return true; } diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 403b7a1..b50502c 100755 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -313,7 +313,7 @@ public class SmsMessage extends SmsMessageBase { } /** - * Get an SMS-SUBMIT PDU for a data message to a destination address & port + * Get an SMS-SUBMIT PDU for a data message to a destination address and port. * * @param scAddr Service Centre address. null == use default * @param destAddr the address of the destination for the message diff --git a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java b/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java index 3813b1d..4907aa9 100644 --- a/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java +++ b/telephony/java/com/android/internal/telephony/cdma/TtyIntent.java @@ -56,10 +56,10 @@ public class TtyIntent { /** * The lookup key for an int that indicates preferred TTY mode. * Valid modes are: - * - {@link Phone.TTY_MODE_OFF} - * - {@link Phone.TTY_MODE_FULL} - * - {@link Phone.TTY_MODE_HCO} - * - {@link Phone.TTY_MODE_VCO} + * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} + * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} + * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} + * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} * * {@hide} */ diff --git a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java index e7fbf6b..af2ad48 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 2bb7968..c7b1e5c 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 87530e4..06f310c 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; @@ -65,7 +66,7 @@ public final class GsmCallTracker extends CallTracker { RegistrantList voiceCallStartedRegistrants = new RegistrantList(); - // connections dropped durin last poll + // connections dropped during last poll ArrayList<GsmConnection> droppedDuringPoll = new ArrayList<GsmConnection>(MAX_CONNECTIONS); @@ -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 4788a01..7dc2504 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/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java index d893ec4..09d46dd 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java @@ -134,7 +134,7 @@ public class GsmDataConnection extends DataConnection { cause = FailCause.INSUFFICIENT_RESOURCES; break; case PDP_FAIL_MISSING_UKNOWN_APN: - cause = FailCause.MISSING_UKNOWN_APN; + cause = FailCause.MISSING_UNKNOWN_APN; break; case PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE: cause = FailCause.UNKNOWN_PDP_ADDRESS; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index cbfb550..9bc0b26 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -45,7 +45,6 @@ import android.provider.Telephony; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; -import android.text.TextUtils; import android.util.EventLog; import android.util.Log; @@ -150,9 +149,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { static final String APN_ID = "apn_id"; private boolean canSetPreferApn = false; - // for tracking retrys on the default APN + // for tracking retries on the default APN private RetryManager mDefaultRetryManager; - // for tracking retrys on a secondary APN + // for tracking retries on a secondary APN private RetryManager mSecondaryRetryManager; BroadcastReceiver mIntentReceiver = new BroadcastReceiver () @@ -189,8 +188,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; if (!enabled) { - // when wifi got disabeled, the NETWORK_STATE_CHANGED_ACTION - // quit and wont report disconnected til next enalbing. + // when wifi got disabled, the NETWORK_STATE_CHANGED_ACTION + // quit and won't report disconnected til next enabling. mIsWifiConnected = false; } } @@ -447,7 +446,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { waitingApns = buildWaitingApns(); if (waitingApns.isEmpty()) { if (DBG) log("No APN found"); - notifyNoData(GsmDataConnection.FailCause.MISSING_UKNOWN_APN); + notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN); return false; } else { log ("Create from allApns : " + apnListToString(allApns)); @@ -1125,7 +1124,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { SystemProperties.set("gsm.defaultpdpcontext.active", "true"); if (canSetPreferApn && preferredApn == null) { - Log.d(LOG_TAG, "PREFERED APN is null"); + Log.d(LOG_TAG, "PREFERRED APN is null"); preferredApn = mActiveApn; setPreferredApn(preferredApn.id); } @@ -1275,7 +1274,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (allApns.isEmpty()) { if (DBG) log("No APN found for carrier: " + operator); preferredApn = null; - notifyNoData(GsmDataConnection.FailCause.MISSING_UKNOWN_APN); + notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN); } else { preferredApn = getPreferredApn(); Log.d(LOG_TAG, "Get PreferredAPN"); diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java index bcbd127..aa16fa3 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java @@ -39,7 +39,7 @@ import java.util.regex.Matcher; * {@hide} * */ -public final class GsmMmiCode extends Handler implements MmiCode { +public final class GsmMmiCode extends Handler implements MmiCode { static final String LOG_TAG = "GSM"; //***** Constants @@ -51,7 +51,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { static final String ACTION_REGISTER = "**"; static final String ACTION_ERASURE = "##"; - // Supp Service cocdes from TS 22.030 Annex B + // Supp Service codes from TS 22.030 Annex B //Called line presentation static final String SC_CLIP = "30"; @@ -154,7 +154,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { /** * Some dial strings in GSM are defined to do non-call setup - * things, such as modify or query supplementry service settings (eg, call + * things, such as modify or query supplementary service settings (eg, call * forwarding). These are generally referred to as "MMI codes". * We look to see if the dial string contains a valid MMI code (potentially * with a dial string at the end as well) and return info here. @@ -457,12 +457,13 @@ public final class GsmMmiCode extends Handler implements MmiCode { && !PhoneNumberUtils.isEmergencyNumber(dialString) && (phone.isInCall() || !((dialString.length() == 2 && dialString.charAt(0) == '1') - /* While contrary to TS 22.030, there is strong precendence + /* While contrary to TS 22.030, there is strong precedence * for treating "0" and "00" as call setup strings. */ || dialString.equals("0") || dialString.equals("00")))); } + /** * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related */ @@ -472,13 +473,12 @@ public final class GsmMmiCode extends Handler implements MmiCode { } /** - * *See TS 22.030 Annex B + * See TS 22.030 Annex B. * In temporary mode, to suppress CLIR for a single call, enter: - * " * 31 # <called number> SEND " + * " * 31 # [called number] SEND " * In temporary mode, to invoke CLIR for a single call enter: - * " # 31 # <called number> SEND " + * " # 31 # [called number] SEND " */ - boolean isTemporaryModeCLIR() { return sc != null && sc.equals(SC_CLIR) && dialingNumber != null @@ -779,7 +779,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { // Note that unlike most everything else, the USSD complete // response does not complete this MMI code...we wait for // an unsolicited USSD "Notify" or "Request". - // The matching up of this is doene in GSMPhone. + // The matching up of this is done in GSMPhone. phone.mCM.sendUSSD(ussdMessage, obtainMessage(EVENT_USSD_COMPLETE, this)); @@ -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[]; @@ -1141,7 +1156,7 @@ public final class GsmMmiCode extends Handler implements MmiCode { // Each bit in the service class gets its own result line // The service classes may be split up over multiple - // CallForwardInfos. So, for each service classs, find out + // CallForwardInfos. So, for each service class, find out // which CallForwardInfo represents it and then build // the response text based on that @@ -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 6ae316d..d720516 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/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index 50b8eba..d539f6f 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -40,7 +40,6 @@ import android.provider.Settings.SettingNotFoundException; import android.provider.Telephony.Intents; import android.telephony.ServiceState; import android.telephony.SignalStrength; -import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.util.Config; @@ -130,7 +129,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { */ private boolean mNeedToRegForSimLoaded; - /** Started the recheck process after finding gprs should registerd but not. */ + /** Started the recheck process after finding gprs should registered but not. */ private boolean mStartedGprsRegCheck = false; /** Already sent the event-log for no gprs register. */ @@ -415,7 +414,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } // Release any temporary cell lock, which could have been - // aquired to allow a single-shot location update. + // acquired to allow a single-shot location update. disableSingleLocationUpdate(); break; @@ -500,9 +499,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker { break; case EVENT_CHECK_REPORT_GPRS: - if (ss != null && !isGprsConsistant(gprsState, ss.getState())) { + if (ss != null && !isGprsConsistent(gprsState, ss.getState())) { - // Can't register data sevice while voice service is ok + // Can't register data service while voice service is ok // i.e. CREG is ok while CGREG is not // possible a network or baseband side error GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); @@ -1027,7 +1026,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { phone.notifyLocationChanged(); } - if (! isGprsConsistant(gprsState, ss.getState())) { + if (! isGprsConsistent(gprsState, ss.getState())) { if (!mStartedGprsRegCheck && !mReportedGprsNoReg) { mStartedGprsRegCheck = true; @@ -1044,13 +1043,13 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } /** - * Check if GPRS got registred while voice is registered + * Check if GPRS got registered while voice is registered. * * @param gprsState for GPRS registration state, i.e. CGREG in GSM * @param serviceState for voice registration state, i.e. CREG in GSM * @return false if device only register to voice but not gprs */ - private boolean isGprsConsistant (int gprsState, int serviceState) { + private boolean isGprsConsistent(int gprsState, int serviceState) { return !((serviceState == ServiceState.STATE_IN_SERVICE) && (gprsState != ServiceState.STATE_IN_SERVICE)); } @@ -1105,13 +1104,13 @@ final class GsmServiceStateTracker extends ServiceStateTracker { long nextTime; - // TODO Done't poll signal strength if screen is off + // TODO Don't poll signal strength if screen is off sendMessageDelayed(msg, POLL_PERIOD_MILLIS); } /** - * send signal-strength-changed notification if changed - * Called both for solicited and unsolicited signal stength updates + * Send signal-strength-changed notification if changed. + * Called both for solicited and unsolicited signal strength updates. */ private void onSignalStrengthResult(AsyncResult ar) { SignalStrength oldSignalStrength = mSignalStrength; @@ -1332,7 +1331,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { /** * @return true if phone is camping on a technology (eg UMTS) - * that could support voice and data simultaniously. + * that could support voice and data simultaneously. */ boolean isConcurrentVoiceAndData() { return (networkType >= DATA_ACCESS_UMTS); diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java index d627baf..12c6b88 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 11b3fd6..a120f52 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/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java index 02590d3..dd2cb08 100644 --- a/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java +++ b/telephony/tests/telephonytests/src/android/telephony/PhoneNumberUtilsTest.java @@ -82,6 +82,16 @@ public class PhoneNumberUtilsTest extends TestCase { assertEquals("17005550020", PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); + b[0] = (byte) 0x80; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; + b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; + assertEquals("17005550020", + PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); + + b[0] = (byte) 0x90; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; + b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; + assertEquals("+17005550020", + PhoneNumberUtils.calledPartyBCDToString(b, 0, 7)); + b[0] = (byte) 0x91; b[1] = (byte) 0x71; b[2] = (byte) 0x00; b[3] = (byte) 0x55; b[4] = (byte) 0x05; b[5] = (byte) 0x20; b[6] = (byte) 0xF0; assertEquals("+17005550020", diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java index f548145..e7a09d1 100644 --- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java +++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java @@ -205,6 +205,8 @@ public class NotificationTestList extends TestActivity Notification n = new Notification(); n.flags |= Notification.FLAG_SHOW_LIGHTS; n.ledARGB = 0xff0000ff; + n.ledOnMS = 1; + n.ledOffMS = 0; mNM.notify(1, n); } }, @@ -215,6 +217,8 @@ public class NotificationTestList extends TestActivity Notification n = new Notification(); n.flags |= Notification.FLAG_SHOW_LIGHTS; n.ledARGB = 0xffff0000; + n.ledOnMS = 1; + n.ledOffMS = 0; mNM.notify(1, n); } }, @@ -225,6 +229,20 @@ public class NotificationTestList extends TestActivity Notification n = new Notification(); n.flags |= Notification.FLAG_SHOW_LIGHTS; n.ledARGB = 0xffffff00; + n.ledOnMS = 1; + n.ledOffMS = 0; + mNM.notify(1, n); + } + }, + + new Test("Lights off") { + public void run() + { + Notification n = new Notification(); + n.flags |= Notification.FLAG_SHOW_LIGHTS; + n.ledARGB = 0x00000000; + n.ledOnMS = 0; + n.ledOffMS = 0; mNM.notify(1, n); } }, @@ -234,7 +252,7 @@ public class NotificationTestList extends TestActivity { Notification n = new Notification(); n.flags |= Notification.FLAG_SHOW_LIGHTS; - n.ledARGB = 0xffffff00; + n.ledARGB = 0xff0000ff; n.ledOnMS = 1300; n.ledOffMS = 1300; mNM.notify(1, n); @@ -246,7 +264,7 @@ public class NotificationTestList extends TestActivity { Notification n = new Notification(); n.flags |= Notification.FLAG_SHOW_LIGHTS; - n.ledARGB = 0xffffff00; + n.ledARGB = 0xff0000ff; n.ledOnMS = 300; n.ledOffMS = 300; mNM.notify(1, n); diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp index fc658f5..f17f66b 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; } |