diff options
68 files changed, 1136 insertions, 627 deletions
diff --git a/api/current.xml b/api/current.xml index b1e9c83..1f53be9 100644 --- a/api/current.xml +++ b/api/current.xml @@ -35725,39 +35725,6 @@ visibility="public" > </field> -<field name="ACTION_TTS_CHECK_TTS_DATA" - type="java.lang.String" - transient="false" - volatile="false" - value=""android.intent.action.CHECK_TTS_DATA"" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> -<field name="ACTION_TTS_INSTALL_TTS_DATA" - type="java.lang.String" - transient="false" - volatile="false" - value=""android.intent.action.INSTALL_TTS_DATA"" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> -<field name="ACTION_TTS_QUEUE_PROCESSING_COMPLETED" - type="java.lang.String" - transient="false" - volatile="false" - value=""android.intent.action.TTS_QUEUE_PROCESSING_COMPLETED"" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> <field name="ACTION_UID_REMOVED" type="java.lang.String" transient="false" @@ -84350,6 +84317,19 @@ visibility="public" > </method> +<method name="setReferenceCounted" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="refCounted" type="boolean"> +</parameter> +</method> </class> <class name="WifiManager.WifiLock" extends="java.lang.Object" @@ -116289,7 +116269,18 @@ <parameter name="filename" type="java.lang.String"> </parameter> </method> -<field name="TTS_ERROR" +<field name="ACTION_TTS_QUEUE_PROCESSING_COMPLETED" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="ERROR" type="int" transient="false" volatile="false" @@ -116300,7 +116291,7 @@ visibility="public" > </field> -<field name="TTS_LANG_AVAILABLE" +<field name="LANG_AVAILABLE" type="int" transient="false" volatile="false" @@ -116311,7 +116302,7 @@ visibility="public" > </field> -<field name="TTS_LANG_COUNTRY_AVAILABLE" +<field name="LANG_COUNTRY_AVAILABLE" type="int" transient="false" volatile="false" @@ -116322,7 +116313,7 @@ visibility="public" > </field> -<field name="TTS_LANG_COUNTRY_VAR_AVAILABLE" +<field name="LANG_COUNTRY_VAR_AVAILABLE" type="int" transient="false" volatile="false" @@ -116333,7 +116324,7 @@ visibility="public" > </field> -<field name="TTS_LANG_MISSING_DATA" +<field name="LANG_MISSING_DATA" type="int" transient="false" volatile="false" @@ -116344,7 +116335,7 @@ visibility="public" > </field> -<field name="TTS_LANG_NOT_SUPPORTED" +<field name="LANG_NOT_SUPPORTED" type="int" transient="false" volatile="false" @@ -116355,7 +116346,7 @@ visibility="public" > </field> -<field name="TTS_QUEUE_ADD" +<field name="QUEUE_ADD" type="int" transient="false" volatile="false" @@ -116366,7 +116357,7 @@ visibility="public" > </field> -<field name="TTS_QUEUE_FLUSH" +<field name="QUEUE_FLUSH" type="int" transient="false" volatile="false" @@ -116377,7 +116368,7 @@ visibility="public" > </field> -<field name="TTS_SUCCESS" +<field name="SUCCESS" type="int" transient="false" volatile="false" @@ -116405,6 +116396,28 @@ visibility="public" > </constructor> +<field name="ACTION_CHECK_TTS_DATA" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.speech.tts.engine.CHECK_TTS_DATA"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="ACTION_INSTALL_TTS_DATA" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.speech.tts.engine.INSTALL_TTS_DATA"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="CHECK_VOICE_DATA_BAD_DATA" type="int" transient="false" @@ -116460,7 +116473,7 @@ visibility="public" > </field> -<field name="TTS_DEFAULT_STREAM" +<field name="DEFAULT_STREAM" type="int" transient="false" volatile="false" @@ -116471,55 +116484,55 @@ visibility="public" > </field> -<field name="TTS_KEY_PARAM_STREAM" +<field name="EXTRA_VOICE_DATA_FILES" type="java.lang.String" transient="false" volatile="false" - value=""streamType"" + value=""dataFiles"" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="TTS_KEY_PARAM_UTTERANCE_ID" +<field name="EXTRA_VOICE_DATA_FILES_INFO" type="java.lang.String" transient="false" volatile="false" - value=""utteranceId"" + value=""dataFilesInfo"" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="VOICE_DATA_FILES" +<field name="EXTRA_VOICE_DATA_ROOT_DIRECTORY" type="java.lang.String" transient="false" volatile="false" - value=""dataFiles"" + value=""dataRoot"" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="VOICE_DATA_FILES_INFO" +<field name="KEY_PARAM_STREAM" type="java.lang.String" transient="false" volatile="false" - value=""dataFilesInfo"" + value=""streamType"" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="VOICE_DATA_ROOT_DIRECTORY" +<field name="KEY_PARAM_UTTERANCE_ID" type="java.lang.String" transient="false" volatile="false" - value=""dataRoot"" + value=""utteranceId"" static="true" final="true" deprecated="not deprecated" @@ -135031,9 +135044,33 @@ type="android.text.style.ImageSpan" static="false" final="false" + deprecated="deprecated" + visibility="public" +> +<parameter name="b" type="android.graphics.Bitmap"> +</parameter> +</constructor> +<constructor name="ImageSpan" + type="android.text.style.ImageSpan" + static="false" + final="false" + deprecated="deprecated" + visibility="public" +> +<parameter name="b" type="android.graphics.Bitmap"> +</parameter> +<parameter name="verticalAlignment" type="int"> +</parameter> +</constructor> +<constructor name="ImageSpan" + type="android.text.style.ImageSpan" + static="false" + final="false" deprecated="not deprecated" visibility="public" > +<parameter name="context" type="android.content.Context"> +</parameter> <parameter name="b" type="android.graphics.Bitmap"> </parameter> </constructor> @@ -135044,6 +135081,8 @@ deprecated="not deprecated" visibility="public" > +<parameter name="context" type="android.content.Context"> +</parameter> <parameter name="b" type="android.graphics.Bitmap"> </parameter> <parameter name="verticalAlignment" type="int"> diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 3aeac53..447512a 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1085,6 +1085,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeInt(result); return true; } + case KILL_APPLICATION_WITH_UID_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String pkg = data.readString(); @@ -1093,6 +1094,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } + + case CLOSE_SYSTEM_DIALOGS_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + String reason = data.readString(); + closeSystemDialogs(reason); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -2376,6 +2385,7 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); return result; } + public void killApplicationWithUid(String pkg, int uid) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -2387,6 +2397,17 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } + + public void closeSystemDialogs(String reason) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeString(reason); + mRemote.transact(CLOSE_SYSTEM_DIALOGS_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } private IBinder mRemote; } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index b1b5282..f6ef549 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -268,7 +268,9 @@ public interface IActivityManager extends IInterface { throws RemoteException; public void killApplicationWithUid(String pkg, int uid) throws RemoteException; - + + public void closeSystemDialogs(String reason) throws RemoteException; + /* * Private non-Binder interfaces */ @@ -424,4 +426,5 @@ public interface IActivityManager extends IInterface { int UNREGISTER_ACTIVITY_WATCHER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93; int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94; int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95; + int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96; } diff --git a/core/java/android/app/IActivityWatcher.aidl b/core/java/android/app/IActivityWatcher.aidl index 5d36e3f..6737545 100644 --- a/core/java/android/app/IActivityWatcher.aidl +++ b/core/java/android/app/IActivityWatcher.aidl @@ -23,4 +23,5 @@ package android.app; */ oneway interface IActivityWatcher { void activityResuming(int activityId); + void closingSystemDialogs(String reason); } diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index e991bc6..4dd2433 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -270,6 +270,16 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS if (!mGlobalSearchMode) { mStoredComponentName = mLaunchComponent; mStoredAppSearchData = mAppSearchData; + + // If this is the browser, we have a special case to not show the icon to the left + // of the text field, for extra space for url entry (this should be reconciled in + // Eclair). So special case a second tap of the search button to remove any + // already-entered text so that we can be sure to show the "Quick Search Box" hint + // text to still make it clear to the user that we've jumped out to global search. + // + // TODO: When the browser icon issue is reconciled in Eclair, remove this special case. + if (isBrowserSearch()) currentSearchText = ""; + return doShow(currentSearchText, false, null, mAppSearchData, true); } else { if (mStoredComponentName != null) { @@ -577,7 +587,11 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } private void updateSearchAppIcon() { - if (mGlobalSearchMode) { + // In Donut, we special-case the case of the browser to hide the app icon as if it were + // global search, for extra space for url entry. + // + // TODO: Remove this special case once the issue has been reconciled in Eclair. + if (mGlobalSearchMode || isBrowserSearch()) { mAppIcon.setImageResource(0); mAppIcon.setVisibility(View.GONE); mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_GLOBAL, @@ -668,6 +682,16 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } mVoiceButton.setVisibility(visibility); } + + /** + * Hack to determine whether this is the browser, so we can remove the browser icon + * to the left of the search field, as a special requirement for Donut. + * + * TODO: For Eclair, reconcile this with the rest of the global search UI. + */ + private boolean isBrowserSearch() { + return mLaunchComponent.flattenToShortString().startsWith("com.android.browser/"); + } /* * Menu. @@ -1297,6 +1321,9 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS if (mGlobalSearchMode) { launchGlobalSearchIntent(intent); } else { + // If the intent was created from a suggestion, it will always have an explicit + // component here. + Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toURI()); getContext().startActivity(intent); // If the search switches to a different activity, // SearchDialogWrapper#performActivityResuming @@ -1338,7 +1365,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); setBrowserApplicationId(intent); - if (DBG) Log.d(LOG_TAG, "Launching intent " + intent.toURI() + " as " + packageName); startActivityInPackage(intent, packageName); } @@ -1379,6 +1405,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS String resultWho = null; int requestCode = -1; boolean onlyIfNeeded = false; + Log.i(LOG_TAG, "Starting (uid " + uid + ", " + packageName + ") " + intent.toURI()); int result = ActivityManagerNative.getDefault().startActivityInPackage( uid, intent, resolvedType, resultTo, resultWho, requestCode, onlyIfNeeded); checkStartActivityResult(result, intent); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 64ee60e..f9b082f 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1409,6 +1409,17 @@ public class Intent implements Parcelable { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN"; /** + * Activity Action: Start this activity to request system shutdown. + * The optional boolean extra field {@link #EXTRA_KEY_CONFIRM} can be set to true + * to request confirmation from the user before shutting down. + * + * <p class="note">This is a protected intent that can only be sent + * by the system. + * + * {@hide} + */ + public static final String ACTION_REQUEST_SHUTDOWN = "android.intent.action.ACTION_REQUEST_SHUTDOWN"; + /** * Broadcast Action: Indicates low memory condition on the device * * <p class="note">This is a protected intent that can only be sent @@ -1684,53 +1695,7 @@ public class Intent implements Parcelable { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_REBOOT = "android.intent.action.REBOOT"; - /** - * Broadcast Action: Triggers the platform Text-To-Speech engine to - * start the activity that installs the resource files on the device - * that are required for TTS to be operational. Since the installation - * of the data can be interrupted or declined by the user, the application - * shouldn't expect successful installation upon return from that intent, - * and if need be, should check installation status with - * {@link #ACTION_TTS_CHECK_TTS_DATA}. - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_TTS_INSTALL_TTS_DATA = - "android.intent.action.INSTALL_TTS_DATA"; - - /** - * Broadcast Action: Starts the activity from the platform Text-To-Speech - * engine to verify the proper installation and availability of the - * resource files on the system. Upon completion, the activity will - * return one of the following codes: - * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_PASS}, - * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_FAIL}, - * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_BAD_DATA}, - * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_MISSING_DATA}, or - * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_MISSING_VOLUME}. - * <p> Moreover, the data received in the activity result will contain the following - * fields: - * <ul> - * <li>{@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_ROOT_DIRECTORY} which - * indicates the path to the location of the resource files</li>, - * <li>{@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_FILES} which contains - * the list of all the resource files</li>, - * <li>and {@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_FILES_INFO} which - * contains, for each resource file, the description of the language covered by - * the file in the xxx-YYY format, where xxx is the 3-letter ISO language code, - * and YYY is the 3-letter ISO country code.</li> - * </ul> - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_TTS_CHECK_TTS_DATA = - "android.intent.action.CHECK_TTS_DATA"; - /** - * Broadcast Action: The TextToSpeech synthesizer has completed processing - * all of the text in the speech queue. - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED = - "android.intent.action.TTS_QUEUE_PROCESSING_COMPLETED"; /** * Broadcast Action: a remote intent is to be broadcasted. @@ -1939,6 +1904,14 @@ public class Intent implements Parcelable { public static final String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT"; /** + * Set to true in {@link #ACTION_REQUEST_SHUTDOWN} to request confirmation from the user + * before shutting down. + * + * {@hide} + */ + public static final String EXTRA_KEY_CONFIRM = "android.intent.extra.KEY_CONFIRM"; + + /** * Used as an boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or * {@link android.content.Intent#ACTION_PACKAGE_CHANGED} intents to override the default action * of restarting the application. diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 0c2b65e..1db17c8 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -879,6 +879,17 @@ public final class Settings { public static final String AIRPLANE_MODE_RADIOS = "airplane_mode_radios"; /** + * A comma separated list of radios that should to be disabled when airplane mode + * is on, but can be manually reenabled by the user. For example, if RADIO_WIFI is + * added to both AIRPLANE_MODE_RADIOS and AIRPLANE_MODE_TOGGLEABLE_RADIOS, then Wifi + * will be turned off when entering airplane mode, but the user will be able to reenable + * Wifi in the Settings app. + * + * {@hide} + */ + public static final String AIRPLANE_MODE_TOGGLEABLE_RADIOS = "airplane_mode_toggleable_radios"; + + /** * The policy for deciding when Wi-Fi should go to sleep (which will in * turn switch to using the mobile data as an Internet connection). * <p> diff --git a/core/java/android/server/search/SearchDialogWrapper.java b/core/java/android/server/search/SearchDialogWrapper.java index b8a9875..49718cb 100644 --- a/core/java/android/server/search/SearchDialogWrapper.java +++ b/core/java/android/server/search/SearchDialogWrapper.java @@ -63,6 +63,8 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { private static final int MSG_STOP_SEARCH = 2; // arg1 is activity id private static final int MSG_ACTIVITY_RESUMING = 3; + // obj is the reason + private static final int MSG_CLOSING_SYSTEM_DIALOGS = 4; private static final String KEY_INITIAL_QUERY = "q"; private static final String KEY_LAUNCH_ACTIVITY = "a"; @@ -127,8 +129,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { private void registerBroadcastReceiver() { if (!mReceiverRegistered) { IntentFilter filter = new IntentFilter( - Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); + Intent.ACTION_CONFIGURATION_CHANGED); mContext.registerReceiver(mBroadcastReceiver, filter, null, mSearchUiThread); mReceiverRegistered = true; @@ -149,12 +150,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { - if (!"search".equals(intent.getStringExtra("reason"))) { - if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - performStopSearch(); - } - } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { + if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { if (DBG) debug(Intent.ACTION_CONFIGURATION_CHANGED); performOnConfigurationChanged(); } @@ -219,6 +215,18 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { mSearchUiThread.sendMessage(msg); } + /** + * Handles closing of system windows/dialogs + * Can be called from any thread. + */ + public void closingSystemDialogs(String reason) { + if (DBG) debug("closingSystemDialogs(reason=" + reason + ")"); + Message msg = Message.obtain(); + msg.what = MSG_CLOSING_SYSTEM_DIALOGS; + msg.obj = reason; + mSearchUiThread.sendMessage(msg); + } + // // Implementation methods that run on the search UI thread // @@ -244,6 +252,9 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { case MSG_ACTIVITY_RESUMING: performActivityResuming(msg.arg1); break; + case MSG_CLOSING_SYSTEM_DIALOGS: + performClosingSystemDialogs((String)msg.obj); + break; } } @@ -330,6 +341,19 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener { } /** + * Updates due to system dialogs being closed + * This must be called on the search UI thread. + */ + void performClosingSystemDialogs(String reason) { + if (DBG) debug("performClosingSystemDialogs(): mStartedIdent=" + + mStartedIdent + ", reason: " + reason); + if (!"search".equals(reason)) { + if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + performStopSearch(); + } + } + + /** * Must be called from the search UI thread. */ void performOnConfigurationChanged() { diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java index fdeb8f9..afed4a4 100644 --- a/core/java/android/server/search/SearchManagerService.java +++ b/core/java/android/server/search/SearchManagerService.java @@ -138,6 +138,11 @@ public class SearchManagerService extends ISearchManager.Stub { if (mSearchDialog == null) return; mSearchDialog.activityResuming(activityId); } + public void closingSystemDialogs(String reason) { + if (DBG) Log.i("foo", "********************** closing dialogs: " + reason); + if (mSearchDialog == null) return; + mSearchDialog.closingSystemDialogs(reason); + } }; /** diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 8f8d976..b033c6a 100755 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -18,6 +18,8 @@ package android.speech.tts; import android.speech.tts.ITts; import android.speech.tts.ITtsCallback; +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -41,51 +43,60 @@ public class TextToSpeech { /** * Denotes a successful operation. */ - public static final int TTS_SUCCESS = 0; + public static final int SUCCESS = 0; /** * Denotes a generic operation failure. */ - public static final int TTS_ERROR = -1; + public static final int ERROR = -1; /** * Queue mode where all entries in the playback queue (media to be played * and text to be synthesized) are dropped and replaced by the new entry. */ - public static final int TTS_QUEUE_FLUSH = 0; + public static final int QUEUE_FLUSH = 0; /** * Queue mode where the new entry is added at the end of the playback queue. */ - public static final int TTS_QUEUE_ADD = 1; + public static final int QUEUE_ADD = 1; /** * Denotes the language is available exactly as specified by the locale */ - public static final int TTS_LANG_COUNTRY_VAR_AVAILABLE = 2; + public static final int LANG_COUNTRY_VAR_AVAILABLE = 2; /** * Denotes the language is available for the language and country specified * by the locale, but not the variant. */ - public static final int TTS_LANG_COUNTRY_AVAILABLE = 1; + public static final int LANG_COUNTRY_AVAILABLE = 1; /** * Denotes the language is available for the language by the locale, * but not the country and variant. */ - public static final int TTS_LANG_AVAILABLE = 0; + public static final int LANG_AVAILABLE = 0; /** * Denotes the language data is missing. */ - public static final int TTS_LANG_MISSING_DATA = -1; + public static final int LANG_MISSING_DATA = -1; /** * Denotes the language is not supported by the current TTS engine. */ - public static final int TTS_LANG_NOT_SUPPORTED = -2; + public static final int LANG_NOT_SUPPORTED = -2; + + + /** + * Broadcast Action: The TextToSpeech synthesizer has completed processing + * of all the text in the speech queue. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED = + "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED"; /** @@ -119,126 +130,167 @@ public class TextToSpeech { /** * {@hide} */ - public static final int FALLBACK_TTS_DEFAULT_RATE = 100; // 1x + public static final int DEFAULT_RATE = 100; // 1x /** * {@hide} */ - public static final int FALLBACK_TTS_DEFAULT_PITCH = 100;// 1x + public static final int DEFAULT_PITCH = 100;// 1x /** * {@hide} */ - public static final int FALLBACK_TTS_USE_DEFAULTS = 0; // false + public static final int USE_DEFAULTS = 0; // false /** * {@hide} */ - public static final String FALLBACK_TTS_DEFAULT_SYNTH = "com.svox.pico"; + public static final String DEFAULT_SYNTH = "com.svox.pico"; // default values for rendering - public static final int TTS_DEFAULT_STREAM = AudioManager.STREAM_MUSIC; + public static final int DEFAULT_STREAM = AudioManager.STREAM_MUSIC; // return codes for a TTS engine's check data activity /** * Indicates success when checking the installation status of the resources used by the - * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent. + * text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. */ public static final int CHECK_VOICE_DATA_PASS = 1; /** * Indicates failure when checking the installation status of the resources used by the - * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent. + * text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. */ public static final int CHECK_VOICE_DATA_FAIL = 0; /** * Indicates erroneous data when checking the installation status of the resources used by - * the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent. + * the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. */ public static final int CHECK_VOICE_DATA_BAD_DATA = -1; /** * Indicates missing resources when checking the installation status of the resources used - * by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent. + * by the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. */ public static final int CHECK_VOICE_DATA_MISSING_DATA = -2; /** * Indicates missing storage volume when checking the installation status of the resources - * used by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent. + * used by the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. */ public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3; - // return codes for a TTS engine's check data activity + // intents to ask engine to install data or check its data + /** + * Broadcast Action: Triggers the platform Text-To-Speech engine to + * start the activity that installs the resource files on the device + * that are required for TTS to be operational. Since the installation + * of the data can be interrupted or declined by the user, the application + * shouldn't expect successful installation upon return from that intent, + * and if need be, should check installation status with + * {@link #ACTION_CHECK_TTS_DATA}. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_INSTALL_TTS_DATA = + "android.speech.tts.engine.INSTALL_TTS_DATA"; + + /** + * Broadcast Action: Starts the activity from the platform Text-To-Speech + * engine to verify the proper installation and availability of the + * resource files on the system. Upon completion, the activity will + * return one of the following codes: + * {@link #CHECK_VOICE_DATA_PASS}, + * {@link #CHECK_VOICE_DATA_FAIL}, + * {@link #CHECK_VOICE_DATA_BAD_DATA}, + * {@link #CHECK_VOICE_DATA_MISSING_DATA}, or + * {@link #CHECK_VOICE_DATA_MISSING_VOLUME}. + * <p> Moreover, the data received in the activity result will contain the following + * fields: + * <ul> + * <li>{@link #EXTRA_VOICE_DATA_ROOT_DIRECTORY} which + * indicates the path to the location of the resource files</li>, + * <li>{@link #EXTRA_VOICE_DATA_FILES} which contains + * the list of all the resource files</li>, + * <li>and {@link #EXTRA_VOICE_DATA_FILES_INFO} which + * contains, for each resource file, the description of the language covered by + * the file in the xxx-YYY format, where xxx is the 3-letter ISO language code, + * and YYY is the 3-letter ISO country code.</li> + * </ul> + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_CHECK_TTS_DATA = + "android.speech.tts.engine.CHECK_TTS_DATA"; + + // extras for a TTS engine's check data activity /** - * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where + * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where * the text-to-speech engine specifies the path to its resources. */ - public static final String VOICE_DATA_ROOT_DIRECTORY = "dataRoot"; + public static final String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot"; /** - * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where + * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where * the text-to-speech engine specifies the file names of its resources under the * resource path. */ - public static final String VOICE_DATA_FILES = "dataFiles"; + public static final String EXTRA_VOICE_DATA_FILES = "dataFiles"; /** - * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where + * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where * the text-to-speech engine specifies the locale associated with each resource file. */ - public static final String VOICE_DATA_FILES_INFO = "dataFilesInfo"; + public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo"; // keys for the parameters passed with speak commands. Hidden keys are used internally // to maintain engine state for each TextToSpeech instance. /** * {@hide} */ - public static final String TTS_KEY_PARAM_RATE = "rate"; + public static final String KEY_PARAM_RATE = "rate"; /** * {@hide} */ - public static final String TTS_KEY_PARAM_LANGUAGE = "language"; + public static final String KEY_PARAM_LANGUAGE = "language"; /** * {@hide} */ - public static final String TTS_KEY_PARAM_COUNTRY = "country"; + public static final String KEY_PARAM_COUNTRY = "country"; /** * {@hide} */ - public static final String TTS_KEY_PARAM_VARIANT = "variant"; + public static final String KEY_PARAM_VARIANT = "variant"; /** * Parameter key to specify the audio stream type to be used when speaking text * or playing back a file. */ - public static final String TTS_KEY_PARAM_STREAM = "streamType"; + public static final String KEY_PARAM_STREAM = "streamType"; /** * Parameter key to identify an utterance in the completion listener after text has been * spoken, a file has been played back or a silence duration has elapsed. */ - public static final String TTS_KEY_PARAM_UTTERANCE_ID = "utteranceId"; + public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId"; // key positions in the array of cached parameters /** * {@hide} */ - protected static final int TTS_PARAM_POSITION_RATE = 0; + protected static final int PARAM_POSITION_RATE = 0; /** * {@hide} */ - protected static final int TTS_PARAM_POSITION_LANGUAGE = 2; + protected static final int PARAM_POSITION_LANGUAGE = 2; /** * {@hide} */ - protected static final int TTS_PARAM_POSITION_COUNTRY = 4; + protected static final int PARAM_POSITION_COUNTRY = 4; /** * {@hide} */ - protected static final int TTS_PARAM_POSITION_VARIANT = 6; + protected static final int PARAM_POSITION_VARIANT = 6; /** * {@hide} */ - protected static final int TTS_PARAM_POSITION_STREAM = 8; + protected static final int PARAM_POSITION_STREAM = 8; /** * {@hide} */ - protected static final int TTS_PARAM_POSITION_UTTERANCE_ID = 10; + protected static final int PARAM_POSITION_UTTERANCE_ID = 10; /** * {@hide} */ - protected static final int TTS_NB_CACHED_PARAMS = 6; + protected static final int NB_CACHED_PARAMS = 6; } /** @@ -273,25 +325,25 @@ public class TextToSpeech { mPackageName = mContext.getPackageName(); mInitListener = listener; - mCachedParams = new String[2*Engine.TTS_NB_CACHED_PARAMS]; // store key and value - mCachedParams[Engine.TTS_PARAM_POSITION_RATE] = Engine.TTS_KEY_PARAM_RATE; - mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE] = Engine.TTS_KEY_PARAM_LANGUAGE; - mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY; - mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT; - mCachedParams[Engine.TTS_PARAM_POSITION_STREAM] = Engine.TTS_KEY_PARAM_STREAM; - mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = Engine.TTS_KEY_PARAM_UTTERANCE_ID; + mCachedParams = new String[2*Engine.NB_CACHED_PARAMS]; // store key and value + mCachedParams[Engine.PARAM_POSITION_RATE] = Engine.KEY_PARAM_RATE; + mCachedParams[Engine.PARAM_POSITION_LANGUAGE] = Engine.KEY_PARAM_LANGUAGE; + mCachedParams[Engine.PARAM_POSITION_COUNTRY] = Engine.KEY_PARAM_COUNTRY; + mCachedParams[Engine.PARAM_POSITION_VARIANT] = Engine.KEY_PARAM_VARIANT; + mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM; + mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID; - mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = - String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE); + mCachedParams[Engine.PARAM_POSITION_RATE + 1] = + String.valueOf(Engine.DEFAULT_RATE); // initialize the language cached parameters with the current Locale Locale defaultLoc = Locale.getDefault(); - mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language(); - mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country(); - mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant(); + mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language(); + mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country(); + mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant(); - mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = - String.valueOf(Engine.TTS_DEFAULT_STREAM); - mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = ""; + mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = + String.valueOf(Engine.DEFAULT_STREAM); + mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = ""; initTts(); } @@ -308,7 +360,7 @@ public class TextToSpeech { mStarted = true; if (mInitListener != null) { // TODO manage failures and missing resources - mInitListener.onInit(TTS_SUCCESS); + mInitListener.onInit(SUCCESS); } } } @@ -349,8 +401,7 @@ public class TextToSpeech { /** * Adds a mapping between a string of text and a sound resource in a * package. - * - * @see #TTS.speak(String text, int queueMode, String[] params) + * @see #speak(String, int, HashMap) * * @param text * Example: <b><code>"south_south_east"</code></b><br/> @@ -371,16 +422,16 @@ public class TextToSpeech { * @param resourceId * Example: <b><code>R.raw.south_south_east</code></b> * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int addSpeech(String text, String packagename, int resourceId) { synchronized(mStartLock) { if (!mStarted) { - return TTS_ERROR; + return ERROR; } try { mITts.addSpeech(mPackageName, text, packagename, resourceId); - return TTS_SUCCESS; + return SUCCESS; } catch (RemoteException e) { // TTS died; restart it. Log.e("TextToSpeech.java - addSpeech", "RemoteException"); @@ -400,7 +451,7 @@ public class TextToSpeech { mStarted = false; initTts(); } - return TTS_ERROR; + return ERROR; } } @@ -415,16 +466,16 @@ public class TextToSpeech { * The full path to the sound file (for example: * "/sdcard/mysounds/hello.wav") * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int addSpeech(String text, String filename) { synchronized (mStartLock) { if (!mStarted) { - return TTS_ERROR; + return ERROR; } try { mITts.addSpeechFile(mPackageName, text, filename); - return TTS_SUCCESS; + return SUCCESS; } catch (RemoteException e) { // TTS died; restart it. Log.e("TextToSpeech.java - addSpeech", "RemoteException"); @@ -444,7 +495,7 @@ public class TextToSpeech { mStarted = false; initTts(); } - return TTS_ERROR; + return ERROR; } } @@ -453,7 +504,7 @@ public class TextToSpeech { * Adds a mapping between a string of text and a sound resource in a * package. * - * @see #TTS.playEarcon(String earcon, int queueMode, String[] params) + * @see #playEarcon(String, int, HashMap) * * @param earcon The name of the earcon * Example: <b><code>"[tick]"</code></b><br/> @@ -474,16 +525,16 @@ public class TextToSpeech { * @param resourceId * Example: <b><code>R.raw.tick_snd</code></b> * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int addEarcon(String earcon, String packagename, int resourceId) { synchronized(mStartLock) { if (!mStarted) { - return TTS_ERROR; + return ERROR; } try { mITts.addEarcon(mPackageName, earcon, packagename, resourceId); - return TTS_SUCCESS; + return SUCCESS; } catch (RemoteException e) { // TTS died; restart it. Log.e("TextToSpeech.java - addEarcon", "RemoteException"); @@ -503,7 +554,7 @@ public class TextToSpeech { mStarted = false; initTts(); } - return TTS_ERROR; + return ERROR; } } @@ -518,16 +569,16 @@ public class TextToSpeech { * The full path to the sound file (for example: * "/sdcard/mysounds/tick.wav") * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int addEarcon(String earcon, String filename) { synchronized (mStartLock) { if (!mStarted) { - return TTS_ERROR; + return ERROR; } try { mITts.addEarconFile(mPackageName, earcon, filename); - return TTS_SUCCESS; + return SUCCESS; } catch (RemoteException e) { // TTS died; restart it. Log.e("TextToSpeech.java - addEarcon", "RemoteException"); @@ -547,7 +598,7 @@ public class TextToSpeech { mStarted = false; initTts(); } - return TTS_ERROR; + return ERROR; } } @@ -563,29 +614,29 @@ public class TextToSpeech { * The string of text to be spoken. * @param queueMode * The queuing strategy to use. - * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH. + * See QUEUE_ADD and QUEUE_FLUSH. * @param params * The hashmap of speech parameters to be used. * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int speak(String text, int queueMode, HashMap<String,String> params) { synchronized (mStartLock) { - int result = TTS_ERROR; + int result = ERROR; Log.i("TTS received: ", text); if (!mStarted) { return result; } try { if ((params != null) && (!params.isEmpty())) { - String extra = params.get(Engine.TTS_KEY_PARAM_STREAM); + String extra = params.get(Engine.KEY_PARAM_STREAM); if (extra != null) { - mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra; + mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra; } - extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); + extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID); if (extra != null) { - mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra; + mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; } } result = mITts.speak(mPackageName, text, queueMode, mCachedParams); @@ -621,28 +672,28 @@ public class TextToSpeech { * @param earcon * The earcon that should be played * @param queueMode - * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH. + * See QUEUE_ADD and QUEUE_FLUSH. * @param params * The hashmap of parameters to be used. * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int playEarcon(String earcon, int queueMode, HashMap<String,String> params) { synchronized (mStartLock) { - int result = TTS_ERROR; + int result = ERROR; if (!mStarted) { return result; } try { if ((params != null) && (!params.isEmpty())) { - String extra = params.get(Engine.TTS_KEY_PARAM_STREAM); + String extra = params.get(Engine.KEY_PARAM_STREAM); if (extra != null) { - mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra; + mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra; } - extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); + extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID); if (extra != null) { - mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra; + mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; } } result = mITts.playEarcon(mPackageName, earcon, queueMode, null); @@ -678,21 +729,21 @@ public class TextToSpeech { * @param durationInMs * A long that indicates how long the silence should last. * @param queueMode - * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH. + * See QUEUE_ADD and QUEUE_FLUSH. * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int playSilence(long durationInMs, int queueMode, HashMap<String,String> params) { synchronized (mStartLock) { - int result = TTS_ERROR; + int result = ERROR; if (!mStarted) { return result; } try { if ((params != null) && (!params.isEmpty())) { - String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); + String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID); if (extra != null) { - mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra; + mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; } } result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams); @@ -760,11 +811,11 @@ public class TextToSpeech { /** * Stops speech from the TTS. * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int stop() { synchronized (mStartLock) { - int result = TTS_ERROR; + int result = ERROR; if (!mStarted) { return result; } @@ -808,24 +859,24 @@ public class TextToSpeech { * lower values slow down the speech (0.5 is half the normal speech rate), * greater values accelerate it (2 is twice the normal speech rate). * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int setSpeechRate(float speechRate) { synchronized (mStartLock) { - int result = TTS_ERROR; + int result = ERROR; if (!mStarted) { return result; } try { if (speechRate > 0) { int rate = (int)(speechRate*100); - mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(rate); + mCachedParams[Engine.PARAM_POSITION_RATE + 1] = String.valueOf(rate); // the rate is not set here, instead it is cached so it will be associated // with all upcoming utterances. if (speechRate > 0.0f) { - result = TTS_SUCCESS; + result = SUCCESS; } else { - result = TTS_ERROR; + result = ERROR; } } } catch (NullPointerException e) { @@ -860,11 +911,11 @@ public class TextToSpeech { * lower values lower the tone of the synthesized voice, * greater values increase it. * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int setPitch(float pitch) { synchronized (mStartLock) { - int result = TTS_ERROR; + int result = ERROR; if (!mStarted) { return result; } @@ -907,27 +958,27 @@ public class TextToSpeech { * @param loc * The locale describing the language to be used. * - * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE}, - * {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE}, - * {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}. + * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE}, + * {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE}, + * {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}. */ public int setLanguage(Locale loc) { synchronized (mStartLock) { - int result = TTS_LANG_NOT_SUPPORTED; + int result = LANG_NOT_SUPPORTED; if (!mStarted) { return result; } try { - mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language(); - mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country(); - mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = loc.getVariant(); + mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language(); + mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country(); + mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = loc.getVariant(); // the language is not set here, instead it is cached so it will be associated // with all upcoming utterances. But we still need to report the language support, // which is achieved by calling isLanguageAvailable() result = mITts.isLanguageAvailable( - mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1], - mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1], - mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] ); + mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1], + mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1], + mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] ); } catch (RemoteException e) { // TTS died; restart it. Log.e("TextToSpeech.java - setLanguage", "RemoteException"); @@ -999,13 +1050,13 @@ public class TextToSpeech { * @param loc * The Locale describing the language to be used. * - * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE}, - * {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE}, - * {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}. + * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE}, + * {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE}, + * {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}. */ public int isLanguageAvailable(Locale loc) { synchronized (mStartLock) { - int result = TTS_LANG_NOT_SUPPORTED; + int result = LANG_NOT_SUPPORTED; if (!mStarted) { return result; } @@ -1048,25 +1099,25 @@ public class TextToSpeech { * The string that gives the full output filename; it should be * something like "/sdcard/myappsounds/mysound.wav". * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int synthesizeToFile(String text, HashMap<String,String> params, String filename) { synchronized (mStartLock) { - int result = TTS_ERROR; + int result = ERROR; if (!mStarted) { return result; } try { if ((params != null) && (!params.isEmpty())) { // no need to read the stream type here - String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); + String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID); if (extra != null) { - mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra; + mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; } } if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){ - result = TTS_SUCCESS; + result = SUCCESS; } } catch (RemoteException e) { // TTS died; restart it. @@ -1099,9 +1150,9 @@ public class TextToSpeech { * if they are not persistent between calls to the service. */ private void resetCachedParams() { - mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = - String.valueOf(Engine.TTS_DEFAULT_STREAM); - mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = ""; + mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = + String.valueOf(Engine.DEFAULT_STREAM); + mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID+ 1] = ""; } /** @@ -1110,12 +1161,12 @@ public class TextToSpeech { * @param listener * The OnUtteranceCompletedListener * - * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. + * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ public int setOnUtteranceCompletedListener(
final OnUtteranceCompletedListener listener) {
synchronized (mStartLock) { - int result = TTS_ERROR; + int result = ERROR; if (!mStarted) { return result; } diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java index 911a23c..86ef5f6 100644 --- a/core/java/android/text/style/ImageSpan.java +++ b/core/java/android/text/style/ImageSpan.java @@ -33,17 +33,34 @@ public class ImageSpan extends DynamicDrawableSpan { private Context mContext; private String mSource; + /** + * @deprecated Use {@link #ImageSpan(Context, Bitmap)} instead. + */ public ImageSpan(Bitmap b) { - this(b, ALIGN_BOTTOM); + this(null, b, ALIGN_BOTTOM); + } + + /** + * @deprecated Use {@link #ImageSpan(Context, Bitmap, int) instead. + */ + public ImageSpan(Bitmap b, int verticalAlignment) { + this(null, b, verticalAlignment); + } + + public ImageSpan(Context context, Bitmap b) { + this(context, b, ALIGN_BOTTOM); } /** * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or * {@link DynamicDrawableSpan#ALIGN_BASELINE}. */ - public ImageSpan(Bitmap b, int verticalAlignment) { + public ImageSpan(Context context, Bitmap b, int verticalAlignment) { super(verticalAlignment); - mDrawable = new BitmapDrawable(mContext.getResources(), b); + mContext = context; + mDrawable = context != null + ? new BitmapDrawable(context.getResources(), b) + : new BitmapDrawable(b); int width = mDrawable.getIntrinsicWidth(); int height = mDrawable.getIntrinsicHeight(); mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0); diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index d46660c..ae84e1e 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -516,14 +516,14 @@ public final class MotionEvent implements Parcelable { } final int NS = (ev.mNumPointers=o.mNumPointers) * NT; - if (ev.mStateSamples.length < NS) { + if (ev.mStateSamples.length >= NS) { System.arraycopy(o.mStateSamples, 0, ev.mStateSamples, 0, NS); } else { ev.mStateSamples = (int[])o.mStateSamples.clone(); } final int ND = NS * NUM_SAMPLE_DATA; - if (ev.mDataSamples.length < ND) { + if (ev.mDataSamples.length >= ND) { System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND); } else { ev.mDataSamples = (float[])o.mDataSamples.clone(); diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index 3da5a3c..50436d8 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -74,6 +74,7 @@ class LoadListener extends Handler implements EventHandler { static { sCertificateMimeTypeMap = new HashSet<String>(); sCertificateMimeTypeMap.add("application/x-x509-ca-cert"); + sCertificateMimeTypeMap.add("application/x-x509-user-cert"); sCertificateMimeTypeMap.add("application/x-pkcs12"); } diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java index b2aa524..a55dbc8 100644 --- a/core/java/android/webkit/MimeTypeMap.java +++ b/core/java/android/webkit/MimeTypeMap.java @@ -330,6 +330,7 @@ public class MimeTypeMap { sMimeTypeMap.loadEntry("application/x-wingz", "wz"); sMimeTypeMap.loadEntry("application/x-webarchive", "webarchive"); sMimeTypeMap.loadEntry("application/x-x509-ca-cert", "crt"); + sMimeTypeMap.loadEntry("application/x-x509-user-cert", "crt"); sMimeTypeMap.loadEntry("application/x-xcf", "xcf"); sMimeTypeMap.loadEntry("application/x-xfig", "fig"); sMimeTypeMap.loadEntry("application/xhtml+xml", "xhtml"); diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 358fc9e..05a7806 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -206,11 +206,6 @@ public class WebView extends AbsoluteLayout static final String LOGTAG = "webview"; - static class ScaleLimitData { - int mMinScale; - int mMaxScale; - } - private static class ExtendedZoomControls extends FrameLayout { public ExtendedZoomControls(Context context, AttributeSet attrs) { super(context, attrs); @@ -472,7 +467,6 @@ public class WebView extends AbsoluteLayout static final int UPDATE_TEXT_ENTRY_MSG_ID = 15; static final int WEBCORE_INITIALIZED_MSG_ID = 16; static final int UPDATE_TEXTFIELD_TEXT_MSG_ID = 17; - static final int DID_FIRST_LAYOUT_MSG_ID = 18; static final int MOVE_OUT_OF_PLUGIN = 19; static final int CLEAR_TEXT_ENTRY = 20; @@ -502,7 +496,7 @@ public class WebView extends AbsoluteLayout "UPDATE_TEXT_ENTRY_MSG_ID", // = 15; "WEBCORE_INITIALIZED_MSG_ID", // = 16; "UPDATE_TEXTFIELD_TEXT_MSG_ID", // = 17; - "DID_FIRST_LAYOUT_MSG_ID", // = 18; + "18", // = 18; "MOVE_OUT_OF_PLUGIN", // = 19; "CLEAR_TEXT_ENTRY", // = 20; "21", // = 21; @@ -1892,6 +1886,13 @@ public class WebView extends AbsoluteLayout r.bottom = viewToContent(r.bottom); } + static class ViewSizeData { + int mWidth; + int mHeight; + int mTextWrapWidth; + float mScale; + } + /** * Compute unzoomed width and height, and if they differ from the last * values we sent, send them to webkit (to be used has new viewport) @@ -1899,7 +1900,8 @@ public class WebView extends AbsoluteLayout * @return true if new values were sent */ private boolean sendViewSizeZoom() { - int newWidth = Math.round(getViewWidth() * mInvActualScale); + int viewWidth = getViewWidth(); + int newWidth = Math.round(viewWidth * mInvActualScale); int newHeight = Math.round(getViewHeight() * mInvActualScale); /* * Because the native side may have already done a layout before the @@ -1914,8 +1916,16 @@ public class WebView extends AbsoluteLayout } // Avoid sending another message if the dimensions have not changed. if (newWidth != mLastWidthSent || newHeight != mLastHeightSent) { - mWebViewCore.sendMessage(EventHub.VIEW_SIZE_CHANGED, - newWidth, newHeight, new Float(mActualScale)); + ViewSizeData data = new ViewSizeData(); + data.mWidth = newWidth; + data.mHeight = newHeight; + // while in zoom overview mode, the text are wrapped to the screen + // width matching mLastScale. So that we don't trigger re-flow while + // toggling between overview mode and normal mode. + data.mTextWrapWidth = mInZoomOverview ? Math.round(viewWidth + / mLastScale) : newWidth; + data.mScale = mActualScale; + mWebViewCore.sendMessage(EventHub.VIEW_SIZE_CHANGED, data); mLastWidthSent = newWidth; mLastHeightSent = newHeight; return true; @@ -3877,11 +3887,6 @@ public class WebView extends AbsoluteLayout if (!mDragFromTextInput) { nativeHideCursor(); } - // remove the zoom anchor if there is any - if (mZoomScale != 0) { - mWebViewCore - .sendMessage(EventHub.SET_SNAP_ANCHOR, 0, 0); - } WebSettings settings = getSettings(); if (settings.supportZoom() && !mInZoomOverview && settings.getBuiltInZoomControls() @@ -4982,15 +4987,35 @@ public class WebView extends AbsoluteLayout final WebViewCore.DrawData draw = (WebViewCore.DrawData) msg.obj; final Point viewSize = draw.mViewPoint; - if (mZoomScale > 0) { - // use the same logic in sendViewSizeZoom() to make sure - // the mZoomScale has matched the viewSize so that we - // can clear mZoomScale - if (Math.round(viewWidth / mZoomScale) == viewSize.x) { - mZoomScale = 0; - mWebViewCore.sendMessage(EventHub.SET_SNAP_ANCHOR, - 0, 0); + boolean useWideViewport = + mWebViewCore.getSettings().getUseWideViewPort(); + WebViewCore.RestoreState restoreState = draw.mRestoreState; + if (restoreState != null) { + mInZoomOverview = false; + mLastScale = restoreState.mTextWrapScale; + if (restoreState.mMinScale == 0) { + mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE; + mMinZoomScaleFixed = false; + } else { + mMinZoomScale = restoreState.mMinScale; + mMinZoomScaleFixed = true; + } + if (restoreState.mMaxScale == 0) { + mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE; + } else { + mMaxZoomScale = restoreState.mMaxScale; + } + if (useWideViewport && restoreState.mViewScale == 0) { + mInZoomOverview = ENABLE_DOUBLETAP_ZOOM; } + setNewZoomScale(mLastScale, false); + setContentScrollTo(restoreState.mScrollX, + restoreState.mScrollY); + // As we are on a new page, remove the WebTextView. This + // is necessary for page loads driven by webkit, and in + // particular when the user was on a password field, so + // the WebTextView was visible. + clearTextEntry(); } // We update the layout (i.e. request a layout from the // view system) if the last view size that we sent to @@ -5009,7 +5034,7 @@ public class WebView extends AbsoluteLayout if (mPictureListener != null) { mPictureListener.onNewPicture(WebView.this, capturePicture()); } - if (mWebViewCore.getSettings().getUseWideViewPort()) { + if (useWideViewport) { mZoomOverviewWidth = Math.max(draw.mMinPrefWidth, draw.mViewPoint.x); } @@ -5056,76 +5081,6 @@ public class WebView extends AbsoluteLayout } } break; - case DID_FIRST_LAYOUT_MSG_ID: { - if (mNativeClass == 0) { - break; - } - ScaleLimitData scaleLimit = (ScaleLimitData) msg.obj; - int minScale = scaleLimit.mMinScale; - if (minScale == 0) { - mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE; - mMinZoomScaleFixed = false; - } else { - mMinZoomScale = (float) (minScale / 100.0); - mMinZoomScaleFixed = true; - } - int maxScale = scaleLimit.mMaxScale; - if (maxScale == 0) { - mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE; - } else { - mMaxZoomScale = (float) (maxScale / 100.0); - } - // If history Picture is drawn, don't update zoomWidth - if (mDrawHistory) { - break; - } - int width = getViewWidth(); - if (width == 0) { - break; - } - final WebSettings settings = mWebViewCore.getSettings(); - int initialScale = msg.arg1; - int viewportWidth = msg.arg2; - // start a new page with DEFAULT_SCALE zoom scale. - float scale = mDefaultScale; - mInZoomOverview = false; - if (mInitialScale > 0) { - scale = mInitialScale / 100.0f; - } else { - if (initialScale == -1) break; - if (settings.getUseWideViewPort()) { - // force viewSizeChanged by setting mLastWidthSent - // to 0 - mLastWidthSent = 0; - } - if (initialScale == 0) { - // if viewportWidth is defined and it is smaller - // than the view width, zoom in to fill the view - if (viewportWidth > 0 && viewportWidth < width) { - scale = (float) width / viewportWidth; - } else { - if (settings.getUseWideViewPort()) { - mInZoomOverview = ENABLE_DOUBLETAP_ZOOM; - } - } - } else if (initialScale < 0) { - // this should only happen when - // ENABLE_DOUBLETAP_ZOOM is true - mInZoomOverview = true; - scale = -initialScale / 100.0f; - } else { - scale = initialScale / 100.0f; - } - } - mLastScale = scale; - setNewZoomScale(scale, false); - // As we are on a new page, remove the WebTextView. This - // is necessary for page loads driven by webkit, and in - // particular when the user was on a password field, so - // the WebTextView was visible. - clearTextEntry(); - break; - } case MOVE_OUT_OF_PLUGIN: if (nativePluginEatsNavKey()) { navHandledKey(msg.arg1, 1, false, 0, true); diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 4afc4cd..8ec8174 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -443,10 +443,6 @@ final class WebViewCore { private native void nativeUpdateFrameCache(); - private native void nativeSetSnapAnchor(int x, int y); - - private native void nativeSnapToAnchor(); - private native void nativeSetBackgroundColor(int color); private native void nativeDumpDomTree(boolean useFile); @@ -674,7 +670,7 @@ final class WebViewCore { "CLICK", // = 118; "SET_NETWORK_STATE", // = 119; "DOC_HAS_IMAGES", // = 120; - "SET_SNAP_ANCHOR", // = 121; + "121", // = 121; "DELETE_SELECTION", // = 122; "LISTBOX_CHOICES", // = 123; "SINGLE_LISTBOX_CHOICE", // = 124; @@ -725,7 +721,6 @@ final class WebViewCore { static final int CLICK = 118; static final int SET_NETWORK_STATE = 119; static final int DOC_HAS_IMAGES = 120; - static final int SET_SNAP_ANCHOR = 121; static final int DELETE_SELECTION = 122; static final int LISTBOX_CHOICES = 123; static final int SINGLE_LISTBOX_CHOICE = 124; @@ -904,11 +899,13 @@ final class WebViewCore { nativeClick(msg.arg1, msg.arg2); break; - case VIEW_SIZE_CHANGED: - viewSizeChanged(msg.arg1, msg.arg2, - ((Float) msg.obj).floatValue()); + case VIEW_SIZE_CHANGED: { + WebView.ViewSizeData data = + (WebView.ViewSizeData) msg.obj; + viewSizeChanged(data.mWidth, data.mHeight, + data.mTextWrapWidth, data.mScale); break; - + } case SET_SCROLL_OFFSET: // note: these are in document coordinates // (inv-zoom) @@ -1107,10 +1104,6 @@ final class WebViewCore { imageResult.sendToTarget(); break; - case SET_SNAP_ANCHOR: - nativeSetSnapAnchor(msg.arg1, msg.arg2); - break; - case DELETE_SELECTION: DeleteSelectionData deleteSelectionData = (DeleteSelectionData) msg.obj; @@ -1401,16 +1394,20 @@ final class WebViewCore { // These values are used to avoid requesting a layout based on old values private int mCurrentViewWidth = 0; private int mCurrentViewHeight = 0; + private float mCurrentViewScale = 1.0f; // notify webkit that our virtual view size changed size (after inv-zoom) - private void viewSizeChanged(int w, int h, float scale) { - if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "CORE onSizeChanged"); + private void viewSizeChanged(int w, int h, int textwrapWidth, float scale) { + if (DebugFlags.WEB_VIEW_CORE) { + Log.v(LOGTAG, "viewSizeChanged w=" + w + "; h=" + h + + "; textwrapWidth=" + textwrapWidth + "; scale=" + scale); + } if (w == 0) { Log.w(LOGTAG, "skip viewSizeChanged as w is 0"); return; } + int width = w; if (mSettings.getUseWideViewPort()) { - int width; if (mViewportWidth == -1) { if (mSettings.getLayoutAlgorithm() == WebSettings.LayoutAlgorithm.NORMAL) { @@ -1433,19 +1430,14 @@ final class WebViewCore { } else { width = Math.max(w, mViewportWidth); } - // while in zoom overview mode, the text are wrapped to the screen - // width matching mWebView.mLastScale. So that we don't trigger - // re-flow while toggling between overview mode and normal mode. - nativeSetSize(width, Math.round((float) width * h / w), - Math.round(mWebView.mInZoomOverview ? w * scale - / mWebView.mLastScale : w), scale, w, h); - } else { - nativeSetSize(w, h, w, scale, w, h); } + nativeSetSize(width, width == w ? h : Math.round((float) width * h / w), + textwrapWidth, scale, w, h); // Remember the current width and height boolean needInvalidate = (mCurrentViewWidth == 0); mCurrentViewWidth = w; mCurrentViewHeight = h; + mCurrentViewScale = scale; if (needInvalidate) { // ensure {@link #webkitDraw} is called as we were blocking in // {@link #contentDraw} when mCurrentViewWidth is 0 @@ -1490,15 +1482,30 @@ final class WebViewCore { // Used to end scale+scroll mode, accessed by both threads boolean mEndScaleZoom = false; - public class DrawData { - public DrawData() { + // mRestoreState is set in didFirstLayout(), and reset in the next + // webkitDraw after passing it to the UI thread. + private RestoreState mRestoreState = null; + + static class RestoreState { + float mMinScale; + float mMaxScale; + float mViewScale; + float mTextWrapScale; + int mScrollX; + int mScrollY; + } + + static class DrawData { + DrawData() { mInvalRegion = new Region(); mWidthHeight = new Point(); } - public Region mInvalRegion; - public Point mViewPoint; - public Point mWidthHeight; - public int mMinPrefWidth; + Region mInvalRegion; + Point mViewPoint; + Point mWidthHeight; + int mMinPrefWidth; + RestoreState mRestoreState; // only non-null if it is for the first + // picture set after the first layout } private void webkitDraw() { @@ -1517,6 +1524,10 @@ final class WebViewCore { if (WebView.ENABLE_DOUBLETAP_ZOOM && mSettings.getUseWideViewPort()) { draw.mMinPrefWidth = nativeGetContentMinPrefWidth(); } + if (mRestoreState != null) { + draw.mRestoreState = mRestoreState; + mRestoreState = null; + } if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID"); Message.obtain(mWebView.mPrivateHandler, WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget(); @@ -1527,9 +1538,6 @@ final class WebViewCore { mWebkitScrollY).sendToTarget(); mWebkitScrollX = mWebkitScrollY = 0; } - // nativeSnapToAnchor() needs to be called after NEW_PICTURE_MSG_ID - // is sent, so that scroll will be based on the new content size. - nativeSnapToAnchor(); } } @@ -1751,17 +1759,8 @@ final class WebViewCore { // called by JNI private void didFirstLayout(boolean standardLoad) { - // Trick to ensure that the Picture has the exact height for the content - // by forcing to layout with 0 height after the page is ready, which is - // indicated by didFirstLayout. This is essential to get rid of the - // white space in the GMail which uses WebView for message view. - if (mWebView != null && mWebView.mHeightCanMeasure) { - mWebView.mLastHeightSent = 0; - // Send a negative scale to indicate that WebCore should reuse the - // current scale - mEventHub.sendMessage(Message.obtain(null, - EventHub.VIEW_SIZE_CHANGED, mWebView.mLastWidthSent, - mWebView.mLastHeightSent, -1.0f)); + if (DebugFlags.WEB_VIEW_CORE) { + Log.v(LOGTAG, "didFirstLayout standardLoad =" + standardLoad); } mBrowserFrame.didFirstLayout(); @@ -1769,6 +1768,9 @@ final class WebViewCore { // reset the scroll position as it is a new page now mWebkitScrollX = mWebkitScrollY = 0; + // for non-standard load, we only adjust scale if mRestoredScale > 0 + if (mWebView == null || (mRestoredScale == 0 && !standardLoad)) return; + // set the viewport settings from WebKit setViewportSettingsFromNative(); @@ -1820,47 +1822,74 @@ final class WebViewCore { } // now notify webview - if (mWebView != null) { - WebView.ScaleLimitData scaleLimit = new WebView.ScaleLimitData(); - scaleLimit.mMinScale = mViewportMinimumScale; - scaleLimit.mMaxScale = mViewportMaximumScale; - - if (mRestoredScale > 0) { - Message.obtain(mWebView.mPrivateHandler, - WebView.DID_FIRST_LAYOUT_MSG_ID, - mRestoredScreenWidthScale > 0 ? - -mRestoredScreenWidthScale : mRestoredScale, 0, - scaleLimit).sendToTarget(); + int webViewWidth = Math.round(mCurrentViewWidth * mCurrentViewScale); + mRestoreState = new RestoreState(); + mRestoreState.mMinScale = mViewportMinimumScale / 100.0f; + mRestoreState.mMaxScale = mViewportMaximumScale / 100.0f; + mRestoreState.mScrollX = mRestoredX; + mRestoreState.mScrollY = mRestoredY; + if (mRestoredScale > 0) { + if (mRestoredScreenWidthScale > 0) { + mRestoreState.mTextWrapScale = + mRestoredScreenWidthScale / 100.0f; + // 0 will trigger WebView to turn on zoom overview mode + mRestoreState.mViewScale = 0; } else { - // if standardLoad is true, use mViewportInitialScale, otherwise - // pass -1 to the WebView to indicate no change of the scale. - Message.obtain(mWebView.mPrivateHandler, - WebView.DID_FIRST_LAYOUT_MSG_ID, - standardLoad ? mViewportInitialScale : -1, - mViewportWidth, scaleLimit).sendToTarget(); + mRestoreState.mViewScale = mRestoreState.mTextWrapScale = + mRestoredScale / 100.0f; } - - // force an early draw for quick feedback after the first layout - if (mCurrentViewWidth != 0) { - synchronized (this) { - if (mDrawIsScheduled) { - mEventHub.removeMessages(EventHub.WEBKIT_DRAW); - } - mDrawIsScheduled = true; - // if no restored offset, move the new page to (0, 0) - mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null, - EventHub.MESSAGE_RELAY, Message.obtain( - mWebView.mPrivateHandler, - WebView.SCROLL_TO_MSG_ID, mRestoredX, - mRestoredY))); - mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null, - EventHub.WEBKIT_DRAW)); - } + } else { + if (mViewportInitialScale > 0) { + mRestoreState.mViewScale = mRestoreState.mTextWrapScale = + mViewportInitialScale / 100.0f; + } else if (mViewportWidth > 0 && mViewportWidth < webViewWidth) { + mRestoreState.mViewScale = mRestoreState.mTextWrapScale = + (float) webViewWidth / mViewportWidth; + } else { + mRestoreState.mTextWrapScale = + WebView.DEFAULT_SCALE_PERCENT / 100.0f; + // 0 will trigger WebView to turn on zoom overview mode + mRestoreState.mViewScale = 0; } - - // reset restored offset, scale - mRestoredX = mRestoredY = mRestoredScale = mRestoredScreenWidthScale = 0; } + + if (mWebView.mHeightCanMeasure) { + // Trick to ensure that the Picture has the exact height for the + // content by forcing to layout with 0 height after the page is + // ready, which is indicated by didFirstLayout. This is essential to + // get rid of the white space in the GMail which uses WebView for + // message view. + mWebView.mLastHeightSent = 0; + // Send a negative scale to indicate that WebCore should reuse + // the current scale + WebView.ViewSizeData data = new WebView.ViewSizeData(); + data.mWidth = mWebView.mLastWidthSent; + data.mHeight = 0; + // if mHeightCanMeasure is true, getUseWideViewPort() can't be + // true. It is safe to use mWidth for mTextWrapWidth. + data.mTextWrapWidth = data.mWidth; + data.mScale = -1.0f; + mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null, + EventHub.VIEW_SIZE_CHANGED, data)); + } else if (mSettings.getUseWideViewPort() && mCurrentViewWidth > 0) { + WebView.ViewSizeData data = new WebView.ViewSizeData(); + // mViewScale as 0 means it is in zoom overview mode. So we don't + // know the exact scale. If mRestoredScale is non-zero, use it; + // otherwise just use mTextWrapScale as the initial scale. + data.mScale = mRestoreState.mViewScale == 0 + ? (mRestoredScale > 0 ? mRestoredScale + : mRestoreState.mTextWrapScale) + : mRestoreState.mViewScale; + data.mWidth = Math.round(webViewWidth / data.mScale); + data.mHeight = mCurrentViewHeight * data.mWidth + / mCurrentViewWidth; + data.mTextWrapWidth = Math.round(webViewWidth + / mRestoreState.mTextWrapScale); + mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null, + EventHub.VIEW_SIZE_CHANGED, data)); + } + // reset restored offset, scale + mRestoredX = mRestoredY = mRestoredScale = mRestoredScreenWidthScale = 0; } // called by JNI diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java index a26bfa2..47f5c6c 100644 --- a/core/java/android/widget/TabWidget.java +++ b/core/java/android/widget/TabWidget.java @@ -277,7 +277,7 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener { if (child.getLayoutParams() == null) { final LinearLayout.LayoutParams lp = new LayoutParams( 0, - ViewGroup.LayoutParams.WRAP_CONTENT, 1); + ViewGroup.LayoutParams.FILL_PARENT, 1.0f); lp.setMargins(0, 0, 0, 0); child.setLayoutParams(lp); } @@ -289,10 +289,10 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener { // If we have dividers between the tabs and we already have at least one // tab, then add a divider before adding the next tab. if (mDividerDrawable != null && getTabCount() > 0) { - View divider = new View(mContext); + ImageView divider = new ImageView(mContext); final LinearLayout.LayoutParams lp = new LayoutParams( mDividerDrawable.getIntrinsicWidth(), - mDividerDrawable.getIntrinsicHeight()); + LayoutParams.FILL_PARENT); lp.setMargins(0, 0, 0, 0); divider.setLayoutParams(lp); divider.setBackgroundDrawable(mDividerDrawable); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 0421612..591f9bb 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -6916,6 +6916,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } + boolean hasLetter = false; + for (int i = start; i < end; i++) { + if (Character.isLetter(mTransformed.charAt(i))) { + hasLetter = true; + break; + } + } + if (!hasLetter) { + return null; + } + if (start == end) { return null; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 1cd04f1..5f94ee5 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1130,6 +1130,16 @@ android:exported="true"> </activity> + <activity android:name="com.android.server.ShutdownActivity" + android:permission="android.permission.SHUTDOWN" + android:excludeFromRecents="true" + android:multiprocess="true"> + <intent-filter> + <action android:name="android.intent.action.ACTION_REQUEST_SHUTDOWN" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + <service android:name="com.android.server.LoadAverageService" android:exported="true" /> diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h index ad27903..13316a9 100644 --- a/include/media/mediarecorder.h +++ b/include/media/mediarecorder.h @@ -93,10 +93,6 @@ enum video_encoder { VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type }; - -// Maximum frames per second is 24 -#define MEDIA_RECORDER_MAX_FRAME_RATE 24 - /* * The state machine of the media_recorder uses a set of different state names. * The mapping between the media_recorder and the pvauthorengine is shown below: diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java index 1de007d..b1b78ea 100644 --- a/keystore/java/android/security/CertTool.java +++ b/keystore/java/android/security/CertTool.java @@ -140,7 +140,7 @@ public class CertTool { private void addExtraIntentInfo(Intent intent, String namespace, String data) { - intent.putExtra(KEY_ITEM + "1", data); + intent.putExtra(KEY_ITEM + "1", data.getBytes()); intent.putExtra(KEY_NAMESPACE + "1", namespace); } diff --git a/keystore/jni/cert.c b/keystore/jni/cert.c index ea21b7d..006a0a3 100644 --- a/keystore/jni/cert.c +++ b/keystore/jni/cert.c @@ -46,7 +46,7 @@ static void save_in_store(EVP_PKEY *pkey) RSA *rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_set1_RSA(newpkey, rsa); PKEY_STORE_free(pkey_store[store_index]); - pkey_store[store_index].key_len = i2d_RSAPublicKey(rsa, &pkey_store[store_index].public_key); + pkey_store[store_index].key_len = i2d_RSA_PUBKEY(rsa, &pkey_store[store_index].public_key); pkey_store[store_index++].pkey = newpkey; store_index %= KEYGEN_STORE_SIZE; RSA_free(rsa); diff --git a/libs/rs/java/Film/res/drawable/p01.png b/libs/rs/java/Film/res/drawable/p01.png Binary files differnew file mode 100644 index 0000000..a9b9bdb --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p01.png diff --git a/libs/rs/java/Film/res/drawable/p02.png b/libs/rs/java/Film/res/drawable/p02.png Binary files differnew file mode 100644 index 0000000..8162c82 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p02.png diff --git a/libs/rs/java/Film/res/drawable/p03.png b/libs/rs/java/Film/res/drawable/p03.png Binary files differnew file mode 100644 index 0000000..e3e26c0 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p03.png diff --git a/libs/rs/java/Film/res/drawable/p04.png b/libs/rs/java/Film/res/drawable/p04.png Binary files differnew file mode 100644 index 0000000..daee603 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p04.png diff --git a/libs/rs/java/Film/res/drawable/p05.png b/libs/rs/java/Film/res/drawable/p05.png Binary files differnew file mode 100644 index 0000000..fac5248 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p05.png diff --git a/libs/rs/java/Film/res/drawable/p06.png b/libs/rs/java/Film/res/drawable/p06.png Binary files differnew file mode 100644 index 0000000..3b51261 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p06.png diff --git a/libs/rs/java/Film/res/drawable/p07.png b/libs/rs/java/Film/res/drawable/p07.png Binary files differnew file mode 100644 index 0000000..d8bd938 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p07.png diff --git a/libs/rs/java/Film/res/drawable/p08.png b/libs/rs/java/Film/res/drawable/p08.png Binary files differnew file mode 100644 index 0000000..ef175e8 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p08.png diff --git a/libs/rs/java/Film/res/drawable/p09.png b/libs/rs/java/Film/res/drawable/p09.png Binary files differnew file mode 100644 index 0000000..7bf3874 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p09.png diff --git a/libs/rs/java/Film/res/drawable/p10.png b/libs/rs/java/Film/res/drawable/p10.png Binary files differnew file mode 100644 index 0000000..908827d --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p10.png diff --git a/libs/rs/java/Film/res/drawable/p11.png b/libs/rs/java/Film/res/drawable/p11.png Binary files differnew file mode 100644 index 0000000..1289f71 --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p11.png diff --git a/libs/rs/java/Film/res/drawable/p12.png b/libs/rs/java/Film/res/drawable/p12.png Binary files differnew file mode 100644 index 0000000..e1af16a --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p12.png diff --git a/libs/rs/java/Film/res/drawable/p13.png b/libs/rs/java/Film/res/drawable/p13.png Binary files differnew file mode 100644 index 0000000..d08bcbe --- /dev/null +++ b/libs/rs/java/Film/res/drawable/p13.png diff --git a/libs/rs/java/Film/res/raw/filmstrip.c b/libs/rs/java/Film/res/raw/filmstrip.c index 495fe55..ac694ab 100644 --- a/libs/rs/java/Film/res/raw/filmstrip.c +++ b/libs/rs/java/Film/res/raw/filmstrip.c @@ -47,8 +47,8 @@ int main(int index) // Start of images. - bindProgramFragmentStore(NAMED_PFImages); - bindProgramFragment(NAMED_PFSImages); + bindProgramFragmentStore(NAMED_PFSImages); + bindProgramFragment(NAMED_PFImages); bindProgramVertex(NAMED_PVImages); float focusPos = loadF(1, POS_FOCUS); @@ -87,7 +87,16 @@ int main(int index) offset = offset + triangleOffsetsCount / 2; - if (!((offset < 0) || (offset >= triangleOffsetsCount))) { + int drawit = 1; + if (offset < 0) { + drawit = 0; + } + if (offset >= triangleOffsetsCount) { + drawit = 0; + } + + //if (!((offset < 0) || (offset >= triangleOffsetsCount))) { + if (drawit) { int start = offset -2; int end = offset + 2; @@ -99,11 +108,9 @@ int main(int index) } bindTexture(NAMED_PFImages, 0, loadI32(0, imgId - 1)); - /* - matrixLoadTranslate(con, &m, -pos - env->triangleOffsetsTex[env->triangleOffsetsCount / 2], 0, 0); - storeEnvMatrix(con, 3, RS_PROGRAM_VERTEX_TEXTURE_OFFSET, &m); - renderTriangleMeshRange(con, env->mesh, env->triangleOffsets[start], env->triangleOffsets[end] - env->triangleOffsets[start]); - */ + matrixLoadTranslate(&f16, -pos - loadF(5, triangleOffsetsCount / 2), 0, 0); + vpLoadTextureMatrix(&f16); + drawTriangleMeshRange(NAMED_mesh, loadI32(4, start), loadI32(4, end) - loadI32(4, start)); } } return 0; diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java index 395bd35..a639c55 100644 --- a/libs/rs/java/Film/src/com/android/film/FilmRS.java +++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java @@ -18,10 +18,6 @@ package com.android.film; import java.io.Writer; -import android.renderscript.RenderScript; -import android.renderscript.ProgramVertexAlloc; -import android.renderscript.Matrix; - import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; @@ -30,13 +26,17 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; +import android.renderscript.Matrix; +import android.renderscript.ProgramVertexAlloc; +import android.renderscript.RenderScript; +import android.renderscript.RenderScript.ElementPredefined; import android.util.AttributeSet; import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; -import android.view.KeyEvent; -import android.view.MotionEvent; public class FilmRS { private final int POS_TRANSLATE = 0; @@ -67,7 +67,7 @@ public class FilmRS { float anim = ((float)x-50) / 270.f; mBufferPos[POS_TRANSLATE] = 2f * anim + 0.5f; // translation mBufferPos[POS_ROTATE] = (anim * 40); // rotation - mBufferPos[POS_FOCUS] = ((float)y) / 16.f - 8; // focusPos + mBufferPos[POS_FOCUS] = ((float)y) / 16.f - 10.f; // focusPos mAllocPos.data(mBufferPos); } @@ -92,6 +92,9 @@ public class FilmRS { private RenderScript.Allocation mAllocPos; private RenderScript.Allocation mAllocState; private RenderScript.Allocation mAllocPV; + private RenderScript.Allocation mAllocOffsetsTex; + private RenderScript.Allocation mAllocOffsets; + private RenderScript.TriangleMesh mMesh; private RenderScript.Light mLight; @@ -101,21 +104,11 @@ public class FilmRS { private float[] mBufferPos = new float[3]; private int[] mBufferState; - private void initSamplers() { - mRS.samplerBegin(); - mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN, - RenderScript.SamplerValue.LINEAR_MIP_LINEAR); - mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_S, - RenderScript.SamplerValue.CLAMP); - mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_T, - RenderScript.SamplerValue.CLAMP); - mSampler = mRS.samplerCreate(); - } - private void initPFS() { mRS.programFragmentStoreBegin(null, null); mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.LESS); mRS.programFragmentStoreDitherEnable(true); + mRS.programFragmentStoreDepthMask(true); mPFSBackground = mRS.programFragmentStoreCreate(); mPFSBackground.setName("PFSBackground"); @@ -130,15 +123,27 @@ public class FilmRS { } private void initPF() { + mRS.samplerBegin(); + mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN, + RenderScript.SamplerValue.LINEAR);//_MIP_LINEAR); + mRS.samplerSet(RenderScript.SamplerParam.FILTER_MAG, + RenderScript.SamplerValue.LINEAR); + mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_S, + RenderScript.SamplerValue.CLAMP); + mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_T, + RenderScript.SamplerValue.WRAP); + mSampler = mRS.samplerCreate(); + + mRS.programFragmentBegin(null, null); mPFBackground = mRS.programFragmentCreate(); mPFBackground.setName("PFBackground"); mRS.programFragmentBegin(null, null); mRS.programFragmentSetTexEnable(0, true); - //mRS.programFragmentSetEnvMode(0, RS_TEX_ENV_MODE_REPLACE); - //rsProgramFragmentSetType(0, gEnv.tex[0]->getType()); + mRS.programFragmentSetTexEnvMode(0, RenderScript.EnvMode.REPLACE); mPFImages = mRS.programFragmentCreate(); + mPFImages.bindSampler(mSampler, 0); mPFImages.setName("PFImages"); } @@ -148,12 +153,12 @@ public class FilmRS { mLight.setPosition(0, -0.5f, -1.0f); mRS.programVertexBegin(null, null); - mRS.programVertexSetTextureMatrixEnable(true); mRS.programVertexAddLight(mLight); mPVBackground = mRS.programVertexCreate(); mPVBackground.setName("PVBackground"); mRS.programVertexBegin(null, null); + mRS.programVertexSetTextureMatrixEnable(true); mPVImages = mRS.programVertexCreate(); mPVImages.setName("PVImages"); } @@ -170,44 +175,47 @@ public class FilmRS { BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inScaled = false; + RenderScript.ElementPredefined ie = + RenderScript.ElementPredefined.RGB_565; + b = BitmapFactory.decodeResource(mRes, R.drawable.p01, opts); - mImages[0] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[0] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p02, opts); - mImages[1] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[1] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p03, opts); - mImages[2] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[2] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p04, opts); - mImages[3] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[3] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p05, opts); - mImages[4] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[4] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p06, opts); - mImages[5] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[5] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p07, opts); - mImages[6] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[6] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p08, opts); - mImages[7] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[7] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p09, opts); - mImages[8] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[8] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p10, opts); - mImages[9] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[9] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p11, opts); - mImages[10] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[10] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p12, opts); - mImages[11] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[11] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); b = BitmapFactory.decodeResource(mRes, R.drawable.p13, opts); - mImages[12] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true); + mImages[12] = mRS.allocationCreateFromBitmapBoxed(b, ie, true); for(int ct=0; ct < mImages.length; ct++) { mImages[ct].uploadToTexture(1); @@ -242,10 +250,8 @@ public class FilmRS { mMesh.setName("mesh"); initPFS(); - initSamplers(); initPF(); initPV(); - mPFImages.bindSampler(mSampler, 0); Log.e("rs", "Done loading named"); @@ -274,28 +280,19 @@ public class FilmRS { mScriptStrip.bindAllocation(mPVA.mAlloc, 3); -/* - { - Resources res = getResources(); - Drawable d = res.getDrawable(R.drawable.gadgets_clock_mp3); - BitmapDrawable bd = (BitmapDrawable)d; - Bitmap b = bd.getBitmap(); - mTexture = mRS.allocationCreateFromBitmap(b, - RenderScript.ElementPredefined.RGB_565, - true); - mTexture.uploadToTexture(0); - } + mAllocOffsets = mRS.allocationCreatePredefSized( + RenderScript.ElementPredefined.USER_I32, + mFSM.mTriangleOffsets.length); + mAllocOffsets.data(mFSM.mTriangleOffsets); + mScriptStrip.bindAllocation(mAllocOffsets, 4); - mRS.programFragmentStoreBegin(null, null); - mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.SRC_ALPHA, RenderScript.BlendDstFunc.ONE); - mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.ALWAYS); - mPFS = mRS.programFragmentStoreCreate(); - mPFS.setName("MyBlend"); - mRS.contextBindProgramFragmentStore(mPFS); - */ + mAllocOffsetsTex = mRS.allocationCreatePredefSized( + RenderScript.ElementPredefined.USER_FLOAT, + mFSM.mTriangleOffsetsTex.length); + mAllocOffsetsTex.data(mFSM.mTriangleOffsetsTex); + mScriptStrip.bindAllocation(mAllocOffsetsTex, 5); setFilmStripPosition(0, 0); - mRS.contextBindRootScript(mScriptStrip); } } diff --git a/libs/rs/java/Film/src/com/android/film/FilmView.java b/libs/rs/java/Film/src/com/android/film/FilmView.java index a743b1b..73b7414 100644 --- a/libs/rs/java/Film/src/com/android/film/FilmView.java +++ b/libs/rs/java/Film/src/com/android/film/FilmView.java @@ -74,7 +74,7 @@ public class FilmView extends RSSurfaceView { if (act == ev.ACTION_UP) { ret = false; } - mRender.setFilmStripPosition((int)ev.getX(), (int)ev.getY()); + mRender.setFilmStripPosition((int)ev.getX(), (int)ev.getY() / 5); return ret; } } diff --git a/libs/rs/java/Rollo/res/raw/rollo.c b/libs/rs/java/Rollo/res/raw/rollo.c index 9e03a44..8763a34 100644 --- a/libs/rs/java/Rollo/res/raw/rollo.c +++ b/libs/rs/java/Rollo/res/raw/rollo.c @@ -80,15 +80,15 @@ int main(void* con, int ft, int launchID) float tmpCos = cosf(rot); //debugF("rot", rot); - float tx1 = tmpSin * diam - (tmpCos * scale); - float tx2 = tx1 + (tmpCos * scale * 2.f); - float tz1 = tmpCos * diam + (tmpSin * scale); - float tz2 = tz1 - (tmpSin * scale * 2.f); + float tx1 = tmpSin * diam - (tmpCos * scale * 0.9f); + float tx2 = tx1 + (tmpCos * scale * 1.8f); + float tz1 = tmpCos * diam + (tmpSin * scale * 0.9f); + float tz2 = tz1 - (tmpSin * scale * 1.8f); int y; for (y = rowCount -1; (y >= 0) && iconCount; y--) { float ty1 = ((y * 3.1f) - 5.f) * scale; - float ty2 = ty1 + scale * 2.f; + float ty2 = ty1 + scale * 1.8f; bindTexture(NAMED_PF, 0, loadI32(1, index)); //if (done && (index != selectedID)) { //color(0.4f, 0.4f, 0.4f, 1.0f); diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java index 520e3e4..c080176 100644 --- a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java +++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java @@ -200,9 +200,6 @@ public class RolloRS { mRS.contextBindProgramVertex(mPV); mAllocScratchBuf = new int[32]; - for(int ct=0; ct < mAllocScratchBuf.length; ct++) { - mAllocScratchBuf[ct] = 0; - } mAllocScratch = mRS.allocationCreatePredefSized( RenderScript.ElementPredefined.USER_I32, mAllocScratchBuf.length); mAllocScratch.data(mAllocScratchBuf); @@ -249,63 +246,63 @@ public class RolloRS { mLabels[3] = makeTextBitmap("settings"); b = BitmapFactory.decodeResource(mRes, R.raw.calendar, opts); - mIcons[4] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[4] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[4] = makeTextBitmap("creed"); b = BitmapFactory.decodeResource(mRes, R.raw.g1155, opts); - mIcons[5] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[5] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[5] = makeTextBitmap("BOA"); b = BitmapFactory.decodeResource(mRes, R.raw.g2140, opts); - mIcons[6] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[6] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[6] = makeTextBitmap("chess"); b = BitmapFactory.decodeResource(mRes, R.raw.maps, opts); - mIcons[7] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[7] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[7] = makeTextBitmap("Dictionary"); b = BitmapFactory.decodeResource(mRes, R.raw.path431, opts); - mIcons[8] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[8] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[8] = makeTextBitmap("facebook"); b = BitmapFactory.decodeResource(mRes, R.raw.path676, opts); - mIcons[9] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[9] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[9] = makeTextBitmap("Flash Light"); b = BitmapFactory.decodeResource(mRes, R.raw.path754, opts); - mIcons[10] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[10] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[10] = makeTextBitmap("Flight Control"); b = BitmapFactory.decodeResource(mRes, R.raw.path815, opts); - mIcons[11] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[11] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[11] = makeTextBitmap("google earth"); b = BitmapFactory.decodeResource(mRes, R.raw.path1920, opts); - mIcons[12] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[12] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[12] = makeTextBitmap("Harry Potter"); b = BitmapFactory.decodeResource(mRes, R.raw.path1927, opts); - mIcons[13] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[13] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[13] = makeTextBitmap("Movies"); b = BitmapFactory.decodeResource(mRes, R.raw.path3099, opts); - mIcons[14] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[14] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[14] = makeTextBitmap("NY Times"); b = BitmapFactory.decodeResource(mRes, R.raw.path3950, opts); - mIcons[15] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[15] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[15] = makeTextBitmap("Pandora"); b = BitmapFactory.decodeResource(mRes, R.raw.path4481, opts); - mIcons[16] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[16] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[16] = makeTextBitmap("Public Radio"); b = BitmapFactory.decodeResource(mRes, R.raw.path5168, opts); - mIcons[17] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[17] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[17] = makeTextBitmap("Public Radio"); b = BitmapFactory.decodeResource(mRes, R.raw.polygon2408, opts); - mIcons[18] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true); + mIcons[18] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); mLabels[18] = makeTextBitmap("Public Radio"); /* @@ -405,7 +402,6 @@ public class RolloRS { tmp[ct * 32 + 31] = 0; } mIconPlate.data(tmp); - Log.e("xx", "plate"); mIconPlate.uploadToTexture(0); mIconPlate.setName("Plate"); mPFImages.bindTexture(mIconPlate, 0); @@ -418,9 +414,9 @@ public class RolloRS { Canvas c = new Canvas(b); Paint p = new Paint(); p.setTypeface(Typeface.DEFAULT_BOLD); - p.setTextSize(16); + p.setTextSize(20); p.setColor(0xffffffff); - c.drawText(t, 2, 20, p); + c.drawText(t, 2, 26, p); return mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true); } diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index c6a9149..ca277ef 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -377,9 +377,9 @@ RsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint3 const uint8_t * src = static_cast<const uint8_t *>(data); for (uint32_t y = 0; y < h; y++) { - uint8_t * ydst = &tmp[y + ((h2 - h) >> 1)]; + uint8_t * ydst = &tmp[(y + ((h2 - h) >> 1)) * w2 * bpp]; memcpy(&ydst[(w2 - w) >> 1], src, w * bpp); - src += h * bpp; + src += w * bpp; } RsAllocation ret = rsi_AllocationCreateFromBitmap(rsc, w2, h2, dstFmt, srcFmt, genMips, tmp); diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index 4121906..7db3619 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -497,9 +497,9 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = { "void", "(int, int, int)" }, // vp - { "vpLoadModelMatrix", (void *)&SC_bindProgramFragment, + { "vpLoadModelMatrix", (void *)&SC_vpLoadModelMatrix, "void", "(void *)" }, - { "vpLoadTextureMatrix", (void *)&SC_bindProgramFragmentStore, + { "vpLoadTextureMatrix", (void *)&SC_vpLoadTextureMatrix, "void", "(void *)" }, diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index a841ab3..fbce73d 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -461,7 +461,8 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const glRotatef(-90, 0, 0, 1); } - if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { + if (!(mFlags & (DisplayHardware::NPOT_EXTENSION | + DisplayHardware::DIRECT_TEXTURE))) { // find the smallest power-of-two that will accommodate our surface GLuint tw = 1 << (31 - clz(width)); GLuint th = 1 << (31 - clz(height)); diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp index 92a9a86..4add8f9 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -65,7 +65,7 @@ status_t BufferMapper::lock(buffer_handle_t handle, { status_t err = mAllocMod->lock(mAllocMod, handle, usage, bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr); - LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); + LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err)); return err; } diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp index 0273a5a..304f521 100644 --- a/media/jni/android_media_MediaRecorder.cpp +++ b/media/jni/android_media_MediaRecorder.cpp @@ -276,7 +276,7 @@ static void android_media_MediaRecorder_setVideoFrameRate(JNIEnv *env, jobject thiz, jint rate) { LOGV("setVideoFrameRate(%d)", rate); - if (rate <= 0 || rate > MEDIA_RECORDER_MAX_FRAME_RATE) { + if (rate <= 0) { jniThrowException(env, "java/lang/IllegalArgumentException", "invalid frame rate"); return; } diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index c33bdd7..6b20445 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -22,6 +22,7 @@ <bool name="def_airplane_mode_on">false</bool> <!-- Comma-separated list of bluetooth, wifi, and cell. --> <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi</string> + <string name="airplane_mode_toggleable_radios" translatable="false">wifi</string> <bool name="def_auto_time">true</bool> <bool name="def_accelerometer_rotation">true</bool> <!-- Default screen brightness, from 0 to 255. 102 is 40%. --> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index f00fd39..835c683 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -64,7 +64,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "SettingsProvider"; private static final String DATABASE_NAME = "settings.db"; - private static final int DATABASE_VERSION = 37; + private static final int DATABASE_VERSION = 38; private Context mContext; @@ -435,6 +435,21 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 36; } + if (upgradeVersion == 37) { + db.beginTransaction(); + try { + SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" + + " VALUES(?,?);"); + loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS, + R.string.airplane_mode_toggleable_radios); + stmt.close(); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + upgradeVersion = 38; + } + if (upgradeVersion != currentVersion) { Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion + ", must wipe the settings provider"); @@ -662,6 +677,9 @@ public class DatabaseHelper extends SQLiteOpenHelper { loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS, R.string.def_airplane_mode_radios); + loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS, + R.string.airplane_mode_toggleable_radios); + loadBooleanSetting(stmt, Settings.System.AUTO_TIME, R.bool.def_auto_time); // Sync time to NITZ diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java index 6832862..1b99d32 100755 --- a/packages/TtsService/src/android/tts/TtsService.java +++ b/packages/TtsService/src/android/tts/TtsService.java @@ -194,7 +194,7 @@ public class TtsService extends Service implements OnCompletionListener { private boolean isDefaultEnforced() { return (android.provider.Settings.Secure.getInt(mResolver, android.provider.Settings.Secure.TTS_USE_DEFAULTS, - TextToSpeech.Engine.FALLBACK_TTS_USE_DEFAULTS) + TextToSpeech.Engine.USE_DEFAULTS) == 1 ); } @@ -202,7 +202,7 @@ public class TtsService extends Service implements OnCompletionListener { private int getDefaultRate() { return android.provider.Settings.Secure.getInt(mResolver, android.provider.Settings.Secure.TTS_DEFAULT_RATE, - TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_RATE); + TextToSpeech.Engine.DEFAULT_RATE); } @@ -346,7 +346,7 @@ public class TtsService extends Service implements OnCompletionListener { */ private int speak(String callingApp, String text, int queueMode, ArrayList<String> params) { Log.v("TtsService", "TTS service received " + text); - if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) { + if (queueMode == TextToSpeech.QUEUE_FLUSH) { stop(callingApp); } else if (queueMode == 2) { stopAll(callingApp); @@ -355,7 +355,7 @@ public class TtsService extends Service implements OnCompletionListener { if (!mIsSpeaking) { processSpeechQueue(); } - return TextToSpeech.TTS_SUCCESS; + return TextToSpeech.SUCCESS; } /** @@ -372,7 +372,7 @@ public class TtsService extends Service implements OnCompletionListener { */ private int playEarcon(String callingApp, String earcon, int queueMode, ArrayList<String> params) { - if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) { + if (queueMode == TextToSpeech.QUEUE_FLUSH) { stop(callingApp); } else if (queueMode == 2) { stopAll(callingApp); @@ -381,14 +381,14 @@ public class TtsService extends Service implements OnCompletionListener { if (!mIsSpeaking) { processSpeechQueue(); } - return TextToSpeech.TTS_SUCCESS; + return TextToSpeech.SUCCESS; } /** * Stops all speech output and removes any utterances still in the queue for the calling app. */ private int stop(String callingApp) { - int result = TextToSpeech.TTS_ERROR; + int result = TextToSpeech.ERROR; boolean speechQueueAvailable = false; try{ speechQueueAvailable = @@ -414,7 +414,7 @@ public class TtsService extends Service implements OnCompletionListener { mIsSpeaking = false; mCurrentSpeechItem = null; } else { - result = TextToSpeech.TTS_SUCCESS; + result = TextToSpeech.SUCCESS; } Log.i("TtsService", "Stopped"); } @@ -437,7 +437,7 @@ public class TtsService extends Service implements OnCompletionListener { * Stops all speech output and removes any utterances still in the queue globally. */ private int stopAll(String callingApp) { - int result = TextToSpeech.TTS_ERROR; + int result = TextToSpeech.ERROR; boolean speechQueueAvailable = false; try{ speechQueueAvailable = @@ -463,7 +463,7 @@ public class TtsService extends Service implements OnCompletionListener { mIsSpeaking = false; mCurrentSpeechItem = null; } else { - result = TextToSpeech.TTS_SUCCESS; + result = TextToSpeech.SUCCESS; } Log.i("TtsService", "Stopped all"); } @@ -487,7 +487,7 @@ public class TtsService extends Service implements OnCompletionListener { if (params != null){ for (int i = 0; i < params.size() - 1; i = i + 2){ String param = params.get(i); - if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){ + if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){ utteranceId = params.get(i+1); } } @@ -500,14 +500,14 @@ public class TtsService extends Service implements OnCompletionListener { private int playSilence(String callingApp, long duration, int queueMode, ArrayList<String> params) { - if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) { + if (queueMode == TextToSpeech.QUEUE_FLUSH) { stop(callingApp); } mSpeechQueue.add(new SpeechItem(callingApp, duration, params)); if (!mIsSpeaking) { processSpeechQueue(); } - return TextToSpeech.TTS_SUCCESS; + return TextToSpeech.SUCCESS; } private void silence(final SpeechItem speechItem) { @@ -517,7 +517,7 @@ public class TtsService extends Service implements OnCompletionListener { if (speechItem.mParams != null){ for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){ String param = speechItem.mParams.get(i); - if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){ + if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){ utteranceId = speechItem.mParams.get(i+1); } } @@ -562,17 +562,17 @@ public class TtsService extends Service implements OnCompletionListener { for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){ String param = speechItem.mParams.get(i); if (param != null) { - if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_RATE)) { + if (param.equals(TextToSpeech.Engine.KEY_PARAM_RATE)) { speechRate = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_LANGUAGE)){ + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_LANGUAGE)){ language = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_COUNTRY)){ + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_COUNTRY)){ country = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){ + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_VARIANT)){ variant = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){ + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){ utteranceId = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_STREAM)) { + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_STREAM)) { try { streamType = Integer.parseInt(speechItem.mParams.get(i + 1)); @@ -638,15 +638,15 @@ public class TtsService extends Service implements OnCompletionListener { for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){ String param = speechItem.mParams.get(i); if (param != null) { - if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_RATE)) { + if (param.equals(TextToSpeech.Engine.KEY_PARAM_RATE)) { speechRate = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_LANGUAGE)){ + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_LANGUAGE)){ language = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_COUNTRY)){ + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_COUNTRY)){ country = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){ + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_VARIANT)){ variant = speechItem.mParams.get(i+1); - } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){ + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){ utteranceId = speechItem.mParams.get(i+1); } } @@ -698,7 +698,7 @@ public class TtsService extends Service implements OnCompletionListener { } private void broadcastTtsQueueProcessingCompleted(){ - Intent i = new Intent(Intent.ACTION_TTS_QUEUE_PROCESSING_COMPLETED); + Intent i = new Intent(TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED); sendBroadcast(i); } @@ -843,7 +843,7 @@ public class TtsService extends Service implements OnCompletionListener { } for (int i = 0; i < paramList.size() - 1; i = i + 2) { String param = paramList.get(i); - if ((param != null) && (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_STREAM))) { + if ((param != null) && (param.equals(TextToSpeech.Engine.KEY_PARAM_STREAM))) { try { streamType = Integer.parseInt(paramList.get(i + 1)); } catch (NumberFormatException e) { @@ -910,18 +910,18 @@ public class TtsService extends Service implements OnCompletionListener { if (cb != null) { mCallbacks.register(cb); mCallbacksMap.put(packageName, cb); - return TextToSpeech.TTS_SUCCESS; + return TextToSpeech.SUCCESS; } - return TextToSpeech.TTS_ERROR; + return TextToSpeech.ERROR; } public int unregisterCallback(String packageName, ITtsCallback cb) { if (cb != null) { mCallbacksMap.remove(packageName); mCallbacks.unregister(cb); - return TextToSpeech.TTS_SUCCESS; + return TextToSpeech.SUCCESS; } - return TextToSpeech.TTS_ERROR; + return TextToSpeech.ERROR; } /** diff --git a/services/java/com/android/server/AccessibilityManagerService.java b/services/java/com/android/server/AccessibilityManagerService.java index 63c9eaa..55007ba 100644 --- a/services/java/com/android/server/AccessibilityManagerService.java +++ b/services/java/com/android/server/AccessibilityManagerService.java @@ -323,15 +323,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub */ private void notifyAccessibilityServicesDelayedLocked(AccessibilityEvent event, boolean isDefault) { - for (int i = 0, count = mServices.size(); i < count; i++) { - Service service = mServices.get(i); + try { + for (int i = 0, count = mServices.size(); i < count; i++) { + Service service = mServices.get(i); - if (service.mIsDefault == isDefault) { - if (canDispathEventLocked(service, event, mHandledFeedbackTypes)) { - mHandledFeedbackTypes |= service.mFeedbackType; - notifyAccessibilityServiceDelayedLocked(service, event); + if (service.mIsDefault == isDefault) { + if (canDispathEventLocked(service, event, mHandledFeedbackTypes)) { + mHandledFeedbackTypes |= service.mFeedbackType; + notifyAccessibilityServiceDelayedLocked(service, event); + } } } + } catch (IndexOutOfBoundsException oobe) { + // An out of bounds exception can happen if services are going away + // as the for loop is running. If that happens, just bail because + // there are no more services to notify. + return; } } diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/java/com/android/server/ShutdownActivity.java new file mode 100644 index 0000000..7f0e90d --- /dev/null +++ b/services/java/com/android/server/ShutdownActivity.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; +import com.android.internal.app.ShutdownThread; + +public class ShutdownActivity extends Activity { + + private static final String TAG = "ShutdownActivity"; + private boolean mConfirm; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mConfirm = getIntent().getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false); + Log.i(TAG, "onCreate(): confirm=" + mConfirm); + + Handler h = new Handler(); + h.post(new Runnable() { + public void run() { + ShutdownThread.shutdown(ShutdownActivity.this, mConfirm); + } + }); + } +} diff --git a/services/java/com/android/server/WallpaperService.java b/services/java/com/android/server/WallpaperService.java index 11981df..67b60a6 100644 --- a/services/java/com/android/server/WallpaperService.java +++ b/services/java/com/android/server/WallpaperService.java @@ -76,11 +76,10 @@ class WallpaperService extends IWallpaperService.Stub { WALLPAPER_DIR.getAbsolutePath(), CREATE | CLOSE_WRITE | DELETE | DELETE_SELF) { @Override public void onEvent(int event, String path) { + if (path == null) { + return; + } synchronized (mLock) { - if (path == null) { - return; - } - // changing the wallpaper means we'll need to back up the new one long origId = Binder.clearCallingIdentity(); BackupManager bm = new BackupManager(mContext); @@ -104,11 +103,9 @@ class WallpaperService extends IWallpaperService.Stub { public WallpaperService(Context context) { if (Config.LOGD) Log.d(TAG, "WallpaperService startup"); mContext = context; - if (!WALLPAPER_DIR.exists()) { - WALLPAPER_DIR.mkdirs(); - } - mWallpaperObserver.startWatching(); + WALLPAPER_DIR.mkdirs(); loadSettingsLocked(); + mWallpaperObserver.startWatching(); } @Override @@ -271,15 +268,15 @@ class WallpaperService extends IWallpaperService.Stub { } while (type != XmlPullParser.END_DOCUMENT); success = true; } catch (NullPointerException e) { - Log.w(TAG, "failed parsing " + file, e); + Log.w(TAG, "failed parsing " + file + " " + e); } catch (NumberFormatException e) { - Log.w(TAG, "failed parsing " + file, e); + Log.w(TAG, "failed parsing " + file + " " + e); } catch (XmlPullParserException e) { - Log.w(TAG, "failed parsing " + file, e); + Log.w(TAG, "failed parsing " + file + " " + e); } catch (IOException e) { - Log.w(TAG, "failed parsing " + file, e); + Log.w(TAG, "failed parsing " + file + " " + e); } catch (IndexOutOfBoundsException e) { - Log.w(TAG, "failed parsing " + file, e); + Log.w(TAG, "failed parsing " + file + " " + e); } try { if (stream != null) { diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index f25c221..d4e57d2 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -93,6 +93,9 @@ public class WifiService extends IWifiManager.Stub { private boolean mDeviceIdle; private int mPluggedType; + // true if the user enabled Wifi while in airplane mode + private boolean mAirplaneModeOverwridden; + private final LockList mLocks = new LockList(); // some wifi lock statistics private int mFullLocksAcquired; @@ -219,6 +222,8 @@ public class WifiService extends IWifiManager.Stub { new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { + // clear our flag indicating the user has overwridden airplane mode + mAirplaneModeOverwridden = false; updateWifiState(); } }, @@ -292,6 +297,8 @@ public class WifiService extends IWifiManager.Stub { synchronized (mWifiHandler) { sWakeLock.acquire(); mLastEnableUid = Binder.getCallingUid(); + // set a flag if the user is enabling Wifi while in airplane mode + mAirplaneModeOverwridden = (enable && isAirplaneModeOn() && isAirplaneToggleable()); sendEnableMessage(enable, true, Binder.getCallingUid()); } @@ -312,7 +319,7 @@ public class WifiService extends IWifiManager.Stub { if (mWifiState == eventualWifiState) { return true; } - if (enable && isAirplaneModeOn()) { + if (enable && isAirplaneModeOn() && !mAirplaneModeOverwridden) { return false; } @@ -1495,7 +1502,7 @@ public class WifiService extends IWifiManager.Stub { private void updateWifiState() { boolean wifiEnabled = getPersistedWifiEnabled(); - boolean airplaneMode = isAirplaneModeOn(); + boolean airplaneMode = isAirplaneModeOn() && !mAirplaneModeOverwridden; boolean lockHeld = mLocks.hasLocks(); int strongestLockMode; boolean wifiShouldBeEnabled = wifiEnabled && !airplaneMode; @@ -1559,6 +1566,13 @@ public class WifiService extends IWifiManager.Stub { || airplaneModeRadios.contains(Settings.System.RADIO_WIFI); } + private boolean isAirplaneToggleable() { + String toggleableRadios = Settings.System.getString(mContext.getContentResolver(), + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS); + return toggleableRadios != null + && toggleableRadios.contains(Settings.System.RADIO_WIFI); + } + /** * Returns true if Wi-Fi is sensitive to airplane mode, and airplane mode is * currently on. diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 7bd2532..552d5be 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -4766,6 +4766,34 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } + public void closeSystemDialogs(String reason) { + Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + if (reason != null) { + intent.putExtra("reason", reason); + } + + final int uid = Binder.getCallingUid(); + final long origId = Binder.clearCallingIdentity(); + synchronized (this) { + int i = mWatchers.beginBroadcast(); + while (i > 0) { + i--; + IActivityWatcher w = mWatchers.getBroadcastItem(i); + if (w != null) { + try { + w.closingSystemDialogs(reason); + } catch (RemoteException e) { + } + } + } + mWatchers.finishBroadcast(); + + broadcastIntentLocked(null, null, intent, null, + null, 0, null, null, null, false, false, -1, uid); + } + Binder.restoreCallingIdentity(origId); + } + private void restartPackageLocked(final String packageName, int uid) { uninstallPackageLocked(packageName, uid, false); Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java index 33e793b..5aed396 100644 --- a/services/java/com/android/server/status/StatusBarPolicy.java +++ b/services/java/com/android/server/status/StatusBarPolicy.java @@ -926,17 +926,16 @@ public class StatusBarPolicy { // Use Evdo icon evdoIconList = this.sSignalImages_evdo; - int evdoEcio = mSignalStrength.getEvdoEcio(); + int evdoDbm = mSignalStrength.getEvdoDbm(); int evdoSnr = mSignalStrength.getEvdoSnr(); - int levelEvdoEcio = 0; + int levelEvdoDbm = 0; int levelEvdoSnr = 0; - // Ec/Io are in dB*10 - if (evdoEcio >= -650) levelEvdoEcio = 4; - else if (evdoEcio >= -750) levelEvdoEcio = 3; - else if (evdoEcio >= -900) levelEvdoEcio = 2; - else if (evdoEcio >= -1050) levelEvdoEcio = 1; - else levelEvdoEcio = 0; + if (evdoDbm >= -65) levelEvdoDbm = 4; + else if (evdoDbm >= -75) levelEvdoDbm = 3; + else if (evdoDbm >= -90) levelEvdoDbm = 2; + else if (evdoDbm >= -105) levelEvdoDbm = 1; + else levelEvdoDbm = 0; if (evdoSnr > 7) levelEvdoSnr = 4; else if (evdoSnr > 5) levelEvdoSnr = 3; @@ -944,7 +943,7 @@ public class StatusBarPolicy { else if (evdoSnr > 1) levelEvdoSnr = 1; else levelEvdoSnr = 0; - evdoIconLevel = (levelEvdoEcio < levelEvdoSnr) ? levelEvdoEcio : levelEvdoSnr; + evdoIconLevel = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; mPhoneEvdoData.iconId = evdoIconList[evdoIconLevel]; mService.updateIcon(mPhoneEvdoIcon, mPhoneEvdoData, null); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index ba5c6e7..ed9af66 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -256,7 +256,7 @@ public class TelephonyManager { * No phone module * */ - public static final int PHONE_TYPE_NONE = 0; + public static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE; /** * GSM phone diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java index ebdac4e..c52fe06 100644 --- a/telephony/java/com/android/internal/telephony/CommandsInterface.java +++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java @@ -1225,8 +1225,10 @@ public interface CommandsInterface { * Request the device MDN / H_SID / H_NID / MIN. * "response" is const char ** * [0] is MDN if CDMA subscription is available - * [1] is H_SID (Home SID) in hexadecimal if CDMA subscription is available - * [2] is H_NID (Home NID) in hexadecimal if CDMA subscription is available + * [1] is a comma separated list of H_SID (Home SID) in decimal format + * if CDMA subscription is available + * [2] is a comma separated list of H_NID (Home NID) in decimal format + * if CDMA subscription is available * [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available */ public void getCDMASubscription(Message response); diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 7834018..1f4ce3d 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -68,8 +68,9 @@ public interface RILConstants { int CDMA_CELL_BROADCAST_SMS_DISABLED = 1; int CDMA_CELL_BROADCAST_SMS_ENABLED = 0; - int CDMA_PHONE = 0; + int NO_PHONE = 0; int GSM_PHONE = 1; + int CDMA_PHONE = 2; int CDM_TTY_MODE_DISABLED = 0; int CDM_TTY_MODE_ENABLED = 1; diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java index 8e76cd2..46b39a5 100644 --- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java @@ -77,7 +77,6 @@ public abstract class ServiceStateTracker extends Handler { // waiting period before recheck gprs and voice registration public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000; - public static final int MAX_NUM_DATA_STATE_READS = 15; public static final int DATA_STATE_POLL_SLEEP_MS = 100; //*****GSM events diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index dda0187..28ce6a5 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -777,6 +777,9 @@ public class CDMAPhone extends PhoneBase { Intent intent = new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS); ActivityManagerNative.broadcastStickyIntent(intent, null); return false; + } else if ((mCT.state == Phone.State.OFFHOOK) && mCT.isInEmergencyCall()) { + // Do not allow data call to be enabled when emergency call is going on + return false; } else { return mDataConnection.setDataEnabled(true); } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java index 7788c75..84d6b3d 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java @@ -80,6 +80,7 @@ public final class CdmaCallTracker extends CallTracker { int pendingCallClirMode; Phone.State state = Phone.State.IDLE; + private boolean mIsInEmergencyCall = false; // boolean needsPoll; @@ -210,6 +211,9 @@ public final class CdmaCallTracker extends CallTracker { // Always unmute when initiating a new call setMute(false); + // Check data call + disableDataCallInEmergencyCall(dialString); + String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); if(inEcm.equals("false")) { cm.dial(pendingMO.address, clirMode, obtainCompleteMessage()); @@ -236,6 +240,9 @@ public final class CdmaCallTracker extends CallTracker { private Connection dialThreeWay (String dialString) { if (!foregroundCall.isIdle()) { + // Check data call + disableDataCallInEmergencyCall(dialString); + // Attach the new connection to foregroundCall pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall); @@ -529,6 +536,9 @@ public final class CdmaCallTracker extends CallTracker { } } foregroundCall.setGeneric(false); + + mIsInEmergencyCall = false; + // Dropped connections are removed from the CallTracker // list but kept in the Call list connections[i] = null; @@ -967,6 +977,26 @@ public final class CdmaCallTracker extends CallTracker { } } + /** + * Disable data call when emergency call is connected + */ + private void disableDataCallInEmergencyCall(String dialString) { + if (PhoneNumberUtils.isEmergencyNumber(dialString)) { + phone.disableDataConnectivity(); + mIsInEmergencyCall = true; + } + } + + /** + * Check if current call is in emergency call + * + * @return true if it is in emergency call + * false if it is not in emergency call + */ + boolean isInEmergencyCall() { + return mIsInEmergencyCall; + } + protected void log(String msg) { Log.d(LOG_TAG, "[CdmaCallTracker] " + msg); } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index c4db609..3ab1f77 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -88,7 +88,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher { int teleService = sms.getTeleService(); boolean handled = false; - if (sms.getUserData() == null) { + if ((sms.getUserData() == null) && (SmsEnvelope.TELESERVICE_MWI != teleService)) { if (Config.LOGD) { Log.d(TAG, "Received SMS without user data"); } @@ -99,10 +99,11 @@ final class CdmaSMSDispatcher extends SMSDispatcher { return Intents.RESULT_SMS_HANDLED; } - if (SmsEnvelope.TELESERVICE_WAP == teleService){ + if (SmsEnvelope.TELESERVICE_WAP == teleService) { return processCdmaWapPdu(sms.getUserData(), sms.messageRef, sms.getOriginatingAddress()); - } else if (SmsEnvelope.TELESERVICE_VMN == teleService) { + } else if ((SmsEnvelope.TELESERVICE_VMN == teleService) || + (SmsEnvelope.TELESERVICE_MWI == teleService)) { // handling Voicemail int voicemailCount = sms.getNumOfVoicemails(); Log.d(TAG, "Voicemail count=" + voicemailCount); diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index d5da666..0cae604 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -401,11 +401,19 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { // TODO: Only grabbing the first SID/NID for now. if (cdmaSubscription[1] != null) { String[] sid = cdmaSubscription[1].split(","); - mHomeSystemId = sid.length > 0 ? Integer.parseInt(sid[0], 16) : 0; + try { + mHomeSystemId = sid.length > 0 ? Integer.parseInt(sid[0]) : 0; + } catch (NumberFormatException e) { + mHomeSystemId = 0; + } } if (cdmaSubscription[2] != null) { String[] nid = cdmaSubscription[2].split(","); - mHomeNetworkId = nid.length > 0 ? Integer.parseInt(nid[0], 16) : 0; + try { + mHomeNetworkId = nid.length > 0 ? Integer.parseInt(nid[0]) : 0; + } catch (NumberFormatException e) { + mHomeNetworkId = 0; + } } mMin = cdmaSubscription[3]; mPrlVersion = cdmaSubscription[4]; @@ -504,9 +512,10 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF; dcTracker.sendMessage(msg); - // Poll data state up to 15 times, with a 100ms delay - // totaling 1.5 sec. Normal data disable action will finish in 100ms. - for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) { + // Poll data state up to 50 times, with a 100ms delay + // totaling 5 sec. + // TODO: change the 5 seconds wait from blocking to non-blocking. + for (int i = 0; i < 50; i++) { DataConnectionTracker.State currentState = dcTracker.getState(); if (currentState != DataConnectionTracker.State.CONNECTED && currentState != DataConnectionTracker.State.DISCONNECTING) { @@ -1073,7 +1082,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { /** * send signal-strength-changed notification if changed - * Called both for solicited and unsolicited signal stength updates + * Called both for solicited and unsolicited signal strength updates */ private void onSignalStrengthResult(AsyncResult ar) { @@ -1086,15 +1095,15 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { int[] ints = (int[])ar.result; int offset = 2; - int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -1; - int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -1; + int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120; + int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -160; int evdoRssi = -1; int evdoEcio = -1; int evdoSnr = -1; if ((networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_0) || (networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_A)) { - evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -1; + evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120; evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1; evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1; } diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java index 30adc52..9c04305 100755 --- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java +++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java @@ -527,6 +527,19 @@ public class SmsMessage extends SmsMessageBase { * Parses a SMS message from its BearerData stream. (mobile-terminated only) */ protected void parseSms() { + // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6 + // It contains only an 8-bit number with the number of messages waiting + if (mEnvelope.teleService == SmsEnvelope.TELESERVICE_MWI) { + mBearerData = new BearerData(); + if (mEnvelope.bearerData != null) { + mBearerData.numberOfMessages = 0x000000FF & mEnvelope.bearerData[0]; + } + if (Config.DEBUG) { + Log.d(LOG_TAG, "parseSms: get MWI " + + Integer.toString(mBearerData.numberOfMessages)); + } + return; + } mBearerData = BearerData.decode(mEnvelope.bearerData); messageRef = mBearerData.messageId; if (mBearerData.userData != null) { diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java index f80e8c0..0dcacc1 100644 --- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java +++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java @@ -36,6 +36,14 @@ public final class SmsEnvelope{ static public final int TELESERVICE_WAP = 0x1004; static public final int TELESERVICE_WEMT = 0x1005; + /** + * The following are defined as extensions to the standard teleservices + */ + // Voice mail notification through Message Waiting Indication in CDMA mode or Analog mode. + // Defined in 3GPP2 C.S-0005, 3.7.5.6, an Info Record containing an 8-bit number with the + // number of messages waiting, it's used by some CDMA carriers for a voice mail count. + static public final int TELESERVICE_MWI = 0x40000; + // ServiceCategories for Cell Broadcast, see 3GPP2 C.R1001 table 9.3.1-1 //static public final int SERVICECATEGORY_EMERGENCY = 0x0010; //... diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index b3b4345..4178115 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -151,6 +151,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker { static final int PS_NOTIFICATION = 888; //id to update and cancel PS restricted static final int CS_NOTIFICATION = 999; //id to update and cancel CS restricted + static final int MAX_NUM_DATA_STATE_READS = 15; + private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { diff --git a/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java b/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java index 7dc1314..67fcd61 100755 --- a/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java @@ -16,10 +16,22 @@ package com.android.unit_tests; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.vpn.L2tpProfile; import android.net.vpn.L2tpIpsecProfile; +import android.net.vpn.L2tpIpsecPskProfile; +import android.net.vpn.PptpProfile; +import android.net.vpn.VpnManager; +import android.net.vpn.VpnProfile; +import android.net.vpn.VpnState; import android.net.vpn.VpnType; +import android.os.ConditionVariable; +import android.os.Parcel; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; +import android.text.TextUtils; /** * Unit test class to test VPN api @@ -29,6 +41,12 @@ import android.test.suitebuilder.annotation.SmallTest; * -w com.android.unit_tests/android.test.InstrumentationTestRunner */ public class VpnTest extends AndroidTestCase { + private static final String NAME = "a name"; + private static final String SERVER_NAME = "a server name"; + private static final String ID = "some id"; + private static final String SUFFICES = "some suffices"; + private static final String ROUTES = "some routes"; + private static final String SAVED_NAME = "some name"; @Override public void setUp() { @@ -39,8 +57,102 @@ public class VpnTest extends AndroidTestCase { } @SmallTest + public void testVpnType() { + testVpnType(VpnType.L2TP); + testVpnType(VpnType.L2TP_IPSEC); + testVpnType(VpnType.L2TP_IPSEC_PSK); + testVpnType(VpnType.PPTP); + } + + @SmallTest + public void testVpnProfile() { + VpnState state = VpnState.CONNECTING; + testVpnProfile(createTestProfile(state), state); + } + + @SmallTest public void testGetType() { - L2tpIpsecProfile li = new L2tpIpsecProfile(); - assertTrue(VpnType.L2TP_IPSEC== li.getType()); + assertEquals(VpnType.L2TP, new L2tpProfile().getType()); + assertEquals(VpnType.L2TP_IPSEC, new L2tpIpsecProfile().getType()); + assertEquals(VpnType.L2TP_IPSEC_PSK, + new L2tpIpsecPskProfile().getType()); + assertEquals(VpnType.PPTP, new PptpProfile().getType()); + } + + @SmallTest + public void testVpnTypes() { + assertTrue(VpnManager.getSupportedVpnTypes().length > 0); + } + + @SmallTest + public void testGetTypeFromManager() { + VpnManager m = new VpnManager(getContext()); + VpnType[] types = VpnManager.getSupportedVpnTypes(); + for (VpnType t : types) { + assertEquals(t, m.createVpnProfile(t).getType()); + } + } + + @SmallTest + public void testParcelable() { + VpnProfile p = createTestProfile(VpnState.CONNECTED); + Parcel parcel = Parcel.obtain(); + p.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + // VpnState is transient and not saved in the parcel + testVpnProfile(VpnProfile.CREATOR.createFromParcel(parcel), null); + } + + @SmallTest + public void testReceiver() { + final String profileName = "whatever"; + final VpnState state = VpnState.DISCONNECTING; + final ConditionVariable cv = new ConditionVariable(); + cv.close(); + BroadcastReceiver r = new BroadcastReceiver() { + public void onReceive(Context c, Intent i) { + assertEquals(profileName, + i.getStringExtra(VpnManager.BROADCAST_PROFILE_NAME)); + assertEquals(state, i.getSerializableExtra( + VpnManager.BROADCAST_CONNECTION_STATE)); + cv.open(); + } + }; + + VpnManager m = new VpnManager(getContext()); + m.registerConnectivityReceiver(r); + m.broadcastConnectivity(profileName, state); + + // fail it if onReceive() doesn't get executed in 5 sec + assertTrue(cv.block(5000)); + } + + private void testVpnType(VpnType type) { + assertFalse(TextUtils.isEmpty(type.getDisplayName())); + assertNotNull(type.getDescription()); + assertNotNull(type.getProfileClass()); + } + + private VpnProfile createTestProfile(VpnState state) { + VpnProfile p = new L2tpProfile(); + p.setName(NAME); + p.setServerName(SERVER_NAME); + p.setId(ID); + p.setDomainSuffices(SUFFICES); + p.setRouteList(ROUTES); + p.setSavedUsername(SAVED_NAME); + p.setState(state); + return p; + } + + private void testVpnProfile(VpnProfile p, VpnState state) { + assertEquals(NAME, p.getName()); + assertEquals(SERVER_NAME, p.getServerName()); + assertEquals(ID, p.getId()); + assertEquals(SUFFICES, p.getDomainSuffices()); + assertEquals(ROUTES, p.getRouteList()); + assertEquals(SAVED_NAME, p.getSavedUsername()); + if (state != null) assertEquals(state, p.getState()); } } diff --git a/tests/CoreTests/android/core/CryptoTest.java b/tests/CoreTests/android/core/CryptoTest.java index f00d49f..e6e50ec 100644 --- a/tests/CoreTests/android/core/CryptoTest.java +++ b/tests/CoreTests/android/core/CryptoTest.java @@ -22,7 +22,6 @@ import junit.framework.TestCase; import org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigest; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.ExtendedDigest; -import org.bouncycastle.crypto.digests.MD2Digest; import org.bouncycastle.crypto.digests.MD4Digest; import org.bouncycastle.crypto.digests.MD5Digest; import org.bouncycastle.crypto.digests.SHA1Digest; @@ -93,16 +92,6 @@ public class CryptoTest extends TestCase { // Assert.assertTrue("New hash should be faster", newTime < oldTime); } - - /** - * Tests the MD2 implementation. - */ - @LargeTest - public void testMD2() { - Digest oldDigest = new MD2Digest(); - Digest newDigest = OpenSSLMessageDigest.getInstance("MD2"); - doTestMessageDigest(oldDigest, newDigest); - } /** * Tests the MD4 implementation. diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 2ee1945..d8a03a9 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -871,7 +871,10 @@ public class WifiManager { * Create a new MulticastLock * * @param tag a tag for the MulticastLock to identify it in debugging - * messages. + * messages. This string is never shown to the user under + * normal conditions, but should be descriptive enough to + * identify your application and the specific MulticastLock + * within it, if it holds multiple MulticastLocks. * * @return a new, unacquired MulticastLock with the given tag. * @@ -887,26 +890,36 @@ public class WifiManager { * addressed to this device. Acquring a MulticastLock will * cause the stack to receive packets addressed to multicast * addresses. Processing these extra packets can cause a noticable - * battery drain and should be disabled when not needed + * battery drain and should be disabled when not needed. */ public class MulticastLock { private String mTag; private final IBinder mBinder; + private int mRefCount; + private boolean mRefCounted; private boolean mHeld; private MulticastLock(String tag) { mTag = tag; mBinder = new Binder(); + mRefCount = 0; + mRefCounted = true; mHeld = false; } /** * Locks Wifi Multicast on until {@link #release} is called. * - * The first call to {@code acquire} will lock the Multicast on - * but subsequent calls will be ignored. Only one call to - * {@link #release} will be required, regardless of the number of - * times that {@code acquire} is called. + * If this MulticastLock is reference-counted each call to + * {@code acquire} will increment the reference count, and the + * wifi interface will receive multicast packets as long as the + * reference count is above zero. + * + * If this MulticastLock is not reference-counted, the first call to + * {@code acquire} will turn on the multicast packets, but subsequent + * calls will be ignored. Only one call to {@link #release} will + * be required, regardless of the number of times that {@code acquire} + * is called. * * Note that other applications may also lock Wifi Multicast on. * Only they can relinquish their lock. @@ -916,7 +929,7 @@ public class WifiManager { */ public void acquire() { synchronized (mBinder) { - if (!mHeld) { + if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) { try { mService.acquireMulticastLock(mBinder, mTag); synchronized (WifiManager.this) { @@ -927,9 +940,9 @@ public class WifiManager { } mActiveLockCount++; } - mHeld = true; } catch (RemoteException ignore) { } + mHeld = true; } } } @@ -938,6 +951,18 @@ public class WifiManager { * Unlocks Wifi Multicast, restoring the filter of packets * not addressed specifically to this device and saving power. * + * If this MulticastLock is reference-counted, each call to + * {@code release} will decrement the reference count, and the + * multicast packets will only stop being received when the reference + * count reaches zero. If the reference count goes below zero (that + * is, if {@code release} is called a greater number of times than + * {@link #acquire}), an exception is thrown. + * + * If this MulticastLock is not reference-counted, the first call to + * {@code release} (after the radio was multicast locked using + * {@linke #acquire}) will unlock the multicast, and subsequent calls + * will be ignored. + * * Note that if any other Wifi Multicast Locks are still outstanding * this {@code release} call will not have an immediate effect. Only * when all applications have released all their Multicast Locks will @@ -948,20 +973,43 @@ public class WifiManager { */ public void release() { synchronized (mBinder) { - if (mHeld) { + if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { mService.releaseMulticastLock(); synchronized (WifiManager.this) { mActiveLockCount--; } - mHeld = false; } catch (RemoteException ignore) { } + mHeld = false; + } + if (mRefCount < 0) { + throw new RuntimeException("MulticastLock under-locked " + + mTag); } } } /** + * Controls whether this is a reference-counted or non-reference- + * counted MulticastLock. + * + * Reference-counted MulticastLocks keep track of the number of calls + * to {@link #acquire} and {@link #release}, and only stop the + * reception of multicast packets when every call to {@link #acquire} + * has been balanced with a call to {@link #release}. Non-reference- + * counted MulticastLocks allow the reception of multicast packets + * whenever {@link #acquire} is called and stop accepting multicast + * packets whenever {@link #release} is called. + * + * @param refCounted true if this MulticastLock should keep a reference + * count + */ + public void setReferenceCounted(boolean refCounted) { + mRefCounted = refCounted; + } + + /** * Checks whether this MulticastLock is currently held. * * @return true if this MulticastLock is held, false otherwise @@ -973,17 +1021,23 @@ public class WifiManager { } public String toString() { - String s1, s2; + String s1, s2, s3; synchronized (mBinder) { s1 = Integer.toHexString(System.identityHashCode(this)); s2 = mHeld ? "held; " : ""; - return "MulticastLock{ " + s1 + "; " + s2 + " }"; + if (mRefCounted) { + s3 = "refcounted: refcount = " + mRefCount; + } else { + s3 = "not refcounted"; + } + return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }"; } } @Override protected void finalize() throws Throwable { super.finalize(); + setReferenceCounted(false); release(); } } |
