summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml15
-rw-r--r--cmds/stagefright/Android.mk2
-rw-r--r--core/java/android/accounts/AccountManagerService.java9
-rwxr-xr-xcore/java/android/os/IHardwareService.aidl6
-rw-r--r--core/java/android/os/IPowerManager.aidl6
-rw-r--r--core/java/android/os/PowerManager.java15
-rw-r--r--core/java/android/provider/ContactsContract.java46
-rwxr-xr-xcore/java/android/speech/tts/TextToSpeech.java197
-rw-r--r--core/java/android/view/SurfaceView.java44
-rw-r--r--core/java/android/webkit/BrowserFrame.java2
-rw-r--r--core/java/android/webkit/WebView.java628
-rw-r--r--core/java/android/webkit/WebViewCore.java20
-rw-r--r--core/java/android/widget/FasttrackBadgeWidget.java253
-rw-r--r--core/java/android/widget/GridView.java17
-rw-r--r--core/java/android/widget/ListView.java71
-rw-r--r--core/res/res/drawable/fasttrack_badge_middle_large.xml (renamed from core/res/res/drawable/fasttrack_badge_middle.xml)4
-rw-r--r--core/res/res/drawable/fasttrack_badge_middle_large_normal.9.pngbin0 -> 612 bytes
-rw-r--r--core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.pngbin0 -> 834 bytes
-rw-r--r--core/res/res/drawable/fasttrack_badge_middle_normal.9.pngbin606 -> 0 bytes
-rw-r--r--core/res/res/drawable/fasttrack_badge_middle_pressed.9.pngbin818 -> 0 bytes
-rw-r--r--core/res/res/layout/contact_header.xml6
-rw-r--r--core/res/res/values/attrs.xml25
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/styles.xml20
-rw-r--r--core/res/res/values/themes.xml3
-rw-r--r--docs/html/guide/topics/resources/available-resources.jd10
-rw-r--r--docs/html/sdk/1.6_r1/index.jd12
-rw-r--r--docs/html/sdk/android-1.6-highlights.jd2
-rw-r--r--graphics/java/android/graphics/BlurMaskFilter.java14
-rw-r--r--graphics/java/android/renderscript/Allocation.java4
-rw-r--r--graphics/java/android/renderscript/RenderScript.java1
-rw-r--r--graphics/jni/android_renderscript_RenderScript.cpp71
-rw-r--r--include/media/IOMX.h13
-rw-r--r--media/libmedia/Android.mk1
-rw-r--r--media/libmedia/IOMX.cpp25
-rw-r--r--media/libmediaplayerservice/Android.mk1
-rw-r--r--media/libstagefright/Android.mk1
-rw-r--r--media/libstagefright/omx/Android.mk1
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java84
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java101
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java10
-rw-r--r--services/java/com/android/server/DockObserver.java7
-rwxr-xr-xservices/java/com/android/server/HardwareService.java28
-rw-r--r--services/java/com/android/server/PowerManagerService.java36
-rw-r--r--services/java/com/android/server/SystemServer.java2
-rw-r--r--telephony/java/com/android/internal/telephony/SmsResponse.java8
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java12
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/SmsMessage.java8
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/os/FileObserverTest.java46
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/os/PowerManagerTest.java19
-rwxr-xr-xtests/DumpRenderTree/assets/run_page_cycler.py11
-rw-r--r--tests/FrameworkTest/src/com/android/frameworktest/settings/BrightnessLimit.java10
-rw-r--r--tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java6
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/HardwareServicePermissionTest.java16
54 files changed, 1111 insertions, 840 deletions
diff --git a/api/current.xml b/api/current.xml
index 38490f3113eb..7562f2e27b34 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -6825,7 +6825,7 @@
value="16843221"
static="true"
final="true"
- deprecated="deprecated"
+ deprecated="not deprecated"
visibility="public"
>
</field>
@@ -150079,6 +150079,19 @@
visibility="public"
>
</method>
+<method name="setOnTop"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="onTop" type="boolean">
+</parameter>
+</method>
</class>
<class name="TouchDelegate"
extends="java.lang.Object"
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 39ed769a040f..5b5525240f02 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -11,6 +11,7 @@ LOCAL_SHARED_LIBRARIES := \
libstagefright
LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
@@ -32,6 +33,7 @@ LOCAL_SHARED_LIBRARIES := \
libstagefright
LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 6abed93e284e..c13893a5a574 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1445,13 +1445,18 @@ public class AccountManagerService extends IAccountManager.Stub {
intent.getComponent().getClassName())) {
createNoCredentialsPermissionNotification(account, intent);
} else {
+ final Integer notificationId = getSigninRequiredNotificationId(account);
+ intent.addCategory(String.valueOf(notificationId));
Notification n = new Notification(android.R.drawable.stat_sys_warning, null,
0 /* when */);
- n.setLatestEventInfo(mContext, mContext.getText(R.string.notification_title),
+ final String notificationTitleFormat =
+ mContext.getText(R.string.notification_title).toString();
+ n.setLatestEventInfo(mContext,
+ String.format(notificationTitleFormat, account.name),
message, PendingIntent.getActivity(
mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT));
((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE))
- .notify(getSigninRequiredNotificationId(account), n);
+ .notify(notificationId, n);
}
} finally {
restoreCallingIdentity(identityToken);
diff --git a/core/java/android/os/IHardwareService.aidl b/core/java/android/os/IHardwareService.aidl
index a6ef64739434..594c0e89b936 100755
--- a/core/java/android/os/IHardwareService.aidl
+++ b/core/java/android/os/IHardwareService.aidl
@@ -28,12 +28,6 @@ interface IHardwareService
boolean getFlashlightEnabled();
void setFlashlightEnabled(boolean on);
void enableCameraFlash(int milliseconds);
-
- // sets the brightness of the backlights (screen, keyboard, button) 0-255
- void setBacklights(int brightness);
-
- // enables or disables automatic brightness mode
- void setAutoBrightness(boolean on);
// for the phone
void setAttentionLight(boolean on);
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 188e7ff09e50..189335ef1e86 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -31,4 +31,10 @@ interface IPowerManager
long getScreenOnTime();
void preventScreenOn(boolean prevent);
void setScreenBrightnessOverride(int brightness);
+
+ // sets the brightness of the backlights (screen, keyboard, button) 0-255
+ void setBacklightBrightness(int brightness);
+
+ // enables or disables automatic brightness mode
+ void setAutoBrightness(boolean on);
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index d5934102c856..11c96d2b4b3c 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -379,6 +379,21 @@ public class PowerManager
}
}
+ /**
+ * sets the brightness of the backlights (screen, keyboard, button).
+ *
+ * @param brightness value from 0 to 255
+ *
+ * {@hide}
+ */
+ public void setBacklightBrightness(int brightness)
+ {
+ try {
+ mService.setBacklightBrightness(brightness);
+ } catch (RemoteException e) {
+ }
+ }
+
/**
* Returns the set of flags for {@link #newWakeLock(int, String) newWakeLock()}
* that are supported on the device.
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index d354ccffd889..b0ac7f4b8608 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -46,6 +46,15 @@ public final class ContactsContract {
/** A content:// style uri to the authority for the contacts provider */
public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
+ /**
+ * An optional insert, update or delete URI parameter that allows the caller
+ * to specify that it is a sync adapter. The default value is false. If true
+ * the dirty flag is not automatically set and the "syncToNetwork" parameter
+ * is set to false when calling
+ * {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}.
+ */
+ public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
+
public interface SyncStateColumns extends SyncStateContract.Columns {
}
@@ -480,7 +489,8 @@ public final class ContactsContract {
* called on a raw contact, it is marked for deletion and removed from its
* aggregate contact. The sync adaptor deletes the raw contact on the server and
* then calls ContactResolver.delete once more, this time passing the
- * {@link RawContacts#DELETE_PERMANENTLY} query parameter to finalize the data removal.
+ * {@link ContactsContract#CALLER_IS_SYNCADAPTER} query parameter to finalize
+ * the data removal.
* <P>Type: INTEGER</P>
*/
public static final String DELETED = "deleted";
@@ -517,14 +527,6 @@ public final class ContactsContract {
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/raw_contact";
/**
- * Query parameter that can be passed with the {@link #CONTENT_URI} URI
- * to the {@link android.content.ContentResolver#delete} method to
- * indicate that the raw contact can be deleted physically, rather than
- * merely marked as deleted.
- */
- public static final String DELETE_PERMANENTLY = "delete_permanently";
-
- /**
* Aggregation mode: aggregate asynchronously.
*/
public static final int AGGREGATION_MODE_DEFAULT = 0;
@@ -648,13 +650,6 @@ public final class ContactsContract {
public static final String SYNC3 = "data_sync3";
/** Generic column for use by sync adapters. */
public static final String SYNC4 = "data_sync4";
-
- /**
- * An optional insert, update or delete URI parameter that determines if
- * the corresponding raw contact should be marked as dirty. The default
- * value is true.
- */
- public static final String MARK_AS_DIRTY = "mark_as_dirty";
}
/**
@@ -1533,8 +1528,9 @@ public final class ContactsContract {
* for deletion. When {@link android.content.ContentResolver#delete} is
* called on a raw contact, it is marked for deletion and removed from its
* aggregate contact. The sync adaptor deletes the raw contact on the server and
- * then calls ContactResolver.delete once more, this time passing the
- * {@link RawContacts#DELETE_PERMANENTLY} query parameter to finalize the data removal.
+ * then calls ContactResolver.delete once more, this time setting the the
+ * {@link ContactsContract#CALLER_IS_SYNCADAPTER} query parameter to finalize
+ * the data removal.
* <P>Type: INTEGER</P>
*/
public static final String DELETED = "deleted";
@@ -1579,20 +1575,6 @@ public final class ContactsContract {
* The MIME type of a single group.
*/
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/group";
-
- /**
- * Query parameter that can be passed with the {@link #CONTENT_URI} URI
- * to the {@link android.content.ContentResolver#delete} method to
- * indicate that the raw contact can be deleted physically, rather than
- * merely marked as deleted.
- */
- public static final String DELETE_PERMANENTLY = "delete_permanently";
-
- /**
- * An optional update or insert URI parameter that determines if the
- * group should be marked as dirty. The default value is true.
- */
- public static final String MARK_AS_DIRTY = "mark_as_dirty";
}
/**
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index a6d76d684fe4..3f369ddd580a 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -35,9 +35,13 @@ import java.util.Locale;
/**
*
* Synthesizes speech from text for immediate playback or to create a sound file.
+ * <p>A TextToSpeech instance can only be used to synthesize text once it has completed its
+ * initialization. Implement the {@link TextToSpeech.OnInitListener} to be
+ * notified of the completion of the initialization.<br>
+ * When you are done using the TextToSpeech instance, call the {@link #shutdown()} method
+ * to release the native resources used by the TextToSpeech engine.
*
*/
-//TODO complete javadoc + add links to constants
public class TextToSpeech {
/**
@@ -85,7 +89,7 @@ public class TextToSpeech {
public static final int LANG_MISSING_DATA = -1;
/**
- * Denotes the language is not supported by the current TTS engine.
+ * Denotes the language is not supported.
*/
public static final int LANG_NOT_SUPPORTED = -2;
@@ -100,29 +104,38 @@ public class TextToSpeech {
/**
- * Called when the TTS has initialized.
- *
- * The InitListener must implement the onInit function. onInit is passed a
- * status code indicating the result of the TTS initialization.
+ * Interface definition of a callback to be invoked indicating the completion of the
+ * TextToSpeech engine initialization.
*/
public interface OnInitListener {
+ /**
+ * Called to signal the completion of the TextToSpeech engine initialization.
+ * @param status {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
+ */
public void onInit(int status);
}
/**
- * Called when the TTS has completed saying something that has an utterance ID set.
+ * Interface definition of a callback to be invoked indicating the TextToSpeech engine has
+ * completed synthesizing an utterance with an utterance ID set.
*
- * The OnUtteranceCompletedListener must implement the onUtteranceCompleted function.
- * onUtteranceCompleted is passed a String that is the utteranceId given in
- * the original speak call.
*/
- public interface OnUtteranceCompletedListener {
+ public interface OnUtteranceCompletedListener {
+ /**
+ * Called to signal the completion of the synthesis of the utterance that was identified
+ * with the string parameter. This identifier is the one originally passed in the
+ * parameter hashmap of the synthesis request in
+ * {@link TextToSpeech#speak(String, int, HashMap)} or
+ * {@link TextToSpeech#synthesizeToFile(String, HashMap, String)} with the
+ * {@link TextToSpeech.Engine#KEY_PARAM_UTTERANCE_ID} key.
+ * @param utteranceId the identifier of the utterance.
+ */
public void onUtteranceCompleted(String utteranceId);
}
/**
- * Internal constants for the TTS functionality
+ * Internal constants for the TextToSpeech functionality
*
*/
public class Engine {
@@ -145,38 +158,41 @@ public class TextToSpeech {
public static final String DEFAULT_SYNTH = "com.svox.pico";
// default values for rendering
+ /**
+ * Default audio stream used when playing synthesized speech.
+ */
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 {@link #ACTION_CHECK_TTS_DATA} intent.
+ * TextToSpeech 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 {@link #ACTION_CHECK_TTS_DATA} intent.
+ * TextToSpeech 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 {@link #ACTION_CHECK_TTS_DATA} intent.
+ * the TextToSpeech 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 {@link #ACTION_CHECK_TTS_DATA} intent.
+ * by the TextToSpeech 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 {@link #ACTION_CHECK_TTS_DATA} intent.
+ * used by the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
*/
public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3;
// intents to ask engine to install data or check its data
/**
- * Activity Action: Triggers the platform Text-To-Speech engine to
+ * Activity Action: Triggers the platform TextToSpeech 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
@@ -197,7 +213,7 @@ public class TextToSpeech {
public static final String ACTION_TTS_DATA_INSTALLED =
"android.speech.tts.engine.TTS_DATA_INSTALLED";
/**
- * Activity Action: Starts the activity from the platform Text-To-Speech
+ * Activity Action: Starts the activity from the platform TextToSpeech
* 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:
@@ -210,9 +226,9 @@ public class TextToSpeech {
* fields:
* <ul>
* <li>{@link #EXTRA_VOICE_DATA_ROOT_DIRECTORY} which
- * indicates the path to the location of the resource files</li>,
+ * 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>,
+ * 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,
@@ -226,18 +242,18 @@ public class TextToSpeech {
// extras for a TTS engine's check data activity
/**
* Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
- * the text-to-speech engine specifies the path to its resources.
+ * the TextToSpeech engine specifies the path to its resources.
*/
public static final String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
/**
* 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
+ * the TextToSpeech engine specifies the file names of its resources under the
* resource path.
*/
public static final String EXTRA_VOICE_DATA_FILES = "dataFiles";
/**
* 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.
+ * the TextToSpeech engine specifies the locale associated with each resource file.
*/
public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo";
@@ -272,11 +288,17 @@ public class TextToSpeech {
/**
* Parameter key to specify the audio stream type to be used when speaking text
* or playing back a file.
+ * @see TextToSpeech#speak(String, int, HashMap)
+ * @see TextToSpeech#playEarcon(String, int, HashMap)
*/
public static final String KEY_PARAM_STREAM = "streamType";
/**
- * Parameter key to identify an utterance in the completion listener after text has been
+ * Parameter key to identify an utterance in the
+ * {@link TextToSpeech.OnUtteranceCompletedListener} after text has been
* spoken, a file has been played back or a silence duration has elapsed.
+ * @see TextToSpeech#speak(String, int, HashMap)
+ * @see TextToSpeech#playEarcon(String, int, HashMap)
+ * @see TextToSpeech#synthesizeToFile(String, HashMap, String)
*/
public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId";
@@ -330,13 +352,14 @@ public class TextToSpeech {
private String[] mCachedParams;
/**
- * The constructor for the TTS.
+ * The constructor for the TextToSpeech class.
+ * This will also initialize the associated TextToSpeech engine if it isn't already running.
*
* @param context
- * The context
+ * The context this instance is running in.
* @param listener
- * The InitListener that will be called when the TTS has
- * initialized successfully.
+ * The {@link TextToSpeech.OnInitListener} that will be called when the
+ * TextToSpeech engine has initialized.
*/
public TextToSpeech(Context context, OnInitListener listener) {
mContext = context;
@@ -402,9 +425,9 @@ public class TextToSpeech {
/**
- * Shuts down the TTS. It is good practice to call this in the onDestroy
- * method of the Activity that is using the TTS so that the TTS is stopped
- * cleanly.
+ * Releases the resources used by the TextToSpeech engine.
+ * It is good practice for instance to call this method in the onDestroy() method of an Activity
+ * so the TextToSpeech engine can be cleanly stopped.
*/
public void shutdown() {
try {
@@ -418,11 +441,12 @@ public class TextToSpeech {
/**
* Adds a mapping between a string of text and a sound resource in a
- * package.
- * @see #speak(String, int, HashMap)
+ * package. After a call to this method, subsequent calls to
+ * {@link #speak(String, int, HashMap)} will play the specified sound resource
+ * if it is available, or synthesize the text it is missing.
*
* @param text
- * Example: <b><code>"south_south_east"</code></b><br/>
+ * The string of text. Example: <code>"south_south_east"</code>
*
* @param packagename
* Pass the packagename of the application that contains the
@@ -438,7 +462,7 @@ public class TextToSpeech {
* </p>
*
* @param resourceId
- * Example: <b><code>R.raw.south_south_east</code></b>
+ * Example: <code>R.raw.south_south_east</code>
*
* @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
@@ -476,10 +500,13 @@ public class TextToSpeech {
/**
* Adds a mapping between a string of text and a sound file. Using this, it
- * is possible to add custom pronounciations for text.
+ * is possible to add custom pronounciations for a string of text.
+ * After a call to this method, subsequent calls to {@link #speak(String, int, HashMap)}
+ * will play the specified sound resource if it is available, or synthesize the text it is
+ * missing.
*
* @param text
- * The string of text
+ * The string of text. Example: <code>"south_south_east"</code>
* @param filename
* The full path to the sound file (for example:
* "/sdcard/mysounds/hello.wav")
@@ -520,28 +547,26 @@ public class TextToSpeech {
/**
* Adds a mapping between a string of text and a sound resource in a
- * package.
+ * package. Use this to add custom earcons.
*
* @see #playEarcon(String, int, HashMap)
*
- * @param earcon The name of the earcon
- * Example: <b><code>"[tick]"</code></b><br/>
+ * @param earcon The name of the earcon.
+ * Example: <code>"[tick]"</code><br/>
*
* @param packagename
- * Pass the packagename of the application that contains the
- * resource. If the resource is in your own application (this is
- * the most common case), then put the packagename of your
- * application here.<br/>
+ * the package name of the application that contains the
+ * resource. This can for instance be the package name of your own application.
* Example: <b>"com.google.marvin.compass"</b><br/>
- * The packagename can be found in the AndroidManifest.xml of
- * your application.
+ * The package name can be found in the AndroidManifest.xml of
+ * the application containing the resource.
* <p>
* <code>&lt;manifest xmlns:android=&quot;...&quot;
* package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
* </p>
*
* @param resourceId
- * Example: <b><code>R.raw.tick_snd</code></b>
+ * Example: <code>R.raw.tick_snd</code>
*
* @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
@@ -578,11 +603,14 @@ public class TextToSpeech {
/**
- * Adds a mapping between a string of text and a sound file. Using this, it
- * is possible to add custom earcons.
+ * Adds a mapping between a string of text and a sound file.
+ * Use this to add custom earcons.
+ *
+ * @see #playEarcon(String, int, HashMap)
*
* @param earcon
- * The name of the earcon
+ * The name of the earcon.
+ * Example: <code>"[tick]"</code>
* @param filename
* The full path to the sound file (for example:
* "/sdcard/mysounds/tick.wav")
@@ -623,18 +651,18 @@ public class TextToSpeech {
/**
* Speaks the string using the specified queuing strategy and speech
- * parameters. Note that the speech parameters are not universally supported
- * by all engines and will be treated as a hint. The TTS library will try to
- * fulfill these parameters as much as possible, but there is no guarantee
- * that the voice used will have the properties specified.
+ * parameters.
*
* @param text
* The string of text to be spoken.
* @param queueMode
* The queuing strategy to use.
- * See QUEUE_ADD and QUEUE_FLUSH.
+ * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
* @param params
- * The hashmap of speech parameters to be used.
+ * The list of parameters to be used. Can be null if no parameters are given.
+ * They are specified using a (key, value) pair, where the key can be
+ * {@link Engine#KEY_PARAM_STREAM} or
+ * {@link Engine#KEY_PARAM_UTTERANCE_ID}.
*
* @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
@@ -690,9 +718,12 @@ public class TextToSpeech {
* @param earcon
* The earcon that should be played
* @param queueMode
- * See QUEUE_ADD and QUEUE_FLUSH.
+ * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
* @param params
- * The hashmap of parameters to be used.
+ * The list of parameters to be used. Can be null if no parameters are given.
+ * They are specified using a (key, value) pair, where the key can be
+ * {@link Engine#KEY_PARAM_STREAM} or
+ * {@link Engine#KEY_PARAM_UTTERANCE_ID}.
*
* @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
@@ -747,7 +778,11 @@ public class TextToSpeech {
* @param durationInMs
* A long that indicates how long the silence should last.
* @param queueMode
- * See QUEUE_ADD and QUEUE_FLUSH.
+ * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
+ * @param params
+ * The list of parameters to be used. Can be null if no parameters are given.
+ * They are specified using a (key, value) pair, where the key can be
+ * {@link Engine#KEY_PARAM_UTTERANCE_ID}.
*
* @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
@@ -791,9 +826,9 @@ public class TextToSpeech {
/**
- * Returns whether or not the TTS is busy speaking.
+ * Returns whether or not the TextToSpeech engine is busy speaking.
*
- * @return Whether or not the TTS is busy speaking.
+ * @return Whether or not the TextToSpeech engine is busy speaking.
*/
public boolean isSpeaking() {
synchronized (mStartLock) {
@@ -827,7 +862,8 @@ public class TextToSpeech {
/**
- * Stops speech from the TTS.
+ * Interrupts the current utterance (whether played or rendered to file) and discards other
+ * utterances in the queue.
*
* @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
@@ -865,15 +901,12 @@ public class TextToSpeech {
/**
- * Sets the speech rate for the TTS engine.
+ * Sets the speech rate for the TextToSpeech engine.
*
- * Note that the speech rate is not universally supported by all engines and
- * will be treated as a hint. The TTS library will try to use the specified
- * speech rate, but there is no guarantee.
* This has no effect on any pre-recorded speech.
*
* @param speechRate
- * The speech rate for the TTS engine. 1 is the normal speed,
+ * The speech rate for the TextToSpeech engine. 1 is the normal speed,
* 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).
*
@@ -917,15 +950,12 @@ public class TextToSpeech {
/**
- * Sets the speech pitch for the TTS engine.
+ * Sets the speech pitch for the TextToSpeech engine.
*
- * Note that the pitch is not universally supported by all engines and
- * will be treated as a hint. The TTS library will try to use the specified
- * pitch, but there is no guarantee.
* This has no effect on any pre-recorded speech.
*
* @param pitch
- * The pitch for the TTS engine. 1 is the normal pitch,
+ * The pitch for the TextToSpeech engine. 1 is the normal pitch,
* lower values lower the tone of the synthesized voice,
* greater values increase it.
*
@@ -967,11 +997,11 @@ public class TextToSpeech {
/**
- * Sets the language for the TTS engine.
- *
- * Note that the language is not universally supported by all engines and
- * will be treated as a hint. The TTS library will try to use the specified
- * language as represented by the Locale, but there is no guarantee.
+ * Sets the language for the TextToSpeech engine.
+ * The TextToSpeech engine will try to use the closest match to the specified
+ * language as represented by the Locale, but there is no guarantee that the exact same Locale
+ * will be used. Use {@link #isLanguageAvailable(Locale)} to check the level of support
+ * before choosing the language to use for the next utterances.
*
* @param loc
* The locale describing the language to be used.
@@ -1023,9 +1053,10 @@ public class TextToSpeech {
/**
- * Returns a Locale instance describing the language currently being used by the TTS engine.
+ * Returns a Locale instance describing the language currently being used by the TextToSpeech
+ * engine.
* @return language, country (if any) and variant (if any) used by the engine stored in a Locale
- * instance, or null is the TTS engine has failed.
+ * instance, or null is the TextToSpeech engine has failed.
*/
public Locale getLanguage() {
synchronized (mStartLock) {
@@ -1063,7 +1094,7 @@ public class TextToSpeech {
}
/**
- * Checks if the specified language as represented by the Locale is available.
+ * Checks if the specified language as represented by the Locale is available and supported.
*
* @param loc
* The Locale describing the language to be used.
@@ -1112,7 +1143,9 @@ public class TextToSpeech {
* @param text
* The String of text that should be synthesized
* @param params
- * A hashmap of parameters.
+ * The list of parameters to be used. Can be null if no parameters are given.
+ * They are specified using a (key, value) pair, where the key can be
+ * {@link Engine#KEY_PARAM_UTTERANCE_ID}.
* @param filename
* The string that gives the full output filename; it should be
* something like "/sdcard/myappsounds/mysound.wav".
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1426aef86099..356f55a134d2 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -236,6 +236,10 @@ public class SurfaceView extends View {
@Override
public boolean gatherTransparentRegion(Region region) {
+ if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+ return super.gatherTransparentRegion(region);
+ }
+
boolean opaque = true;
if ((mPrivateFlags & SKIP_DRAW) == 0) {
// this view draws, remove it from the transparent region
@@ -259,20 +263,24 @@ public class SurfaceView extends View {
@Override
public void draw(Canvas canvas) {
- // draw() is not called when SKIP_DRAW is set
- if ((mPrivateFlags & SKIP_DRAW) == 0) {
- // punch a whole in the view-hierarchy below us
- canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+ // draw() is not called when SKIP_DRAW is set
+ if ((mPrivateFlags & SKIP_DRAW) == 0) {
+ // punch a whole in the view-hierarchy below us
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ }
}
super.draw(canvas);
}
@Override
protected void dispatchDraw(Canvas canvas) {
- // if SKIP_DRAW is cleared, draw() has already punched a hole
- if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
- // punch a whole in the view-hierarchy below us
- canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+ // if SKIP_DRAW is cleared, draw() has already punched a hole
+ if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
+ // punch a whole in the view-hierarchy below us
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ }
}
// reposition ourselves where the surface is
mHaveFrame = true;
@@ -281,6 +289,22 @@ public class SurfaceView extends View {
}
/**
+ * Control whether the surface view's surface is placed on top of its
+ * window. Normally it is placed behind the window, to allow it to
+ * (for the most part) appear to composite with the views in the
+ * hierarchy. By setting this, you cause it to be placed above the
+ * window. This means that none of the contents of the window this
+ * SurfaceView is in will be visible on top of its surface.
+ *
+ * <p>Note that this must be set before the surface view's containing
+ * window is attached to the window manager.
+ */
+ public void setOnTop(boolean onTop) {
+ mWindowType = onTop ? WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
+ : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+ }
+
+ /**
* Hack to allow special layering of windows. The type is one of the
* types in WindowManager.LayoutParams. This is a hack so:
* @hide
@@ -345,7 +369,9 @@ public class SurfaceView extends View {
}
mLayout.format = mRequestedFormat;
- mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+ mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_SCALED
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index db6b74f965ac..465eef885189 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -222,7 +222,6 @@ class BrowserFrame extends Handler {
private void resetLoadingStates() {
mCommitted = true;
- mWebViewCore.mEndScaleZoom = mFirstLayoutDone == false;
mFirstLayoutDone = true;
}
@@ -245,7 +244,6 @@ class BrowserFrame extends Handler {
// blocking the update in {@link #loadStarted}
mWebViewCore.contentDraw();
}
- mWebViewCore.mEndScaleZoom = true;
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 2329e2194fe6..081f67a86ec7 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -25,8 +25,6 @@ import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.Point;
import android.graphics.Rect;
@@ -59,7 +57,6 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.animation.AlphaAnimation;
-import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebTextView.AutoCompleteAdapter;
import android.webkit.WebViewCore.EventHub;
@@ -68,9 +65,7 @@ import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
-import android.widget.ImageView;
import android.widget.ListView;
-import android.widget.ScrollBarDrawable;
import android.widget.Scroller;
import android.widget.Toast;
import android.widget.ZoomButtonsController;
@@ -219,13 +214,13 @@ public class WebView extends AbsoluteLayout
inflater.inflate(com.android.internal.R.layout.zoom_magnify, this, true);
mPlusMinusZoomControls = (ZoomControls) findViewById(
com.android.internal.R.id.zoomControls);
- mZoomMagnify = (ImageView) findViewById(com.android.internal.R.id.zoomMagnify);
+ findViewById(com.android.internal.R.id.zoomMagnify).setVisibility(
+ View.GONE);
}
public void show(boolean showZoom, boolean canZoomOut) {
mPlusMinusZoomControls.setVisibility(
showZoom ? View.VISIBLE : View.GONE);
- mZoomMagnify.setVisibility(canZoomOut ? View.VISIBLE : View.GONE);
fade(View.VISIBLE, 0.0f, 1.0f);
}
@@ -240,12 +235,8 @@ public class WebView extends AbsoluteLayout
setVisibility(visibility);
}
- public void setIsZoomMagnifyEnabled(boolean isEnabled) {
- mZoomMagnify.setEnabled(isEnabled);
- }
-
public boolean hasFocus() {
- return mPlusMinusZoomControls.hasFocus() || mZoomMagnify.hasFocus();
+ return mPlusMinusZoomControls.hasFocus();
}
public void setOnZoomInClickListener(OnClickListener listener) {
@@ -256,12 +247,7 @@ public class WebView extends AbsoluteLayout
mPlusMinusZoomControls.setOnZoomOutClickListener(listener);
}
- public void setOnZoomMagnifyClickListener(OnClickListener listener) {
- mZoomMagnify.setOnClickListener(listener);
- }
-
ZoomControls mPlusMinusZoomControls;
- ImageView mZoomMagnify;
}
/**
@@ -351,9 +337,6 @@ public class WebView extends AbsoluteLayout
private float mLastVelX;
private float mLastVelY;
- // use this flag to control whether enabling the new double tap zoom
- static final boolean ENABLE_DOUBLETAP_ZOOM = true;
-
/**
* Touch mode
*/
@@ -363,17 +346,9 @@ public class WebView extends AbsoluteLayout
private static final int TOUCH_DRAG_MODE = 3;
private static final int TOUCH_SHORTPRESS_START_MODE = 4;
private static final int TOUCH_SHORTPRESS_MODE = 5;
- private static final int TOUCH_DOUBLECLICK_MODE = 6;
+ private static final int TOUCH_DOUBLE_TAP_MODE = 6;
private static final int TOUCH_DONE_MODE = 7;
private static final int TOUCH_SELECT_MODE = 8;
- // touch mode values specific to scale+scroll
- private static final int FIRST_SCROLL_ZOOM = 9;
- private static final int SCROLL_ZOOM_ANIMATION_IN = 9;
- private static final int SCROLL_ZOOM_ANIMATION_OUT = 10;
- private static final int SCROLL_ZOOM_OUT = 11;
- private static final int LAST_SCROLL_ZOOM = 11;
- // end of touch mode values specific to scale+scroll
- private static final int TOUCH_DOUBLE_TAP_MODE = 12;
// Whether to forward the touch events to WebCore
private boolean mForwardTouchEvents = false;
@@ -1835,23 +1810,50 @@ public class WebView extends AbsoluteLayout
return contentToViewDimension(y) + getTitleHeight();
}
+ private Rect contentToViewRect(Rect x) {
+ return new Rect(contentToViewX(x.left), contentToViewY(x.top),
+ contentToViewX(x.right), contentToViewY(x.bottom));
+ }
+
+ /* To invalidate a rectangle in content coordinates, we need to transform
+ the rect into view coordinates, so we can then call invalidate(...).
+
+ Normally, we would just call contentToView[XY](...), which eventually
+ calls Math.round(coordinate * mActualScale). However, for invalidates,
+ we need to account for the slop that occurs with antialiasing. To
+ address that, we are a little more liberal in the size of the rect that
+ we invalidate.
+
+ This liberal calculation calls floor() for the top/left, and ceil() for
+ the bottom/right coordinates. This catches the possible extra pixels of
+ antialiasing that we might have missed with just round().
+ */
+
// Called by JNI to invalidate the View, given rectangle coordinates in
// content space
private void viewInvalidate(int l, int t, int r, int b) {
- invalidate(contentToViewX(l), contentToViewY(t), contentToViewX(r),
- contentToViewY(b));
+ final float scale = mActualScale;
+ final int dy = getTitleHeight();
+ invalidate((int)Math.floor(l * scale),
+ (int)Math.floor(t * scale) + dy,
+ (int)Math.ceil(r * scale),
+ (int)Math.ceil(b * scale) + dy);
}
// Called by JNI to invalidate the View after a delay, given rectangle
// coordinates in content space
private void viewInvalidateDelayed(long delay, int l, int t, int r, int b) {
- postInvalidateDelayed(delay, contentToViewX(l), contentToViewY(t),
- contentToViewX(r), contentToViewY(b));
+ final float scale = mActualScale;
+ final int dy = getTitleHeight();
+ postInvalidateDelayed(delay,
+ (int)Math.floor(l * scale),
+ (int)Math.floor(t * scale) + dy,
+ (int)Math.ceil(r * scale),
+ (int)Math.ceil(b * scale) + dy);
}
- private Rect contentToView(Rect x) {
- return new Rect(contentToViewX(x.left), contentToViewY(x.top)
- , contentToViewX(x.right), contentToViewY(x.bottom));
+ private void invalidateContentRect(Rect r) {
+ viewInvalidate(r.left, r.top, r.right, r.bottom);
}
// stop the scroll animation, and don't let a subsequent fling add
@@ -2675,32 +2677,19 @@ public class WebView extends AbsoluteLayout
if (mNativeClass == 0) {
return;
}
- if (mWebViewCore.mEndScaleZoom) {
- mWebViewCore.mEndScaleZoom = false;
- if (mTouchMode >= FIRST_SCROLL_ZOOM
- && mTouchMode <= LAST_SCROLL_ZOOM) {
- setHorizontalScrollBarEnabled(true);
- setVerticalScrollBarEnabled(true);
- mTouchMode = TOUCH_DONE_MODE;
- }
- }
canvas.save();
- if (mTouchMode >= FIRST_SCROLL_ZOOM && mTouchMode <= LAST_SCROLL_ZOOM) {
- scrollZoomDraw(canvas);
- } else {
- // Update the buttons in the picture, so when we draw the picture
- // to the screen, they are in the correct state.
- // Tell the native side if user is a) touching the screen,
- // b) pressing the trackball down, or c) pressing the enter key
- // If the cursor is on a button, we need to draw it in the pressed
- // state.
- // If mNativeClass is 0, we should not reach here, so we do not
- // need to check it again.
- nativeRecordButtons(hasFocus() && hasWindowFocus(),
- mTouchMode == TOUCH_SHORTPRESS_START_MODE
- || mTrackballDown || mGotCenterDown, false);
- drawCoreAndCursorRing(canvas, mBackgroundColor, mDrawCursorRing);
- }
+ // Update the buttons in the picture, so when we draw the picture
+ // to the screen, they are in the correct state.
+ // Tell the native side if user is a) touching the screen,
+ // b) pressing the trackball down, or c) pressing the enter key
+ // If the cursor is on a button, we need to draw it in the pressed
+ // state.
+ // If mNativeClass is 0, we should not reach here, so we do not
+ // need to check it again.
+ nativeRecordButtons(hasFocus() && hasWindowFocus(),
+ mTouchMode == TOUCH_SHORTPRESS_START_MODE
+ || mTrackballDown || mGotCenterDown, false);
+ drawCoreAndCursorRing(canvas, mBackgroundColor, mDrawCursorRing);
canvas.restoreToCount(saveCount);
if (AUTO_REDRAW_HACK && mAutoRedraw) {
@@ -2765,13 +2754,14 @@ public class WebView extends AbsoluteLayout
zoomScale = mZoomScale;
// set mZoomScale to be 0 as we have done animation
mZoomScale = 0;
+ animateZoom = false; // inform drawContentPicture we're done
if (mNeedToAdjustWebTextView) {
mNeedToAdjustWebTextView = false;
mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
contentToViewDimension(
nativeFocusCandidateTextSize()));
Rect bounds = nativeFocusCandidateNodeBounds();
- Rect vBox = contentToView(bounds);
+ Rect vBox = contentToViewRect(bounds);
mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
vBox.height());
// If it is a password field, start drawing the
@@ -2838,371 +2828,6 @@ public class WebView extends AbsoluteLayout
}
}
- private float scrollZoomGridScale(float invScale) {
- float griddedInvScale = (int) (invScale * SCROLL_ZOOM_GRID)
- / (float) SCROLL_ZOOM_GRID;
- return 1.0f / griddedInvScale;
- }
-
- private float scrollZoomX(float scale) {
- int width = getViewWidth();
- float maxScrollZoomX = mContentWidth * scale - width;
- int maxX = mContentWidth - width;
- return -(maxScrollZoomX > 0 ? mZoomScrollX * maxScrollZoomX / maxX
- : maxScrollZoomX / 2);
- }
-
- private float scrollZoomY(float scale) {
- int height = getViewHeight();
- float maxScrollZoomY = mContentHeight * scale - height;
- int maxY = mContentHeight - height;
- return -(maxScrollZoomY > 0 ? mZoomScrollY * maxScrollZoomY / maxY
- : maxScrollZoomY / 2);
- }
-
- private void drawMagnifyFrame(Canvas canvas, Rect frame, Paint paint) {
- final float ADORNMENT_LEN = 16.0f;
- float width = frame.width();
- float height = frame.height();
- Path path = new Path();
- path.moveTo(-ADORNMENT_LEN, -ADORNMENT_LEN);
- path.lineTo(0, 0);
- path.lineTo(width, 0);
- path.lineTo(width + ADORNMENT_LEN, -ADORNMENT_LEN);
- path.moveTo(-ADORNMENT_LEN, height + ADORNMENT_LEN);
- path.lineTo(0, height);
- path.lineTo(width, height);
- path.lineTo(width + ADORNMENT_LEN, height + ADORNMENT_LEN);
- path.moveTo(0, 0);
- path.lineTo(0, height);
- path.moveTo(width, 0);
- path.lineTo(width, height);
- path.offset(frame.left, frame.top);
- canvas.drawPath(path, paint);
- }
-
- // Returns frame surrounding magified portion of screen while
- // scroll-zoom is enabled. The frame is also used to center the
- // zoom-in zoom-out points at the start and end of the animation.
- private Rect scrollZoomFrame(int width, int height, float halfScale) {
- Rect scrollFrame = new Rect();
- scrollFrame.set(mZoomScrollX, mZoomScrollY,
- mZoomScrollX + width, mZoomScrollY + height);
- if (mContentWidth * mZoomScrollLimit < width) {
- float scale = zoomFrameScaleX(width, halfScale, 1.0f);
- float offsetX = (width * scale - width) * 0.5f;
- scrollFrame.left -= offsetX;
- scrollFrame.right += offsetX;
- }
- if (mContentHeight * mZoomScrollLimit < height) {
- float scale = zoomFrameScaleY(height, halfScale, 1.0f);
- float offsetY = (height * scale - height) * 0.5f;
- scrollFrame.top -= offsetY;
- scrollFrame.bottom += offsetY;
- }
- return scrollFrame;
- }
-
- private float zoomFrameScaleX(int width, float halfScale, float noScale) {
- // mContentWidth > width > mContentWidth * mZoomScrollLimit
- if (mContentWidth <= width) {
- return halfScale;
- }
- float part = (width - mContentWidth * mZoomScrollLimit)
- / (width * (1 - mZoomScrollLimit));
- return halfScale * part + noScale * (1.0f - part);
- }
-
- private float zoomFrameScaleY(int height, float halfScale, float noScale) {
- if (mContentHeight <= height) {
- return halfScale;
- }
- float part = (height - mContentHeight * mZoomScrollLimit)
- / (height * (1 - mZoomScrollLimit));
- return halfScale * part + noScale * (1.0f - part);
- }
-
- private float scrollZoomMagScale(float invScale) {
- return (invScale * 2 + mInvActualScale) / 3;
- }
-
- private void scrollZoomDraw(Canvas canvas) {
- float invScale = mZoomScrollInvLimit;
- int elapsed = 0;
- if (mTouchMode != SCROLL_ZOOM_OUT) {
- elapsed = (int) Math.min(System.currentTimeMillis()
- - mZoomScrollStart, SCROLL_ZOOM_DURATION);
- float transitionScale = (mZoomScrollInvLimit - mInvActualScale)
- * elapsed / SCROLL_ZOOM_DURATION;
- if (mTouchMode == SCROLL_ZOOM_ANIMATION_OUT) {
- invScale = mInvActualScale + transitionScale;
- } else { /* if (mTouchMode == SCROLL_ZOOM_ANIMATION_IN) */
- invScale = mZoomScrollInvLimit - transitionScale;
- }
- }
- float scale = scrollZoomGridScale(invScale);
- invScale = 1.0f / scale;
- int width = getViewWidth();
- int height = getViewHeight();
- float halfScale = scrollZoomMagScale(invScale);
- Rect scrollFrame = scrollZoomFrame(width, height, halfScale);
- if (elapsed == SCROLL_ZOOM_DURATION) {
- if (mTouchMode == SCROLL_ZOOM_ANIMATION_IN) {
- setHorizontalScrollBarEnabled(true);
- setVerticalScrollBarEnabled(true);
- rebuildWebTextView();
- scrollTo((int) (scrollFrame.centerX() * mActualScale)
- - (width >> 1), (int) (scrollFrame.centerY()
- * mActualScale) - (height >> 1));
- mTouchMode = TOUCH_DONE_MODE;
- // Show all the child views once we are done.
- mViewManager.showAll();
- } else {
- mTouchMode = SCROLL_ZOOM_OUT;
- }
- }
- float newX = scrollZoomX(scale);
- float newY = scrollZoomY(scale);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "scrollZoomDraw scale=" + scale + " + (" + newX
- + ", " + newY + ") mZoomScroll=(" + mZoomScrollX + ", "
- + mZoomScrollY + ")" + " invScale=" + invScale + " scale="
- + scale);
- }
- canvas.translate(newX, newY);
- canvas.scale(scale, scale);
- boolean animating = mTouchMode != SCROLL_ZOOM_OUT;
- if (mDrawHistory) {
- int sc = canvas.save(Canvas.CLIP_SAVE_FLAG);
- Rect clip = new Rect(0, 0, mHistoryPicture.getWidth(),
- mHistoryPicture.getHeight());
- canvas.clipRect(clip, Region.Op.DIFFERENCE);
- canvas.drawColor(mBackgroundColor);
- canvas.restoreToCount(sc);
- canvas.drawPicture(mHistoryPicture);
- } else {
- mWebViewCore.drawContentPicture(canvas, mBackgroundColor,
- animating, true);
- }
- if (mTouchMode == TOUCH_DONE_MODE) {
- return;
- }
- Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(30.0f);
- paint.setARGB(0x50, 0, 0, 0);
- int maxX = mContentWidth - width;
- int maxY = mContentHeight - height;
- if (true) { // experiment: draw hint to place finger off magnify area
- drawMagnifyFrame(canvas, scrollFrame, paint);
- } else {
- canvas.drawRect(scrollFrame, paint);
- }
- int sc = canvas.save();
- canvas.clipRect(scrollFrame);
- float halfX = (float) mZoomScrollX / maxX;
- if (mContentWidth * mZoomScrollLimit < width) {
- halfX = zoomFrameScaleX(width, 0.5f, halfX);
- }
- float halfY = (float) mZoomScrollY / maxY;
- if (mContentHeight * mZoomScrollLimit < height) {
- halfY = zoomFrameScaleY(height, 0.5f, halfY);
- }
- canvas.scale(halfScale, halfScale, mZoomScrollX + width * halfX
- , mZoomScrollY + height * halfY);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "scrollZoomDraw halfScale=" + halfScale + " w/h=("
- + width + ", " + height + ") half=(" + halfX + ", "
- + halfY + ")");
- }
- if (mDrawHistory) {
- canvas.drawPicture(mHistoryPicture);
- } else {
- mWebViewCore.drawContentPicture(canvas, mBackgroundColor,
- animating, false);
- }
- canvas.restoreToCount(sc);
- if (mTouchMode != SCROLL_ZOOM_OUT) {
- invalidate();
- }
- }
-
- private void zoomScrollTap(float x, float y) {
- float scale = scrollZoomGridScale(mZoomScrollInvLimit);
- float left = scrollZoomX(scale);
- float top = scrollZoomY(scale);
- int width = getViewWidth();
- int height = getViewHeight();
- x -= width * scale / 2;
- y -= height * scale / 2;
- mZoomScrollX = Math.min(mContentWidth - width
- , Math.max(0, (int) ((x - left) / scale)));
- mZoomScrollY = Math.min(mContentHeight - height
- , Math.max(0, (int) ((y - top) / scale)));
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "zoomScrollTap scale=" + scale + " + (" + left
- + ", " + top + ") mZoomScroll=(" + mZoomScrollX + ", "
- + mZoomScrollY + ")" + " x=" + x + " y=" + y);
- }
- }
-
- /**
- * @hide
- */
- public boolean canZoomScrollOut() {
- if (mContentWidth == 0 || mContentHeight == 0) {
- return false;
- }
- int width = getViewWidth();
- int height = getViewHeight();
- float x = (float) width / (float) mContentWidth;
- float y = (float) height / (float) mContentHeight;
- mZoomScrollLimit = Math.max(DEFAULT_MIN_ZOOM_SCALE, Math.min(x, y));
- mZoomScrollInvLimit = 1.0f / mZoomScrollLimit;
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "canZoomScrollOut"
- + " mInvActualScale=" + mInvActualScale
- + " mZoomScrollLimit=" + mZoomScrollLimit
- + " mZoomScrollInvLimit=" + mZoomScrollInvLimit
- + " mContentWidth=" + mContentWidth
- + " mContentHeight=" + mContentHeight
- );
- }
- // don't zoom out unless magnify area is at least half as wide
- // or tall as content
- float limit = mZoomScrollLimit * 2;
- return mContentWidth >= width * limit
- || mContentHeight >= height * limit;
- }
-
- private void startZoomScrollOut() {
- setHorizontalScrollBarEnabled(false);
- setVerticalScrollBarEnabled(false);
- if (getSettings().getBuiltInZoomControls()) {
- if (mZoomButtonsController.isVisible()) {
- mZoomButtonsController.setVisible(false);
- }
- } else {
- if (mZoomControlRunnable != null) {
- mPrivateHandler.removeCallbacks(mZoomControlRunnable);
- }
- if (mZoomControls != null) {
- mZoomControls.hide();
- }
- }
- int width = getViewWidth();
- int height = getViewHeight();
- int halfW = width >> 1;
- mLastTouchX = halfW;
- int halfH = height >> 1;
- mLastTouchY = halfH;
- abortAnimation();
- mZoomScrollStart = System.currentTimeMillis();
- Rect zoomFrame = scrollZoomFrame(width, height
- , scrollZoomMagScale(mZoomScrollInvLimit));
- mZoomScrollX = Math.max(0, (int) ((mScrollX + halfW) * mInvActualScale)
- - (zoomFrame.width() >> 1));
- mZoomScrollY = Math.max(0, (int) ((mScrollY + halfH) * mInvActualScale)
- - (zoomFrame.height() >> 1));
- scrollTo(0, 0); // triggers inval, starts animation
- clearTextEntry();
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "startZoomScrollOut mZoomScroll=("
- + mZoomScrollX + ", " + mZoomScrollY +")");
- }
- }
-
- /**
- * @hide
- */
- public void zoomScrollOut() {
- if (canZoomScrollOut() == false) {
- mTouchMode = TOUCH_DONE_MODE;
- return;
- }
- // Hide the child views while in this mode.
- mViewManager.hideAll();
- startZoomScrollOut();
- mTouchMode = SCROLL_ZOOM_ANIMATION_OUT;
- invalidate();
- }
-
- private void moveZoomScrollWindow(float x, float y) {
- if (Math.abs(x - mLastZoomScrollRawX) < 1.5f
- && Math.abs(y - mLastZoomScrollRawY) < 1.5f) {
- return;
- }
- mLastZoomScrollRawX = x;
- mLastZoomScrollRawY = y;
- int oldX = mZoomScrollX;
- int oldY = mZoomScrollY;
- int width = getViewWidth();
- int height = getViewHeight();
- int maxZoomX = mContentWidth - width;
- if (maxZoomX > 0) {
- int maxScreenX = width - (int) Math.ceil(width
- * mZoomScrollLimit) - SCROLL_ZOOM_FINGER_BUFFER;
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "moveZoomScrollWindow-X"
- + " maxScreenX=" + maxScreenX + " width=" + width
- + " mZoomScrollLimit=" + mZoomScrollLimit + " x=" + x);
- }
- x += maxScreenX * mLastScrollX / maxZoomX - mLastTouchX;
- x *= Math.max(maxZoomX / maxScreenX, mZoomScrollInvLimit);
- mZoomScrollX = Math.max(0, Math.min(maxZoomX, (int) x));
- }
- int maxZoomY = mContentHeight - height;
- if (maxZoomY > 0) {
- int maxScreenY = height - (int) Math.ceil(height
- * mZoomScrollLimit) - SCROLL_ZOOM_FINGER_BUFFER;
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "moveZoomScrollWindow-Y"
- + " maxScreenY=" + maxScreenY + " height=" + height
- + " mZoomScrollLimit=" + mZoomScrollLimit + " y=" + y);
- }
- y += maxScreenY * mLastScrollY / maxZoomY - mLastTouchY;
- y *= Math.max(maxZoomY / maxScreenY, mZoomScrollInvLimit);
- mZoomScrollY = Math.max(0, Math.min(maxZoomY, (int) y));
- }
- if (oldX != mZoomScrollX || oldY != mZoomScrollY) {
- invalidate();
- }
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "moveZoomScrollWindow"
- + " scrollTo=(" + mZoomScrollX + ", " + mZoomScrollY + ")"
- + " mLastTouch=(" + mLastTouchX + ", " + mLastTouchY + ")"
- + " maxZoom=(" + maxZoomX + ", " + maxZoomY + ")"
- + " last=("+mLastScrollX+", "+mLastScrollY+")"
- + " x=" + x + " y=" + y);
- }
- }
-
- private void setZoomScrollIn() {
- mZoomScrollStart = System.currentTimeMillis();
- }
-
- private float mZoomScrollLimit;
- private float mZoomScrollInvLimit;
- private int mLastScrollX;
- private int mLastScrollY;
- private long mZoomScrollStart;
- private int mZoomScrollX;
- private int mZoomScrollY;
- private float mLastZoomScrollRawX = -1000.0f;
- private float mLastZoomScrollRawY = -1000.0f;
- // The zoomed scale varies from 1.0 to DEFAULT_MIN_ZOOM_SCALE == 0.25.
- // The zoom animation duration SCROLL_ZOOM_DURATION == 0.5.
- // Two pressures compete for gridding; a high frame rate (e.g. 20 fps)
- // and minimizing font cache allocations (fewer frames is better).
- // A SCROLL_ZOOM_GRID of 6 permits about 20 zoom levels over 0.5 seconds:
- // the inverse of: 1.0, 1.16, 1.33, 1.5, 1.67, 1.84, 2.0, etc. to 4.0
- private static final int SCROLL_ZOOM_GRID = 6;
- private static final int SCROLL_ZOOM_DURATION = 500;
- // Make it easier to get to the bottom of a document by reserving a 32
- // pixel buffer, for when the starting drag is a bit below the bottom of
- // the magnify frame.
- private static final int SCROLL_ZOOM_FINGER_BUFFER = 32;
-
// draw history
private boolean mDrawHistory = false;
private Picture mHistoryPicture = null;
@@ -3312,9 +2937,7 @@ public class WebView extends AbsoluteLayout
*/
/* package */ void rebuildWebTextView() {
// If the WebView does not have focus, do nothing until it gains focus.
- if (!hasFocus() && (null == mWebTextView || !mWebTextView.hasFocus())
- || (mTouchMode >= FIRST_SCROLL_ZOOM
- && mTouchMode <= LAST_SCROLL_ZOOM)) {
+ if (!hasFocus() && (null == mWebTextView || !mWebTextView.hasFocus())) {
return;
}
boolean alreadyThere = inEditingMode();
@@ -3365,7 +2988,7 @@ public class WebView extends AbsoluteLayout
Selection.setSelection(spannable, start, end);
}
} else {
- Rect vBox = contentToView(bounds);
+ Rect vBox = contentToViewRect(bounds);
mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
vBox.height());
mWebTextView.setGravity(nativeFocusCandidateIsRtlText() ?
@@ -3479,11 +3102,9 @@ public class WebView extends AbsoluteLayout
// Bubble up the key event if
// 1. it is a system key; or
- // 2. the host application wants to handle it; or
- // 3. webview is in scroll-zoom state;
+ // 2. the host application wants to handle it;
if (event.isSystem()
- || mCallbackProxy.uiOverrideKeyEvent(event)
- || (mTouchMode >= FIRST_SCROLL_ZOOM && mTouchMode <= LAST_SCROLL_ZOOM)) {
+ || mCallbackProxy.uiOverrideKeyEvent(event)) {
return false;
}
@@ -3630,18 +3251,6 @@ public class WebView extends AbsoluteLayout
return false;
}
- // special handling in scroll_zoom state
- if (mTouchMode >= FIRST_SCROLL_ZOOM && mTouchMode <= LAST_SCROLL_ZOOM) {
- if (KeyEvent.KEYCODE_DPAD_CENTER == keyCode
- && mTouchMode != SCROLL_ZOOM_ANIMATION_IN) {
- setZoomScrollIn();
- mTouchMode = SCROLL_ZOOM_ANIMATION_IN;
- invalidate();
- return true;
- }
- return false;
- }
-
if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
|| keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT) {
if (commitCopy()) {
@@ -3962,11 +3571,8 @@ public class WebView extends AbsoluteLayout
}
// pass the touch events from UI thread to WebCore thread
- if (mForwardTouchEvents && mTouchMode != SCROLL_ZOOM_OUT
- && mTouchMode != SCROLL_ZOOM_ANIMATION_IN
- && mTouchMode != SCROLL_ZOOM_ANIMATION_OUT
- && (action != MotionEvent.ACTION_MOVE ||
- eventTime - mLastSentTouchTime > TOUCH_SENT_INTERVAL)) {
+ if (mForwardTouchEvents && (action != MotionEvent.ACTION_MOVE
+ || eventTime - mLastSentTouchTime > TOUCH_SENT_INTERVAL)) {
WebViewCore.TouchEventData ted = new WebViewCore.TouchEventData();
ted.mAction = action;
ted.mX = viewToContentX((int) x + mScrollX);
@@ -3980,15 +3586,7 @@ public class WebView extends AbsoluteLayout
switch (action) {
case MotionEvent.ACTION_DOWN: {
- if (mTouchMode == SCROLL_ZOOM_ANIMATION_IN
- || mTouchMode == SCROLL_ZOOM_ANIMATION_OUT) {
- // no interaction while animation is in progress
- break;
- } else if (mTouchMode == SCROLL_ZOOM_OUT) {
- mLastScrollX = mZoomScrollX;
- mLastScrollY = mZoomScrollY;
- // If two taps are close, ignore the first tap
- } else if (!mScroller.isFinished()) {
+ if (!mScroller.isFinished()) {
// stop the current scroll animation, but if this is
// the start of a fling, allow it to add to the current
// fling's velocity
@@ -4039,17 +3637,10 @@ public class WebView extends AbsoluteLayout
break;
}
case MotionEvent.ACTION_MOVE: {
- if (mTouchMode == TOUCH_DONE_MODE
- || mTouchMode == SCROLL_ZOOM_ANIMATION_IN
- || mTouchMode == SCROLL_ZOOM_ANIMATION_OUT) {
+ if (mTouchMode == TOUCH_DONE_MODE) {
// no dragging during scroll zoom animation
break;
}
- if (mTouchMode == SCROLL_ZOOM_OUT) {
- // while fully zoomed out, move the virtual window
- moveZoomScrollWindow(x, y);
- break;
- }
mVelocityTracker.addMovement(ev);
if (mTouchMode != TOUCH_DRAG_MODE) {
@@ -4097,8 +3688,7 @@ public class WebView extends AbsoluteLayout
if (settings.supportZoom()
&& settings.getBuiltInZoomControls()
&& !mZoomButtonsController.isVisible()
- && (canZoomScrollOut() ||
- mMinZoomScale < mMaxZoomScale)) {
+ && mMinZoomScale < mMaxZoomScale) {
mZoomButtonsController.setVisible(true);
}
}
@@ -4165,12 +3755,11 @@ public class WebView extends AbsoluteLayout
if (!getSettings().getBuiltInZoomControls()) {
boolean showPlusMinus = mMinZoomScale < mMaxZoomScale;
- boolean showMagnify = canZoomScrollOut();
- if (mZoomControls != null && (showPlusMinus || showMagnify)) {
+ if (mZoomControls != null && showPlusMinus) {
if (mZoomControls.getVisibility() == View.VISIBLE) {
mPrivateHandler.removeCallbacks(mZoomControlRunnable);
} else {
- mZoomControls.show(showPlusMinus, showMagnify);
+ mZoomControls.show(showPlusMinus, false);
}
mPrivateHandler.postDelayed(mZoomControlRunnable,
ZOOM_CONTROLS_TIMEOUT);
@@ -4193,17 +3782,14 @@ public class WebView extends AbsoluteLayout
doDoubleTap();
break;
case TOUCH_INIT_MODE: // tap
- if (ENABLE_DOUBLETAP_ZOOM) {
- mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
- if (!mPreventDrag) {
- mPrivateHandler.sendMessageDelayed(
- mPrivateHandler.obtainMessage(
- RELEASE_SINGLE_TAP),
- ViewConfiguration.getDoubleTapTimeout());
- }
- break;
+ mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
+ if (!mPreventDrag) {
+ mPrivateHandler.sendMessageDelayed(
+ mPrivateHandler.obtainMessage(
+ RELEASE_SINGLE_TAP),
+ ViewConfiguration.getDoubleTapTimeout());
}
- // fall through
+ break;
case TOUCH_SHORTPRESS_START_MODE:
case TOUCH_SHORTPRESS_MODE:
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
@@ -4215,29 +3801,9 @@ public class WebView extends AbsoluteLayout
commitCopy();
mTouchSelection = false;
break;
- case SCROLL_ZOOM_ANIMATION_IN:
- case SCROLL_ZOOM_ANIMATION_OUT:
- // no action during scroll animation
- break;
- case SCROLL_ZOOM_OUT:
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "ACTION_UP SCROLL_ZOOM_OUT"
- + " eventTime - mLastTouchTime="
- + (eventTime - mLastTouchTime));
- }
- // for now, always zoom back when the drag completes
- if (true || eventTime - mLastTouchTime < TAP_TIMEOUT) {
- // but if we tap, zoom in where we tap
- if (eventTime - mLastTouchTime < TAP_TIMEOUT) {
- zoomScrollTap(x, y);
- }
- // start zooming in back to the original view
- setZoomScrollIn();
- mTouchMode = SCROLL_ZOOM_ANIMATION_IN;
- invalidate();
- }
- break;
case TOUCH_DRAG_MODE:
+ // redraw in high-quality, as we're done dragging
+ invalidate();
// if the user waits a while w/o moving before the
// up, we don't want to do a fling
if (eventTime - mLastTouchTime <= MIN_FLING_TIME) {
@@ -4270,10 +3836,7 @@ public class WebView extends AbsoluteLayout
mVelocityTracker.recycle();
mVelocityTracker = null;
}
- if (mTouchMode == SCROLL_ZOOM_OUT ||
- mTouchMode == SCROLL_ZOOM_ANIMATION_IN) {
- scrollTo(mZoomScrollX, mZoomScrollY);
- } else if (mTouchMode == TOUCH_DRAG_MODE) {
+ if (mTouchMode == TOUCH_DRAG_MODE) {
WebViewCore.resumeUpdate(mWebViewCore);
}
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
@@ -4372,11 +3935,6 @@ public class WebView extends AbsoluteLayout
if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent gmail quit");
return false;
}
- // no move if we're still waiting on SWITCH_TO_CLICK timeout
- if (mTouchMode == TOUCH_DOUBLECLICK_MODE) {
- if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent 2 click quit");
- return true;
- }
if (mTrackballDown) {
if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent down quit");
return true; // discard move if trackball is down
@@ -4512,25 +4070,6 @@ public class WebView extends AbsoluteLayout
int height = mContentHeight - getViewHeight();
if (width < 0) width = 0;
if (height < 0) height = 0;
- if (mTouchMode == SCROLL_ZOOM_OUT) {
- int oldX = mZoomScrollX;
- int oldY = mZoomScrollY;
- int maxWH = Math.max(width, height);
- mZoomScrollX += scaleTrackballX(xRate, maxWH);
- mZoomScrollY += scaleTrackballY(yRate, maxWH);
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "doTrackball SCROLL_ZOOM_OUT"
- + " mZoomScrollX=" + mZoomScrollX
- + " mZoomScrollY=" + mZoomScrollY);
- }
- mZoomScrollX = Math.min(width, Math.max(0, mZoomScrollX));
- mZoomScrollY = Math.min(height, Math.max(0, mZoomScrollY));
- if (oldX != mZoomScrollX || oldY != mZoomScrollY) {
- invalidate();
- }
- mTrackballRemainsX = mTrackballRemainsY = 0;
- return;
- }
ax = Math.abs(mTrackballRemainsX * TRACKBALL_MULTIPLIER);
ay = Math.abs(mTrackballRemainsY * TRACKBALL_MULTIPLIER);
maxA = Math.max(ax, ay);
@@ -4750,14 +4289,6 @@ public class WebView extends AbsoluteLayout
zoomOut();
}
});
- zoomControls.setOnZoomMagnifyClickListener(new OnClickListener() {
- public void onClick(View v) {
- mPrivateHandler.removeCallbacks(mZoomControlRunnable);
- mPrivateHandler.postDelayed(mZoomControlRunnable,
- ZOOM_CONTROLS_TIMEOUT);
- zoomScrollOut();
- }
- });
return zoomControls;
}
@@ -4802,7 +4333,7 @@ public class WebView extends AbsoluteLayout
// TODO: alternatively we can disallow this during draw history mode
switchOutDrawHistory();
float scale = mActualScale * 0.8f;
- if (scale < (mMinZoomScale + 0.1f) && WebView.ENABLE_DOUBLETAP_ZOOM
+ if (scale < (mMinZoomScale + 0.1f)
&& mWebViewCore.getSettings().getUseWideViewPort()) {
// when zoom out to min scale, switch to overview mode
doDoubleTap();
@@ -4889,6 +4420,9 @@ public class WebView extends AbsoluteLayout
// In case the soft keyboard has been dismissed, bring it back up.
InputMethodManager.getInstance(getContext()).showSoftInput(mWebTextView,
0);
+ if (nativeFocusNodePointer() != nativeCursorNodePointer()) {
+ nativeMotionUp(x, y, mNavSlop);
+ }
nativeTextInputMotionUp(x, y);
}
@@ -5259,7 +4793,7 @@ public class WebView extends AbsoluteLayout
setNewZoomScale(mLastScale, false);
setContentScrollTo(restoreState.mScrollX,
restoreState.mScrollY);
- if (ENABLE_DOUBLETAP_ZOOM && useWideViewport
+ if (useWideViewport
&& settings.getLoadWithOverviewMode()) {
if (restoreState.mViewScale == 0
|| (restoreState.mMobileSite
@@ -5286,7 +4820,7 @@ public class WebView extends AbsoluteLayout
Log.v(LOGTAG, "NEW_PICTURE_MSG_ID {" +
b.left+","+b.top+","+b.right+","+b.bottom+"}");
}
- invalidate(contentToView(draw.mInvalRegion.getBounds()));
+ invalidateContentRect(draw.mInvalRegion.getBounds());
if (mPictureListener != null) {
mPictureListener.onNewPicture(WebView.this, capturePicture());
}
@@ -5745,7 +5279,7 @@ public class WebView extends AbsoluteLayout
// FIXME the divisor should be retrieved from somewhere
// the closest thing today is hard-coded into ScrollView.java
// (from ScrollView.java, line 363) int maxJump = height/2;
- return viewToContentY(height);
+ return Math.round(height * mInvActualScale);
}
/**
@@ -5785,7 +5319,7 @@ public class WebView extends AbsoluteLayout
}
Rect contentCursorRingBounds = nativeGetCursorRingBounds();
if (contentCursorRingBounds.isEmpty()) return keyHandled;
- Rect viewCursorRingBounds = contentToView(contentCursorRingBounds);
+ Rect viewCursorRingBounds = contentToViewRect(contentCursorRingBounds);
Rect visRect = new Rect();
calcOurVisibleRect(visRect);
Rect outset = new Rect(visRect);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 26d93434d431..5f2d65e5da86 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -37,7 +37,6 @@ import android.view.SurfaceView;
import java.util.ArrayList;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import junit.framework.Assert;
@@ -838,9 +837,11 @@ final class WebViewCore {
case DESTROY:
// Time to take down the world. Cancel all pending
// loads and destroy the native view and frame.
- mBrowserFrame.destroy();
- mBrowserFrame = null;
- mNativeClass = 0;
+ synchronized (WebViewCore.this) {
+ mBrowserFrame.destroy();
+ mBrowserFrame = null;
+ mNativeClass = 0;
+ }
break;
case UPDATE_FRAME_CACHE_IF_LOADING:
@@ -1528,9 +1529,6 @@ final class WebViewCore {
// Used to suspend drawing.
private boolean mDrawIsPaused;
- // Used to end scale+scroll mode, accessed by both threads
- boolean mEndScaleZoom = false;
-
// mRestoreState is set in didFirstLayout(), and reset in the next
// webkitDraw after passing it to the UI thread.
private RestoreState mRestoreState = null;
@@ -1571,7 +1569,7 @@ final class WebViewCore {
// Send the native view size that was used during the most recent
// layout.
draw.mViewPoint = new Point(mCurrentViewWidth, mCurrentViewHeight);
- if (WebView.ENABLE_DOUBLETAP_ZOOM && mSettings.getUseWideViewPort()) {
+ if (mSettings.getUseWideViewPort()) {
draw.mMinPrefWidth = Math.max(
mViewportWidth == -1 ? DEFAULT_VIEWPORT_WIDTH
: (mViewportWidth == 0 ? mCurrentViewWidth
@@ -1627,11 +1625,11 @@ final class WebViewCore {
}
}
- /* package */ boolean pictureReady() {
+ /* package */ synchronized boolean pictureReady() {
return nativePictureReady();
}
- /*package*/ Picture copyContentPicture() {
+ /*package*/ synchronized Picture copyContentPicture() {
Picture result = new Picture();
nativeCopyContentToPicture(result);
return result;
@@ -1977,7 +1975,7 @@ final class WebViewCore {
// called by JNI
private void restoreScreenWidthScale(int scale) {
- if (!WebView.ENABLE_DOUBLETAP_ZOOM || !mSettings.getUseWideViewPort()) {
+ if (!mSettings.getUseWideViewPort()) {
return;
}
diff --git a/core/java/android/widget/FasttrackBadgeWidget.java b/core/java/android/widget/FasttrackBadgeWidget.java
new file mode 100644
index 000000000000..22ca5fd7856a
--- /dev/null
+++ b/core/java/android/widget/FasttrackBadgeWidget.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.database.Cursor;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Intents;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+
+/**
+ * Widget used to show an image with the standard fasttrack badge
+ * and on-click behavior.
+ *
+ * @hide
+ */
+public class FasttrackBadgeWidget extends ImageView implements OnClickListener {
+
+ private Uri mContactUri;
+ private String mContactEmail;
+ private String mContactPhone;
+ private int mMode;
+ private QueryHandler mQueryHandler;
+
+ protected String[] mExcludeMimes = null;
+
+ static final private int TOKEN_EMAIL_LOOKUP = 0;
+ static final private int TOKEN_PHONE_LOOKUP = 1;
+ static final private int TOKEN_EMAIL_LOOKUP_AND_TRIGGER = 2;
+ static final private int TOKEN_PHONE_LOOKUP_AND_TRIGGER = 3;
+
+ static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {
+ RawContacts.CONTACT_ID,
+ Contacts.LOOKUP_KEY,
+ };
+ static int EMAIL_ID_COLUMN_INDEX = 0;
+ static int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1;
+
+ static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
+ PhoneLookup._ID,
+ PhoneLookup.LOOKUP_KEY,
+ };
+ static int PHONE_ID_COLUMN_INDEX = 0;
+ static int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1;
+
+
+
+ public FasttrackBadgeWidget(Context context) {
+ this(context, null);
+ }
+
+ public FasttrackBadgeWidget(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public FasttrackBadgeWidget(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a =
+ context.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.FasttrackBadgeWidget, defStyle, 0);
+
+ mMode = a.getInt(com.android.internal.R.styleable.FasttrackBadgeWidget_fasttrackWindowSize,
+ Intents.MODE_MEDIUM);
+
+ a.recycle();
+
+ init();
+ }
+
+ private void init() {
+ mQueryHandler = new QueryHandler(mContext.getContentResolver());
+ setOnClickListener(this);
+ }
+
+ /**
+ * Assign the contact uri that this fasttrack badge should be associated with.
+ * Note that this is only used for displaying the fasttrack window and won't
+ * bind the contact's photo for you.
+ *
+ * @param conatctUri Either a {Contacts.CONTENT_URI} or {Contacts.CONTENT_LOOKUP_URI}
+ * style URI.
+ */
+ public void assignContactUri(Uri contactUri) {
+ mContactUri = contactUri;
+ }
+
+ /**
+ * Assign a contact based on an email address. This should only be used when
+ * the contact's URI is not available, as an extra query will have to be
+ * performed to lookup the URI based on the email.
+ *
+ * @param emailAddress The email address of the contact.
+ * @param lazyLookup If this is true, the lookup query will not be performed
+ * until this view is clicked.
+ */
+ public void assignContactFromEmail(String emailAddress, boolean lazyLookup) {
+ mContactEmail = emailAddress;
+ if (!lazyLookup) {
+ mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP, null,
+ Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
+ EMAIL_LOOKUP_PROJECTION, null, null, null);
+ }
+ }
+
+ /**
+ * Assign a contact based on a phone number. This should only be used when
+ * the contact's URI is not available, as an extra query will have to be
+ * performed to lookup the URI based on the phone number.
+ *
+ * @param phoneNumber The phone number of the contact.
+ * @param lazyLookup If this is true, the lookup query will not be performed
+ * until this view is clicked.
+ */
+ public void assignContactFromPhone(String phoneNumber, boolean lazyLookup) {
+ mContactPhone = phoneNumber;
+ if (!lazyLookup) {
+ mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP, null,
+ Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
+ PHONE_LOOKUP_PROJECTION, null, null, null);
+ }
+ }
+
+ /**
+ * Set the fasttrack window mode. Options are {@link Intents.MODE_SMALL},
+ * {@link Intents.MODE_MEDIUM}, {@link Intents.MODE_LARGE}.
+ * @param size
+ */
+ public void setMode(int size) {
+ mMode = size;
+ }
+
+ public void onClick(View v) {
+ final Rect target = getTargetRect(v);
+
+ if (mContactUri != null) {
+ trigger(mContactUri, target);
+ } else if (mContactEmail != null) {
+ mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, target,
+ Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
+ EMAIL_LOOKUP_PROJECTION, null, null, null);
+ } else if (mContactPhone != null) {
+ mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP_AND_TRIGGER, target,
+ Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
+ PHONE_LOOKUP_PROJECTION, null, null, null);
+ } else {
+ // If a contact hasn't been assigned, don't react to click.
+ return;
+ }
+ }
+
+ /**
+ * Set a list of specific MIME-types to exclude and not display. For
+ * example, this can be used to hide the {@link Contacts#CONTENT_ITEM_TYPE}
+ * profile icon.
+ */
+ public void setExcludeMimes(String[] excludeMimes) {
+ mExcludeMimes = excludeMimes;
+ }
+
+ private void trigger(Uri contactUri, Rect target) {
+ Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, contactUri);
+ intent.putExtra(Intents.EXTRA_TARGET_RECT, target);
+ intent.putExtra(Intents.EXTRA_MODE, mMode);
+ mContext.startActivity(intent);
+ }
+
+ private Rect getTargetRect(View anchor) {
+ final int[] location = new int[2];
+ anchor.getLocationOnScreen(location);
+
+ final Rect rect = new Rect();
+ rect.left = location[0];
+ rect.top = location[1];
+ rect.right = rect.left + anchor.getWidth();
+ rect.bottom = rect.top + anchor.getHeight();
+ return rect;
+ }
+
+ private class QueryHandler extends AsyncQueryHandler {
+
+ public QueryHandler(ContentResolver cr) {
+ super(cr);
+ }
+
+ @Override
+ protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ Uri contactUri = null;
+ boolean trigger = false;
+
+ try{
+ switch(token) {
+ case TOKEN_PHONE_LOOKUP_AND_TRIGGER:
+ trigger = true;
+ case TOKEN_PHONE_LOOKUP: {
+ if (cursor != null && cursor.moveToFirst()) {
+ long contactId = cursor.getLong(PHONE_ID_COLUMN_INDEX);
+ String lookupKey = cursor.getString(PHONE_LOOKUP_STRING_COLUMN_INDEX);
+ contactUri = Contacts.getLookupUri(contactId, lookupKey);
+ }
+ break;
+ }
+ case TOKEN_EMAIL_LOOKUP_AND_TRIGGER:
+ trigger = true;
+ case TOKEN_EMAIL_LOOKUP: {
+ if (cursor != null && cursor.moveToFirst()) {
+ long contactId = cursor.getLong(EMAIL_ID_COLUMN_INDEX);
+ String lookupKey = cursor.getString(EMAIL_LOOKUP_STRING_COLUMN_INDEX);
+ contactUri = Contacts.getLookupUri(contactId, lookupKey);
+ }
+ }
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ if (contactUri != null) {
+ mContactUri = contactUri;
+ if (trigger && cookie != null) {
+ trigger(contactUri, (Rect) cookie);
+ }
+ }
+ }
+ }
+}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 9ec8347e4647..33e83c3eb792 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1148,9 +1148,12 @@ public class GridView extends AbsListView {
if (sel != null) {
positionSelector(sel);
mSelectedTop = sel.getTop();
+ } else if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
+ View child = getChildAt(mMotionPosition - mFirstPosition);
+ positionSelector(child);
} else {
- mSelectedTop = 0;
- mSelectorRect.setEmpty();
+ mSelectedTop = 0;
+ mSelectorRect.setEmpty();
}
mLayoutMode = LAYOUT_NORMAL;
@@ -1231,8 +1234,12 @@ public class GridView extends AbsListView {
private void setupChild(View child, int position, int y, boolean flow, int childrenLeft,
boolean selected, boolean recycled, int where) {
boolean isSelected = selected && shouldShowSelector();
-
final boolean updateChildSelected = isSelected != child.isSelected();
+ final int mode = mTouchMode;
+ final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
+ mMotionPosition == position;
+ final boolean updateChildPressed = isPressed != child.isPressed();
+
boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make
@@ -1257,6 +1264,10 @@ public class GridView extends AbsListView {
}
}
+ if (updateChildPressed) {
+ child.setPressed(isPressed);
+ }
+
if (needToMeasure) {
int childHeightSpec = ViewGroup.getChildMeasureSpec(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height);
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 6316864c24d1..41c926726bca 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1542,37 +1542,42 @@ public class ListView extends AbsListView {
recycleBin.scrapActiveViews();
if (sel != null) {
- // the current selected item should get focus if items
- // are focusable
- if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) {
- final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild &&
- focusLayoutRestoreView.requestFocus()) || sel.requestFocus();
- if (!focusWasTaken) {
- // selected item didn't take focus, fine, but still want
- // to make sure something else outside of the selected view
- // has focus
- final View focused = getFocusedChild();
- if (focused != null) {
- focused.clearFocus();
- }
- positionSelector(sel);
- } else {
- sel.setSelected(false);
- mSelectorRect.setEmpty();
- }
- } else {
- positionSelector(sel);
- }
- mSelectedTop = sel.getTop();
+ // the current selected item should get focus if items
+ // are focusable
+ if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) {
+ final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild &&
+ focusLayoutRestoreView.requestFocus()) || sel.requestFocus();
+ if (!focusWasTaken) {
+ // selected item didn't take focus, fine, but still want
+ // to make sure something else outside of the selected view
+ // has focus
+ final View focused = getFocusedChild();
+ if (focused != null) {
+ focused.clearFocus();
+ }
+ positionSelector(sel);
+ } else {
+ sel.setSelected(false);
+ mSelectorRect.setEmpty();
+ }
+ } else {
+ positionSelector(sel);
+ }
+ mSelectedTop = sel.getTop();
} else {
- mSelectedTop = 0;
- mSelectorRect.setEmpty();
+ if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
+ View child = getChildAt(mMotionPosition - mFirstPosition);
+ positionSelector(child);
+ } else {
+ mSelectedTop = 0;
+ mSelectorRect.setEmpty();
+ }
- // even if there is not selected position, we may need to restore
- // focus (i.e. something focusable in touch mode)
- if (hasFocus() && focusLayoutRestoreView != null) {
- focusLayoutRestoreView.requestFocus();
- }
+ // even if there is not selected position, we may need to restore
+ // focus (i.e. something focusable in touch mode)
+ if (hasFocus() && focusLayoutRestoreView != null) {
+ focusLayoutRestoreView.requestFocus();
+ }
}
// tell focus view we are done mucking with it, if it is still in
@@ -1686,6 +1691,10 @@ public class ListView extends AbsListView {
boolean selected, boolean recycled) {
final boolean isSelected = selected && shouldShowSelector();
final boolean updateChildSelected = isSelected != child.isSelected();
+ final int mode = mTouchMode;
+ final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL &&
+ mMotionPosition == position;
+ final boolean updateChildPressed = isPressed != child.isPressed();
final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();
// Respect layout params that are already in the view. Otherwise make some up...
@@ -1711,6 +1720,10 @@ public class ListView extends AbsListView {
child.setSelected(isSelected);
}
+ if (updateChildPressed) {
+ child.setPressed(isPressed);
+ }
+
if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
if (child instanceof Checkable) {
((Checkable) child).setChecked(mCheckStates.get(position));
diff --git a/core/res/res/drawable/fasttrack_badge_middle.xml b/core/res/res/drawable/fasttrack_badge_middle_large.xml
index 6df230aaf053..dd591bd7819b 100644
--- a/core/res/res/drawable/fasttrack_badge_middle.xml
+++ b/core/res/res/drawable/fasttrack_badge_middle_large.xml
@@ -19,10 +19,10 @@
android:state_focused="false"
android:state_selected="false"
android:state_pressed="false"
- android:drawable="@drawable/fasttrack_badge_middle_normal" />
+ android:drawable="@drawable/fasttrack_badge_middle_large_normal" />
<item
android:state_pressed="true"
- android:drawable="@drawable/fasttrack_badge_middle_pressed" />
+ android:drawable="@drawable/fasttrack_badge_middle_large_pressed" />
</selector> \ No newline at end of file
diff --git a/core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png b/core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png
new file mode 100644
index 000000000000..ca275cdd37d2
--- /dev/null
+++ b/core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.png b/core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.png
new file mode 100644
index 000000000000..b69ccbd9f0af
--- /dev/null
+++ b/core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable/fasttrack_badge_middle_normal.9.png b/core/res/res/drawable/fasttrack_badge_middle_normal.9.png
deleted file mode 100644
index 07df063d1827..000000000000
--- a/core/res/res/drawable/fasttrack_badge_middle_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/fasttrack_badge_middle_pressed.9.png b/core/res/res/drawable/fasttrack_badge_middle_pressed.9.png
deleted file mode 100644
index ded95f699167..000000000000
--- a/core/res/res/drawable/fasttrack_badge_middle_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/layout/contact_header.xml b/core/res/res/layout/contact_header.xml
index ba91e00e6c0e..8d7e470fb93d 100644
--- a/core/res/res/layout/contact_header.xml
+++ b/core/res/res/layout/contact_header.xml
@@ -24,12 +24,12 @@
android:gravity="center_vertical">
<ImageView android:id="@+id/photo"
- android:layout_width="48dip"
- android:layout_height="52dip"
+ android:layout_width="56dip"
+ android:layout_height="62dip"
android:layout_marginRight="10dip"
android:layout_marginLeft="10dip"
android:scaleType="fitCenter"
- android:background="@drawable/fasttrack_badge_middle"/>
+ android:background="@drawable/fasttrack_badge_middle_large"/>
<LinearLayout
android:layout_width="0dip"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d1cb0bd78cf3..a1a179bfd813 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -396,6 +396,14 @@
<attr name="spinnerItemStyle" format="reference" />
<!-- Default MapView style. -->
<attr name="mapViewStyle" format="reference" />
+ <!-- Dark Fasttrack badge style. -->
+ <attr name="fasttrackBadgeWidgetStyle" format="reference" />
+ <!-- Dark Fasttrack badge style with small fasttrack window. -->
+ <attr name="fasttrackBadgeWidgetStyleWindowSmall" format="reference" />
+ <!-- Dark Fasttrack badge style with medium fasttrack window. -->
+ <attr name="fasttrackBadgeWidgetStyleWindowMedium" format="reference" />
+ <!-- Dark Fasttrack badge style with large fasttrack window. -->
+ <attr name="fasttrackBadgeWidgetStyleWindowLarge" format="reference" />
<!-- =================== -->
<!-- Preference styles -->
@@ -2197,6 +2205,14 @@
<attr name="orientation" />
</declare-styleable>
+ <declare-styleable name="FasttrackBadgeWidget">
+ <attr name="fasttrackWindowSize">
+ <enum name="modeSmall" value="1" />
+ <enum name="modeMedium" value="2" />
+ <enum name="modeLarge" value="3" />
+ </attr>
+ </declare-styleable>
+
<!-- ======================================= -->
<!-- Widget package parent layout attributes -->
<!-- ======================================= -->
@@ -2843,9 +2859,7 @@
is also used as an icon to the left of the search box and you cannot modify this
behavior, so including the icon attribute is unecessary and this may be
deprecated in the future.
- <i>Optional attribute.</i>
- {@deprecated This will create a non-standard UI appearance, because the search bar UI
- now puts the activity or application icon beside the search box.} -->
+ <i>Optional attribute.</i> -->
<attr name="icon" />
<!-- This is the user-displayed name of the searchable activity. <i>Required
attribute.</i> -->
@@ -2870,10 +2884,7 @@
<flag name="showSearchLabelAsBadge" value="0x04" />
<!-- If set, this flag enables the display of the search target (icon) within the
search bar. (Note, overrides showSearchLabel) If neither bad mode is selected,
- no badge will be shown.
- {@deprecated This will create a non-standard UI appearance, because the search bar UI
- now puts the activity or application icon beside the search box.}
- -->
+ no badge will be shown.-->
<flag name="showSearchIconAsBadge" value="0x08" />
<!-- If set, this flag causes the suggestion column SUGGEST_COLUMN_INTENT_DATA to
be considered as the text for suggestion query rewriting. This should only
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0902c217a7fc..69ddd630f0e9 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -234,7 +234,7 @@
supply an auth token without prompting the user to re-enter the
password. This is the text that will scroll through the
notification bar (will be seen by the user as he uses another application). -->
- <string name="notification_title">Sign-in error</string>
+ <string name="notification_title">Sign-in error for <xliff:g id="account" example="foo@gmail.com">%1$s</xliff:g></string>
<!-- Sync notifications --> <skip />
<!-- A notification is shown when there is a sync error. This is the text that will scroll through the notification bar (will be seen by the user as he uses another application). -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index a2ceb8f38446..fae612c8bada 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -517,6 +517,26 @@
<item name="android:shadowRadius">2.75</item>
</style>
+ <style name="Widget.FasttrackBadgeWidget">
+ <item name="android:layout_width">48dip</item>
+ <item name="android:layout_height">52dip</item>
+ <item name="android:background">@android:drawable/fasttrack_badge_dark</item>
+ <item name="android:clickable">true</item>
+ <item name="android:scaleType">fitCenter</item>
+ </style>
+
+ <style name="Widget.FasttrackBadgeWidget.WindowSmall">
+ <item name="android:fasttrackWindowSize">modeSmall</item>
+ </style>
+
+ <style name="Widget.FasttrackBadgeWidget.WindowMedium">
+ <item name="android:fasttrackWindowSize">modeMedium</item>
+ </style>
+
+ <style name="Widget.FasttrackBadgeWidget.WindowLarge">
+ <item name="android:fasttrackWindowSize">modeLarge</item>
+ </style>
+
<!-- Text Appearances -->
<eat-comment />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 3b9590d24652..4f76c5605349 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -176,6 +176,9 @@
<item name="spinnerItemStyle">@android:style/Widget.TextView.SpinnerItem</item>
<item name="dropDownHintAppearance">@android:style/TextAppearance.Widget.DropDownHint</item>
<item name="keyboardViewStyle">@android:style/Widget.KeyboardView</item>
+ <item name="fasttrackBadgeWidgetStyleWindowSmall">@android:style/Widget.FasttrackBadgeWidget.WindowSmall</item>
+ <item name="fasttrackBadgeWidgetStyleWindowMedium">@android:style/Widget.FasttrackBadgeWidget.WindowMedium</item>
+ <item name="fasttrackBadgeWidgetStyleWindowLarge">@android:style/Widget.FasttrackBadgeWidget.WindowLarge</item>
<!-- Preference styles -->
<item name="preferenceScreenStyle">@android:style/Preference.PreferenceScreen</item>
diff --git a/docs/html/guide/topics/resources/available-resources.jd b/docs/html/guide/topics/resources/available-resources.jd
index 0dfc625793e4..f5f1475b79da 100644
--- a/docs/html/guide/topics/resources/available-resources.jd
+++ b/docs/html/guide/topics/resources/available-resources.jd
@@ -908,7 +908,7 @@ res/layout/<em>some_file</em>.xml.</p>
</p>
<pre>
&lt;<em>ViewGroupClass</em> xmlns:android="http://schemas.android.com/apk/res/android"
- id="@+id/<em>string_name</em>" (attributes)&gt;
+ android:id="@+id/<em>string_name</em>" (attributes)&gt;
&lt;<em>widget</em> or other nested <em>ViewGroupClass</em>&gt;+
&lt;requestFocus/&gt;(0 or 1 per layout file, assigned to any element)
&lt;/<em>ViewGroupClass</em>&gt;
@@ -919,7 +919,7 @@ res/layout/<em>some_file</em>.xml.</p>
</dt>
<dd>
<p>The file must have a single root element. This can be a ViewGroup class that contains other elements, or a widget (or custom item) if it's only one object. By default, you can use any (case-sensitive) Android {@link android.widget widget} or {@link android.view.ViewGroup ViewGroup} class name as an element. These elements support attributes that apply to the underlying class, but the naming is not as clear. How to discover what attributes are supported for what tags is discussed below. You should not assume that any nesting is valid (for example you cannot enclose <code>&lt;TextView&gt;</code> elements inside a <code>&lt;ListLayout&gt;</code>).</p>
- <p>If a class derives from another class, the XML element inherits all the attributes from the element that it "derives" from. So, for example, <code>&lt;EditText&gt;</code> is the corresponding XML element for the EditText class. It exposes its own unique attributes (<code>EditText_numeric</code>), as well as all attributes supported by <code>&lt;TextView&gt;</code> and <code>&lt;View&gt;</code>. For the <em>id</em> attribute of a tag in XML, you should use a special syntax: "@+id/<em>somestringvalue</em>". The "@+" syntax creates a resource number in the R.id class, if one doesn't exist, or uses it, if it does exist. When declaring an ID value for an XML tag, use this syntax. Example: <code>&lt;TextView id="@+id/nameTextbox"/&gt;</code>, and refer to it this way in Java: <code>findViewById(R.id.nameTextbox)</code>. All elements support the following values:</p>
+ <p>If a class derives from another class, the XML element inherits all the attributes from the element that it "derives" from. So, for example, <code>&lt;EditText&gt;</code> is the corresponding XML element for the EditText class. It exposes its own unique attributes (<code>EditText_numeric</code>), as well as all attributes supported by <code>&lt;TextView&gt;</code> and <code>&lt;View&gt;</code>. For the <em>id</em> attribute of a tag in XML, you should use a special syntax: "@+id/<em>somestringvalue</em>". The "@+" syntax creates a resource number in the R.id class, if one doesn't exist, or uses it, if it does exist. When declaring an ID value for an XML tag, use this syntax. Example: <code>&lt;TextView android:id="@+id/nameTextbox"/&gt;</code>, and refer to it this way in Java: <code>findViewById(R.id.nameTextbox)</code>. All elements support the following values:</p>
<ul>
<li>
<em>id</em> - An ID value used to access this element in Java. Typically you will use the syntax @+id/<em>string_name</em> to generate an ID for you in the id.xml file if you haven't created one yourself.
@@ -1007,7 +1007,7 @@ res/layout/<em>some_file</em>.xml.</p>
android:paddingBottom="4" // TextView.paddingBottom
android:text="@string/redirect_getter"/&gt; // TextView.text
- &lt;EditText id="@+id/text"
+ &lt;EditText android:id="@+id/text"
android:layout_width="fill_parent" // EditText.LayoutParams.width
android:layout_height="wrap_content" // EditText.LayoutParams.height
android:layout_weight="0" // EditText.LinearLayoutParams.weight
@@ -1015,7 +1015,7 @@ res/layout/<em>some_file</em>.xml.</p>
&lt;requestFocus /&gt;
&lt;/EditText&gt;
- &lt;Button id="@+id/apply"
+ &lt;Button android:id="@+id/apply"
android:layout_width="wrap_content" // Button.LayoutParams.width
android:layout_height="wrap_content" // Button.LayoutParams.height
android:text="@string/apply" /&gt; // TextView.text
@@ -1047,7 +1047,7 @@ setContentView(R.layout.main_screen);
<strong>Java implementation file</strong> - The implementation file. The class must extend {@link android.view.View View} or a subclass. See LabelView.java in ApiDemos.
</li>
<li>
- <strong>res/values/attrs.xml</strong> - Defines the XML element, and the attributes that it supports, for clients to use to instantiate your object in their layout XML file. Define your element in a <code>&lt;declare-styleable id=<em>your_java_class_name</em>&gt;</code>. See res/layout/attrs.xml in ApiDemos.
+ <strong>res/values/attrs.xml</strong> - Defines the XML element, and the attributes that it supports, for clients to use to instantiate your object in their layout XML file. Define your element in a <code>&lt;declare-styleable name=<em>your_java_class_name</em>&gt;</code>. See res/values/attrs.xml in ApiDemos.
</li>
<li>
<strong>res/layout/<em>your_class</em>.xml</strong> [<em>optional</em>] - An optional XML file to describe the layout of your object. This could also be done in Java. See custom_view_1.xml in ApiDemos.
diff --git a/docs/html/sdk/1.6_r1/index.jd b/docs/html/sdk/1.6_r1/index.jd
index 419649e9faa2..8f33949c05d1 100644
--- a/docs/html/sdk/1.6_r1/index.jd
+++ b/docs/html/sdk/1.6_r1/index.jd
@@ -5,16 +5,16 @@ sdk.version=1.6
sdk.date=September 2009
sdk.win_download=android-sdk-windows-1.6_r1.zip
-sdk.win_bytes=251325064
-sdk.win_checksum=efd6fccd5a6ff6b57585b49393d221d9
+sdk.win_bytes=260529085
+sdk.win_checksum=2bcbacbc7af0363058ca1cac6abad848
sdk.mac_download=android-sdk-mac_x86-1.6_r1.zip
-sdk.mac_bytes=238229779
-sdk.mac_checksum=2be1a1ae5d33272be841c97e8a3a3b1c
+sdk.mac_bytes=247412515
+sdk.mac_checksum=eb13cc79602d492e89103efcf48ac1f6
sdk.linux_download=android-sdk-linux_x86-1.6_r1.tgz
-sdk.linux_bytes=229032773
-sdk.linux_checksum=02ff0d0e38d4f464108a5a7f7567b207
+sdk.linux_bytes=238224860
+sdk.linux_checksum=b4bf0e610ff6db2fb6fb09c49cba1e79
adt.zip_download=ADT-0.9.3.zip
adt.zip_version=0.9.3
diff --git a/docs/html/sdk/android-1.6-highlights.jd b/docs/html/sdk/android-1.6-highlights.jd
index 74dcd9f41851..b4a97d7e13e5 100644
--- a/docs/html/sdk/android-1.6-highlights.jd
+++ b/docs/html/sdk/android-1.6-highlights.jd
@@ -113,7 +113,7 @@ adjusting settings, stopping the application, or uninstalling the application.</
<h3 id="A11y">Accessibility</h3>
<p>Users will be able to download new accessibility services built
-on the new Accessibility framework and enable them in Settings.</p>
+on the new accessibility framework and enable them in Settings.</p>
diff --git a/graphics/java/android/graphics/BlurMaskFilter.java b/graphics/java/android/graphics/BlurMaskFilter.java
index dbf57aca5754..5eafe76c357a 100644
--- a/graphics/java/android/graphics/BlurMaskFilter.java
+++ b/graphics/java/android/graphics/BlurMaskFilter.java
@@ -16,13 +16,19 @@
package android.graphics;
+/**
+ * This takes a mask, and blurs its edge by the specified radius. Whether or
+ * or not to include the original mask, and whether the blur goes outside,
+ * inside, or straddles, the original mask's border, is controlled by the
+ * Blur enum.
+ */
public class BlurMaskFilter extends MaskFilter {
public enum Blur {
- NORMAL(0), //!< fuzzy inside and outside
- SOLID(1), //!< solid inside, fuzzy outside
- OUTER(2), //!< nothing inside, fuzzy outside
- INNER(3); //!< fuzzy inside, nothing outside
+ NORMAL(0), //!< blur inside and outside of the original border
+ SOLID(1), //!< include the original mask, blur outside
+ OUTER(2), //!< just blur outside the original border
+ INNER(3); //!< just blur inside the original border
Blur(int value) {
native_int = value;
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 7749ad34998a..30c81ab4c897 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -113,6 +113,10 @@ public class Allocation extends BaseObj {
mRS.nAllocationSubDataFromObject(mID, mType, 0, o);
}
+ public void read(Object o) {
+ mRS.nAllocationSubReadFromObject(mID, mType, 0, o);
+ }
+
public void subData(int offset, Object o) {
mRS.nAllocationSubDataFromObject(mID, mType, offset, o);
}
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 6f5b67eb07d9..89db4fa6b4ec 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -106,6 +106,7 @@ public class RenderScript {
native void nAllocationRead(int id, int[] d);
native void nAllocationRead(int id, float[] d);
native void nAllocationSubDataFromObject(int id, Type t, int offset, Object o);
+ native void nAllocationSubReadFromObject(int id, Type t, int offset, Object o);
native void nTriangleMeshBegin(int vertex, int index);
native void nTriangleMeshAddVertex_XY (float x, float y);
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index a94ccb159e02..90b5958ccf77 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -253,10 +253,39 @@ static void * SF_LoadFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *bu
return ((uint8_t *)buffer) + 4;
}
+static void * SF_SaveInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
+{
+ LOGE("Save Int");
+ _env->SetIntField(_obj, _field, ((int32_t *)buffer)[0]);
+ return ((uint8_t *)buffer) + 4;
+}
+
+static void * SF_SaveShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
+{
+ LOGE("Save Short");
+ _env->SetShortField(_obj, _field, ((int16_t *)buffer)[0]);
+ return ((uint8_t *)buffer) + 2;
+}
+
+static void * SF_SaveByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
+{
+ LOGE("Save Byte");
+ _env->SetByteField(_obj, _field, ((int8_t *)buffer)[0]);
+ return ((uint8_t *)buffer) + 1;
+}
+
+static void * SF_SaveFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
+{
+ LOGE("Save Float");
+ _env->SetFloatField(_obj, _field, ((float *)buffer)[0]);
+ return ((uint8_t *)buffer) + 4;
+}
+
struct TypeFieldCache {
jfieldID field;
int bits;
void * (*ptr)(JNIEnv *, jobject, jfieldID, void *buffer);
+ void * (*readPtr)(JNIEnv *, jobject, jfieldID, void *buffer);
};
struct TypeCache {
@@ -296,13 +325,23 @@ nTypeSetupFields(JNIEnv *_env, jobject _this, jobject _type, jintArray _types, j
switch(fType[ct]) {
case RS_TYPE_FLOAT:
tfc[ct].ptr = SF_LoadFloat;
+ tfc[ct].readPtr = SF_SaveFloat;
break;
case RS_TYPE_UNSIGNED:
case RS_TYPE_SIGNED:
switch(tfc[ct].bits) {
- case 32: tfc[ct].ptr = SF_LoadInt; break;
- case 16: tfc[ct].ptr = SF_LoadShort; break;
- case 8: tfc[ct].ptr = SF_LoadByte; break;
+ case 32:
+ tfc[ct].ptr = SF_LoadInt;
+ tfc[ct].readPtr = SF_SaveInt;
+ break;
+ case 16:
+ tfc[ct].ptr = SF_LoadShort;
+ tfc[ct].readPtr = SF_SaveShort;
+ break;
+ case 8:
+ tfc[ct].ptr = SF_LoadByte;
+ tfc[ct].readPtr = SF_SaveByte;
+ break;
}
break;
}
@@ -545,7 +584,30 @@ nAllocationSubDataFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _t
buf = tfc->ptr(_env, _o, tfc->field, buf);
}
rsAllocation1DSubData(con, (RsAllocation)alloc, offset, 1, bufAlloc, tc->size);
- const uint32_t * tmp = (const uint32_t *)bufAlloc;
+ free(bufAlloc);
+}
+
+static void
+nAllocationSubReadFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _type, jint offset, jobject _o)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nAllocationReadFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc);
+
+ assert(offset == 0);
+
+ const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache);
+
+ void * bufAlloc = malloc(tc->size);
+ void * buf = bufAlloc;
+ rsAllocationRead(con, (RsAllocation)alloc, bufAlloc);
+
+ LOGE("size %i, ", tc->size);
+
+ for (int ct=0; ct < tc->fieldCount; ct++) {
+ const TypeFieldCache *tfc = &tc->fields[ct];
+ LOGE("ct=%i, buf=%p", ct, buf);
+ buf = tfc->readPtr(_env, _o, tfc->field, buf);
+ }
free(bufAlloc);
}
@@ -1270,6 +1332,7 @@ static JNINativeMethod methods[] = {
{"nAllocationRead", "(I[I)V", (void*)nAllocationRead_i },
{"nAllocationRead", "(I[F)V", (void*)nAllocationRead_f },
{"nAllocationSubDataFromObject", "(ILandroid/renderscript/Type;ILjava/lang/Object;)V", (void*)nAllocationSubDataFromObject },
+{"nAllocationSubReadFromObject", "(ILandroid/renderscript/Type;ILjava/lang/Object;)V", (void*)nAllocationSubReadFromObject },
{"nTriangleMeshBegin", "(II)V", (void*)nTriangleMeshBegin },
{"nTriangleMeshAddVertex_XY", "(FF)V", (void*)nTriangleMeshAddVertex_XY },
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 0014d5c5e3b0..10e0197b6b94 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -25,6 +25,8 @@
#include <OMX_Core.h>
#include <OMX_Video.h>
+#include "jni.h"
+
namespace android {
class IMemory;
@@ -102,15 +104,22 @@ public:
size_t encodedWidth, size_t encodedHeight,
size_t displayWidth, size_t displayHeight) = 0;
- // Note: This method is _not_ virtual, it exists as a wrapper around
+ // Note: These methods are _not_ virtual, it exists as a wrapper around
// the virtual "createRenderer" method above facilitating extraction
- // of the ISurface from a regular Surface.
+ // of the ISurface from a regular Surface or a java Surface object.
sp<IOMXRenderer> createRenderer(
const sp<Surface> &surface,
const char *componentName,
OMX_COLOR_FORMATTYPE colorFormat,
size_t encodedWidth, size_t encodedHeight,
size_t displayWidth, size_t displayHeight);
+
+ sp<IOMXRenderer> createRendererFromJavaSurface(
+ JNIEnv *env, jobject javaSurface,
+ const char *componentName,
+ OMX_COLOR_FORMATTYPE colorFormat,
+ size_t encodedWidth, size_t encodedHeight,
+ size_t displayWidth, size_t displayHeight);
};
struct omx_message {
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 9d442c3c5850..7c01687c9ddb 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -37,6 +37,7 @@ LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_C_INCLUDES := \
+ $(JNI_H_INCLUDE) \
$(call include-path-for, graphics corecg) \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 10bebd00cfcc..0cec7bbe8c10 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -45,6 +45,31 @@ sp<IOMXRenderer> IOMX::createRenderer(
displayWidth, displayHeight);
}
+sp<IOMXRenderer> IOMX::createRendererFromJavaSurface(
+ JNIEnv *env, jobject javaSurface,
+ const char *componentName,
+ OMX_COLOR_FORMATTYPE colorFormat,
+ size_t encodedWidth, size_t encodedHeight,
+ size_t displayWidth, size_t displayHeight) {
+ jclass surfaceClass = env->FindClass("android/view/Surface");
+ if (surfaceClass == NULL) {
+ LOGE("Can't find android/view/Surface");
+ return NULL;
+ }
+
+ jfieldID surfaceID = env->GetFieldID(surfaceClass, "mSurface", "I");
+ if (surfaceID == NULL) {
+ LOGE("Can't find Surface.mSurface");
+ return NULL;
+ }
+
+ sp<Surface> surface = (Surface *)env->GetIntField(javaSurface, surfaceID);
+
+ return createRenderer(
+ surface, componentName, colorFormat, encodedWidth,
+ encodedHeight, displayWidth, displayHeight);
+}
+
class BpOMX : public BpInterface<IOMX> {
public:
BpOMX(const sp<IBinder> &impl)
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 93b7a3aed896..f21eb737bea6 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -47,6 +47,7 @@ LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_C_INCLUDES := external/tremor/Tremor \
+ $(JNI_H_INCLUDE) \
$(call include-path-for, graphics corecg) \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
$(TOP)/frameworks/base/media/libstagefright/omx
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 79a32b5de595..3c343a3103a2 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -38,6 +38,7 @@ LOCAL_SRC_FILES += \
endif
LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
$(TOP)/external/opencore/android
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 77e42bebedb8..4cadccd82e87 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -7,6 +7,7 @@ LOCAL_C_INCLUDES := $(PV_INCLUDES)
LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
LOCAL_C_INCLUDES += $(TOP)/hardware/ti/omap3/liboverlay
+LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
LOCAL_SRC_FILES:= \
OMX.cpp \
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
new file mode 100644
index 000000000000..0401390df29e
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
@@ -0,0 +1,84 @@
+package com.android.mediaframeworktest;
+
+import android.media.MediaRecorder;
+import android.os.SystemProperties;
+import java.util.HashMap;
+
+public class MediaProfileReader {
+
+ public static final HashMap<String, Integer>
+ OUTPUT_FORMAT_TABLE = new HashMap<String, Integer>();
+ public static String MEDIA_ENC_VID = "ro.media.enc.vid.";
+ public static String MEDIA_AUD_VID = "ro.media.enc.aud.";
+ public static String[] VIDEO_ENCODER_PROPERTY = {".width", ".height", ".bps", ".fps",};
+ public static String[] AUDIO_ENCODER_PROPERTY = {".bps", ".hz", ".ch",};
+
+ public static String getVideoCodecProperty() {
+ String s;
+ s = SystemProperties.get("ro.media.enc.vid.codec");
+ return s;
+ }
+
+ public static String getAudioCodecProperty() {
+ String s;
+ s = SystemProperties.get("ro.media.enc.aud.codec");
+ return s;
+ }
+
+ public static String getDeviceType() {
+ // push all the property into one big table
+ String s;
+ s = SystemProperties.get("ro.product.name");
+ return s;
+ }
+
+ public static void createVideoProfileTable() {
+ // push all the property into one big table
+ String encoderType = getVideoCodecProperty();
+ String encoder[] = encoderType.split(",");
+ for (int i = 0; i < encoder.length; i++) {
+ for (int j = 0; j < VIDEO_ENCODER_PROPERTY.length; j++) {
+ String propertyName = MEDIA_ENC_VID + encoder[i] + VIDEO_ENCODER_PROPERTY[j];
+ String prop = SystemProperties.get(propertyName);
+ //push to the table
+ String propRange[] = prop.split(",");
+ OUTPUT_FORMAT_TABLE.put((encoder[i] + VIDEO_ENCODER_PROPERTY[j] + "_low"),
+ Integer.parseInt(propRange[0]));
+ OUTPUT_FORMAT_TABLE.put((encoder[i] + VIDEO_ENCODER_PROPERTY[j] + "_high"),
+ Integer.parseInt(propRange[1]));
+ }
+
+ }
+ }
+
+ public static void createAudioProfileTable() {
+ // push all the property into one big table
+ String audioType = getAudioCodecProperty();
+ String encoder[] = audioType.split(",");
+ for (int i = 0; i < encoder.length; i++) {
+ for (int j = 0; j < AUDIO_ENCODER_PROPERTY.length; j++) {
+ String propertyName = MEDIA_AUD_VID + encoder[i] + AUDIO_ENCODER_PROPERTY[j];
+ String prop = SystemProperties.get(propertyName);
+ //push to the table
+ String propRange[] = prop.split(",");
+ OUTPUT_FORMAT_TABLE.put((encoder[i] + AUDIO_ENCODER_PROPERTY[j] + "_low"),
+ Integer.parseInt(propRange[0]));
+ OUTPUT_FORMAT_TABLE.put((encoder[i] + AUDIO_ENCODER_PROPERTY[j] + "_high"),
+ Integer.parseInt(propRange[1]));
+ }
+
+ }
+ }
+
+ public static void createEncoderTable(){
+ OUTPUT_FORMAT_TABLE.put("h263", MediaRecorder.VideoEncoder.H263);
+ OUTPUT_FORMAT_TABLE.put("h264", MediaRecorder.VideoEncoder.H264);
+ OUTPUT_FORMAT_TABLE.put("m4v", MediaRecorder.VideoEncoder.MPEG_4_SP);
+ OUTPUT_FORMAT_TABLE.put("amrnb", MediaRecorder.AudioEncoder.AMR_NB);
+ OUTPUT_FORMAT_TABLE.put("amrwb", MediaRecorder.AudioEncoder.AMR_WB);
+ OUTPUT_FORMAT_TABLE.put("aac", MediaRecorder.AudioEncoder.AAC);
+ OUTPUT_FORMAT_TABLE.put("aacplus", MediaRecorder.AudioEncoder.AAC_PLUS);
+ OUTPUT_FORMAT_TABLE.put("eaacplus",
+ MediaRecorder.AudioEncoder.EAAC_PLUS);
+ }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index ef0a3b1f1fe1..39846c6eb0b9 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -29,7 +29,7 @@ import android.test.ActivityInstrumentationTestCase;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
-
+import com.android.mediaframeworktest.MediaProfileReader;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.Suppress;
@@ -46,6 +46,9 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
private SurfaceHolder mSurfaceHolder = null;
private MediaRecorder mRecorder;
+
+ private int MIN_VIDEO_FPS = 5;
+
Context mContext;
Camera mCamera;
@@ -96,7 +99,70 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
}
}
-
+ private boolean recordVideoWithPara(String encoder, String audio, String quality){
+ boolean recordSuccess = false;
+ int videoEncoder = MediaProfileReader.OUTPUT_FORMAT_TABLE.get(encoder);
+ int audioEncoder = MediaProfileReader.OUTPUT_FORMAT_TABLE.get(audio);
+ int videoWidth = MediaProfileReader.OUTPUT_FORMAT_TABLE.get(encoder + ".width_" + quality);
+ int videoHeight =
+ MediaProfileReader.OUTPUT_FORMAT_TABLE.get(encoder + ".height_" + quality);
+ int videoFps = MediaProfileReader.OUTPUT_FORMAT_TABLE.get(encoder + ".fps_" + quality);
+ int videoBitrate = MediaProfileReader.OUTPUT_FORMAT_TABLE.get(encoder + ".bps_" + quality);
+ int audioBitrate = MediaProfileReader.OUTPUT_FORMAT_TABLE.get(audio + ".bps_" + quality);
+ int audioChannels = MediaProfileReader.OUTPUT_FORMAT_TABLE.get(audio + ".ch_" + quality);
+ int audioSamplingRate =
+ MediaProfileReader.OUTPUT_FORMAT_TABLE.get(audio + ".hz_" + quality);
+
+ if (videoFps < MIN_VIDEO_FPS) {
+ videoFps = MIN_VIDEO_FPS;
+ }
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ String filename = ("/sdcard/" + encoder + "_" + audio + "_" + quality + ".3gp");
+ try {
+ Log.v(TAG, "video encoder :" + videoEncoder);
+ Log.v(TAG, "audio encoder :" + audioEncoder);
+ Log.v(TAG, "quality : " + quality);
+ Log.v(TAG, "encoder : " + encoder);
+ Log.v(TAG, "audio : " + audio);
+ Log.v(TAG, "videoWidth : " + videoWidth);
+ Log.v(TAG, "videoHeight : " + videoHeight);
+ Log.v(TAG, "videoFPS : " + videoFps);
+ Log.v(TAG, "videobitrate : " + videoBitrate);
+ Log.v(TAG, "audioBitrate : " + audioBitrate);
+ Log.v(TAG, "audioChannel : " + audioChannels);
+ Log.v(TAG, "AudioSampleRate : " + audioSamplingRate);
+
+ MediaRecorder mMediaRecorder = new MediaRecorder();
+ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mMediaRecorder.setOutputFile(filename);
+ mMediaRecorder.setVideoFrameRate(videoFps);
+ mMediaRecorder.setVideoSize(videoWidth, videoHeight);
+ mMediaRecorder.setParameters(String.format("video-param-encoding-bitrate=%d",
+ videoBitrate));
+ mMediaRecorder.setParameters(String.format("audio-param-encoding-bitrate=%d",
+ audioBitrate));
+ mMediaRecorder.setParameters(String.format("audio-param-number-of-channels=%d",
+ audioChannels));
+ mMediaRecorder.setParameters(String.format("audio-param-sampling-rate=%d",
+ audioSamplingRate));
+ mMediaRecorder.setVideoEncoder(videoEncoder);
+ mMediaRecorder.setAudioEncoder(audioEncoder);
+ mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ mMediaRecorder.prepare();
+ mMediaRecorder.start();
+ Thread.sleep(MediaNames.RECORDED_TIME);
+ mMediaRecorder.stop();
+ mMediaRecorder.release();
+ recordSuccess = validateVideo(filename, videoWidth, videoHeight);
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ return false;
+ }
+ return recordSuccess;
+ }
+
private boolean invalidRecordSetting(int frameRate, int width, int height,
int videoFormat, int outFormat, String outFile, boolean videoOnly) {
try {
@@ -356,6 +422,35 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
assertTrue("Invalid FrameRate", isTestInvalidFrameRateSuccessful);
}
-
+
+ @LargeTest
+ //est cases for the new codec
+ public void testDeviceSpecificCodec() throws Exception {
+ boolean recordSuccess = false;
+ String deviceType = MediaProfileReader.getDeviceType();
+ Log.v(TAG, "deviceType = " + deviceType);
+ if (deviceType.compareTo("voles") == 0) {
+ // Test cases are device specified
+ MediaProfileReader.createVideoProfileTable();
+ MediaProfileReader.createAudioProfileTable();
+ MediaProfileReader.createEncoderTable();
+ String encoderType = MediaProfileReader.getVideoCodecProperty();
+ String encoder[] = encoderType.split(",");
+ String audioType = MediaProfileReader.getAudioCodecProperty();
+ String audio[] = audioType.split(",");
+ for (int k = 0; k < 2; k++) {
+ for (int i = 0; i < encoder.length; i++) {
+ for (int j = 0; j < audio.length; j++) {
+ if (k == 0) {
+ recordSuccess = recordVideoWithPara(encoder[i], audio[j], "high");
+ } else {
+ recordSuccess = recordVideoWithPara(encoder[i], audio[j], "low");
+ }
+ assertTrue((encoder[i] + audio[j]), recordSuccess);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index b13883e64a4d..39084a735b3f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -27,7 +27,7 @@ import android.content.IContentService;
import android.content.res.Configuration;
import android.location.LocationManager;
import android.media.AudioManager;
-import android.os.IHardwareService;
+import android.os.IPowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
@@ -94,10 +94,10 @@ public class SettingsHelper {
private void setBrightness(int brightness) {
try {
- IHardwareService hardware = IHardwareService.Stub
- .asInterface(ServiceManager.getService("hardware"));
- if (hardware != null) {
- hardware.setBacklights(brightness);
+ IPowerManager power = IPowerManager.Stub.asInterface(
+ ServiceManager.getService("power"));
+ if (power != null) {
+ power.setBacklightBrightness(brightness);
}
} catch (RemoteException doe) {
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 738535955e6c..30c25e0ba867 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
+import android.os.SystemClock;
import android.os.UEventObserver;
import android.util.Log;
@@ -41,8 +42,11 @@ class DockObserver extends UEventObserver {
private final Context mContext;
- public DockObserver(Context context) {
+ private PowerManagerService mPowerManager;
+
+ public DockObserver(Context context, PowerManagerService pm) {
mContext = context;
+ mPowerManager = pm;
init(); // set initial status
startObserving(DOCK_UEVENT_MATCH);
}
@@ -103,6 +107,7 @@ class DockObserver extends UEventObserver {
synchronized (this) {
Log.d(TAG, "Broadcasting dock state " + mDockState);
// Pack up the values and broadcast them to everyone
+ mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
mContext.sendStickyBroadcast(intent);
diff --git a/services/java/com/android/server/HardwareService.java b/services/java/com/android/server/HardwareService.java
index 01daae344197..29c13e04f7f8 100755
--- a/services/java/com/android/server/HardwareService.java
+++ b/services/java/com/android/server/HardwareService.java
@@ -269,26 +269,6 @@ public class HardwareService extends IHardwareService.Stub {
Hardware.enableCameraFlash(milliseconds);
}
- public void setBacklights(int brightness) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires HARDWARE_TEST permission");
- }
- // Don't let applications turn the screen all the way off
- brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
- setLightBrightness_UNCHECKED(LIGHT_ID_BACKLIGHT, brightness);
- setLightBrightness_UNCHECKED(LIGHT_ID_KEYBOARD, brightness);
- setLightBrightness_UNCHECKED(LIGHT_ID_BUTTONS, brightness);
- long identity = Binder.clearCallingIdentity();
- try {
- mBatteryStats.noteScreenBrightness(brightness);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
void setLightOff_UNCHECKED(int light) {
setLight_native(mNativePointer, light, 0, LIGHT_FLASH_NONE, 0, 0);
}
@@ -307,14 +287,6 @@ public class HardwareService extends IHardwareService.Stub {
setLight_native(mNativePointer, light, color, mode, onMS, offMS);
}
- public void setAutoBrightness(boolean on) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires HARDWARE_TEST permission");
- }
- setAutoBrightness_UNCHECKED(on);
- }
-
void setAutoBrightness_UNCHECKED(boolean on) {
if (mAutoBrightnessAvailable) {
setAutoBrightness_native(mNativePointer, on);
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 29513849b1d3..35f508b8f297 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -2061,6 +2061,42 @@ class PowerManagerService extends IPowerManager.Stub
return result;
}
+ public void setBacklightBrightness(int brightness) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+ // Don't let applications turn the screen all the way off
+ brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
+ mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BACKLIGHT, brightness);
+ mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD, brightness);
+ mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, brightness);
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.noteScreenBrightness(brightness);
+ } catch (RemoteException e) {
+ Log.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+
+ // update our animation state
+ if (ANIMATE_SCREEN_LIGHTS) {
+ mScreenBrightness.curValue = brightness;
+ mScreenBrightness.animating = false;
+ }
+ if (ANIMATE_KEYBOARD_LIGHTS) {
+ mKeyboardBrightness.curValue = brightness;
+ mKeyboardBrightness.animating = false;
+ }
+ if (ANIMATE_BUTTON_LIGHTS) {
+ mButtonBrightness.curValue = brightness;
+ mButtonBrightness.animating = false;
+ }
+ }
+
+ public void setAutoBrightness(boolean on) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+ mHardware.setAutoBrightness_UNCHECKED(on);
+ }
+
private SensorManager getSensorManager() {
if (mSensorManager == null) {
mSensorManager = new SensorManager(mHandlerThread.getLooper());
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7c2a7ac86a05..b3b50e56c86e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -330,7 +330,7 @@ class ServerThread extends Thread {
try {
Log.i(TAG, "Dock Observer");
// Listen for dock station changes
- dock = new DockObserver(context);
+ dock = new DockObserver(context, power);
} catch (Throwable e) {
Log.e(TAG, "Failure starting DockObserver", e);
}
diff --git a/telephony/java/com/android/internal/telephony/SmsResponse.java b/telephony/java/com/android/internal/telephony/SmsResponse.java
index bd79e02da8f5..a7c2840effb7 100644
--- a/telephony/java/com/android/internal/telephony/SmsResponse.java
+++ b/telephony/java/com/android/internal/telephony/SmsResponse.java
@@ -37,4 +37,12 @@ public class SmsResponse {
this.ackPdu = ackPdu;
this.errorCode = errorCode;
}
+
+ public String toString() {
+ String ret = "{ messageRef = " + messageRef
+ + ", errorCode = " + errorCode
+ + ", ackPdu = " + ackPdu
+ + "}";
+ return ret;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 623d9856e245..386dc3d46899 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -299,14 +299,16 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
// Build up the data stream
ByteArrayOutputStream output = new ByteArrayOutputStream();
- for (int i = 0; i < totalSegments-1; i++) {
+ for (int i = 0; i < totalSegments; i++) {
// reassemble the (WSP-)pdu
- output.write(pdus[i], 0, pdus[i].length);
+ if (i == segment) {
+ // This one isn't in the DB, so add it
+ output.write(pdu, index, pdu.length - index);
+ } else {
+ output.write(pdus[i], 0, pdus[i].length);
+ }
}
- // This one isn't in the DB, so add it
- output.write(pdu, index, pdu.length - index);
-
byte[] datagram = output.toByteArray();
// Dispatch the PDU to applications
switch (destinationPort) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 165d58328216..266d1270cfd8 100755
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -69,7 +69,7 @@ import static android.telephony.SmsMessage.MessageClass;
*/
public class SmsMessage extends SmsMessageBase {
static final String LOG_TAG = "CDMA";
- private final static Boolean DBG_SMS = false;
+ static private final String LOGGABLE_TAG = "CDMA:SMS";
/**
* Status of a previously submitted SMS.
@@ -533,7 +533,7 @@ public class SmsMessage extends SmsMessageBase {
return;
}
mBearerData = BearerData.decode(mEnvelope.bearerData);
- if (DBG_SMS) {
+ if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
Log.d(LOG_TAG, "MT raw BearerData = '" +
HexDump.toHexString(mEnvelope.bearerData) + "'");
Log.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData);
@@ -614,7 +614,7 @@ public class SmsMessage extends SmsMessageBase {
int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1);
String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1);
SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId);
- if (DBG_SMS) {
+ if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
Log.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId);
Log.d(LOG_TAG, "readback gets " +
SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID));
@@ -655,7 +655,7 @@ public class SmsMessage extends SmsMessageBase {
bearerData.userData = userData;
byte[] encodedBearerData = BearerData.encode(bearerData);
- if (DBG_SMS) {
+ if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
Log.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData);
Log.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'");
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/os/FileObserverTest.java b/tests/AndroidTests/src/com/android/unit_tests/os/FileObserverTest.java
index a504cd3b384b..a9be5bdad15b 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/os/FileObserverTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/os/FileObserverTest.java
@@ -33,7 +33,7 @@ import java.util.Map;
public class FileObserverTest extends AndroidTestCase {
private Observer mObserver;
private File mTestFile;
-
+
private static class Observer extends FileObserver {
public List<Map> events = Lists.newArrayList();
public int totalEvents = 0;
@@ -56,10 +56,10 @@ public class FileObserverTest extends AndroidTestCase {
}
}
}
-
+
@Override
protected void setUp() throws Exception {
- mTestFile = File.createTempFile(".file_observer_test", ".txt");
+ mTestFile = File.createTempFile(".file_observer_test", ".txt");
}
@Override
@@ -68,13 +68,13 @@ public class FileObserverTest extends AndroidTestCase {
mTestFile.delete();
}
}
-
+
@LargeTest
public void testRun() throws Exception {
// make file changes and wait for them
assertTrue(mTestFile.exists());
assertNotNull(mTestFile.getParent());
-
+
mObserver = new Observer(mTestFile.getParent());
mObserver.startWatching();
@@ -85,10 +85,11 @@ public class FileObserverTest extends AndroidTestCase {
waitForEvent(); // modify
mTestFile.delete();
+ waitForEvent(); // modify
waitForEvent(); // delete
mObserver.stopWatching();
-
+
// Ensure that we have seen at least 3 events.
assertTrue(mObserver.totalEvents > 3);
} finally {
@@ -111,10 +112,41 @@ public class FileObserverTest extends AndroidTestCase {
while (it.hasNext()) {
Map map = it.next();
- Log.i("FileObserverTest", "event: " + map.get("event").toString() + " path: " + map.get("path"));
+ Log.i("FileObserverTest", "event: " + getEventString((Integer)map.get("event")) + " path: " + map.get("path"));
}
mObserver.events.clear();
}
}
+
+ private String getEventString(int event) {
+ switch (event) {
+ case FileObserver.ACCESS:
+ return "ACCESS";
+ case FileObserver.MODIFY:
+ return "MODIFY";
+ case FileObserver.ATTRIB:
+ return "ATTRIB";
+ case FileObserver.CLOSE_WRITE:
+ return "CLOSE_WRITE";
+ case FileObserver.CLOSE_NOWRITE:
+ return "CLOSE_NOWRITE";
+ case FileObserver.OPEN:
+ return "OPEN";
+ case FileObserver.MOVED_FROM:
+ return "MOVED_FROM";
+ case FileObserver.MOVED_TO:
+ return "MOVED_TO";
+ case FileObserver.CREATE:
+ return "CREATE";
+ case FileObserver.DELETE:
+ return "DELETE";
+ case FileObserver.DELETE_SELF:
+ return "DELETE_SELF";
+ case FileObserver.MOVE_SELF:
+ return "MOVE_SELF";
+ default:
+ return "UNKNOWN";
+ }
+ }
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/os/PowerManagerTest.java b/tests/AndroidTests/src/com/android/unit_tests/os/PowerManagerTest.java
index bd5c955eac16..2f1a7389e8fc 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/os/PowerManagerTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/os/PowerManagerTest.java
@@ -63,6 +63,8 @@ public class PowerManagerTest extends AndroidTestCase {
wl = mPm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PARTIAL_WAKE_LOCK");
doTestWakeLock(wl);
+ doTestSetBacklightBrightness();
+
// TODO: Some sort of functional test (maybe not in the unit test here?)
// that confirms that things are really happening e.g. screen power, keyboard power.
}
@@ -121,5 +123,20 @@ public class PowerManagerTest extends AndroidTestCase {
// TODO: Threaded test (needs handler) to make sure timed wakelocks work too
}
-
+
+ /**
+ * Test that calling {@link android.os.IHardwareService#setBacklights(int)} requires
+ * permissions.
+ * <p>Tests permission:
+ * {@link android.Manifest.permission#DEVICE_POWER}
+ */
+ private void doTestSetBacklightBrightness() {
+ try {
+ mPm.setBacklightBrightness(0);
+ fail("setBacklights did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
}
diff --git a/tests/DumpRenderTree/assets/run_page_cycler.py b/tests/DumpRenderTree/assets/run_page_cycler.py
index 4a68d7216fb3..7dd4a882fd80 100755
--- a/tests/DumpRenderTree/assets/run_page_cycler.py
+++ b/tests/DumpRenderTree/assets/run_page_cycler.py
@@ -88,8 +88,15 @@ def main(options, args):
result_file = "/sdcard/load_test_result.txt"
shell_cmd_str = adb_cmd + " pull " + result_file + " " + results_dir
- adb_output = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
- logging.info(adb_output)
+ (adb_output, err) = subprocess.Popen(
+ shell_cmd_str, shell=True,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
+ if not os.path.isfile(os.path.join(results_dir, "load_test_result.txt")):
+ logging.error("Failed to pull result file.")
+ logging.error("adb stdout:")
+ logging.error(adb_output)
+ logging.error("adb stderr:")
+ logging.error(err)
logging.info("Results are stored under: " + results_dir + "/load_test_result.txt\n")
if '__main__' == __name__:
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/settings/BrightnessLimit.java b/tests/FrameworkTest/src/com/android/frameworktest/settings/BrightnessLimit.java
index 564404460229..6d5996c85691 100644
--- a/tests/FrameworkTest/src/com/android/frameworktest/settings/BrightnessLimit.java
+++ b/tests/FrameworkTest/src/com/android/frameworktest/settings/BrightnessLimit.java
@@ -16,7 +16,7 @@
package com.android.frameworktest.settings;
-import android.os.IHardwareService;
+import android.os.IPowerManager;
import android.app.Activity;
import android.os.Bundle;
@@ -45,11 +45,11 @@ public class BrightnessLimit extends Activity implements OnClickListener {
}
public void onClick(View v) {
- IHardwareService hardware = IHardwareService.Stub.asInterface(
- ServiceManager.getService("hardware"));
- if (hardware != null) {
+ IPowerManager power = IPowerManager.Stub.asInterface(
+ ServiceManager.getService("power"));
+ if (power != null) {
try {
- hardware.setBacklights(0);
+ power.setBacklightBrightness(0);
} catch (RemoteException darn) {
}
diff --git a/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java b/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
index 1ba9d66a48b0..dc959f5e174e 100644
--- a/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
+++ b/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
@@ -188,9 +188,9 @@ public class ContentProviderOperationTest extends TestCase {
previousResults[3] = new ContentProviderResult(103);
ContentValues expectedValues = new ContentValues(values);
- expectedValues.put("a1", "103");
- expectedValues.put("a2", "101");
- expectedValues.put("a3", "102");
+ expectedValues.put("a1", (long) 103);
+ expectedValues.put("a2", (long) 101);
+ expectedValues.put("a3", (long) 102);
ContentProviderOperation op1 = ContentProviderOperation.newInsert(sTestUri1)
.withValues(values)
diff --git a/tests/permission/src/com/android/framework/permission/tests/HardwareServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/HardwareServicePermissionTest.java
index aebd68cc4db7..2290c1d16175 100644
--- a/tests/permission/src/com/android/framework/permission/tests/HardwareServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/HardwareServicePermissionTest.java
@@ -117,20 +117,4 @@ public class HardwareServicePermissionTest extends TestCase {
// expected
}
}
-
- /**
- * Test that calling {@link android.os.IHardwareService#setBacklights(int)} requires
- * permissions.
- * <p>Tests permission:
- * {@link android.Manifest.permission#HARDWARE_TEST}
- * @throws RemoteException
- */
- public void testSetBacklights() throws RemoteException {
- try {
- mHardwareService.setBacklights(0);
- fail("setBacklights did not throw SecurityException as expected");
- } catch (SecurityException e) {
- // expected
- }
- }
}